// ignore_for_file: use_build_context_synchronously

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';

import '../../../core/i18n/app_localizations.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/theme/app_colors_extension.dart';

/// 加班明细输入数据。
class OvertimeDetailData {
  final String empCode;
  final String shiftType;
  final String startDate;
  final String endDate;
  final double approvedHours;
  final String isApproved;
  final String directOt;
  final double otQuantity;
  final String reason;
  final String handleMethod;
  final String chargeMethod;
  final String remark;
  final String isClosed;
  final String outBillNo;

  const OvertimeDetailData({
    required this.empCode,
    required this.shiftType,
    required this.startDate,
    required this.endDate,
    required this.approvedHours,
    required this.isApproved,
    required this.directOt,
    required this.otQuantity,
    required this.reason,
    required this.handleMethod,
    required this.chargeMethod,
    required this.remark,
    required this.isClosed,
    required this.outBillNo,
  });
}

/// 加班明细录入弹窗。
class OvertimeDetailDialog extends StatefulWidget {
  final AppLocalizations l10n;
  final OvertimeDetailData? initialData;

  const OvertimeDetailDialog({super.key, required this.l10n, this.initialData});

  /// 显示弹窗，返回 [OvertimeDetailData] 或 `null`（取消时）。
  static Future<OvertimeDetailData?> show(
    BuildContext context, {
    required AppLocalizations l10n,
    OvertimeDetailData? initialData,
  }) {
    FocusScope.of(context).unfocus();
    return Navigator.push<OvertimeDetailData>(
      context,
      TDSlidePopupRoute<OvertimeDetailData>(
        slideTransitionFrom: SlideTransitionFrom.bottom,
        isDismissible: true,
        builder: (_) =>
            OvertimeDetailDialog(l10n: l10n, initialData: initialData),
      ),
    );
  }

  @override
  State<OvertimeDetailDialog> createState() => _OvertimeDetailDialogState();
}

class _OvertimeDetailDialogState extends State<OvertimeDetailDialog> {
  final _empCodeCtrl = TextEditingController();
  final _shiftTypeCtrl = TextEditingController();
  String _startDate = '';
  String _endDate = '';
  final _approvedHoursCtrl = TextEditingController();
  String _isApproved = 'N';
  String _directOt = 'N';
  final _reasonCtrl = TextEditingController();
  final _handleMethodCtrl = TextEditingController();
  final _chargeMethodCtrl = TextEditingController();
  final _remarkCtrl = TextEditingController();
  String _isClosed = 'N';
  final _outBillNoCtrl = TextEditingController();

  final _scrollCtrl = ScrollController();

  AppLocalizations get _l10n => widget.l10n;

  bool get _isEdit => widget.initialData != null;

  @override
  void initState() {
    super.initState();
    final d = widget.initialData;
    if (d != null) {
      _empCodeCtrl.text = d.empCode;
      _shiftTypeCtrl.text = d.shiftType;
      _startDate = d.startDate;
      _endDate = d.endDate;
      _approvedHoursCtrl.text = d.approvedHours > 0
          ? d.approvedHours.toString()
          : '';
      _isApproved = d.isApproved;
      _directOt = d.directOt;
      _reasonCtrl.text = d.reason;
      _handleMethodCtrl.text = d.handleMethod;
      _chargeMethodCtrl.text = d.chargeMethod;
      _remarkCtrl.text = d.remark;
      _isClosed = d.isClosed;
      _outBillNoCtrl.text = d.outBillNo;
    }
  }

  @override
  void dispose() {
    _empCodeCtrl.dispose();
    _shiftTypeCtrl.dispose();
    _approvedHoursCtrl.dispose();
    _reasonCtrl.dispose();
    _handleMethodCtrl.dispose();
    _chargeMethodCtrl.dispose();
    _remarkCtrl.dispose();
    _outBillNoCtrl.dispose();
    _scrollCtrl.dispose();
    super.dispose();
  }

  void _confirm() {
    if (_empCodeCtrl.text.trim().isEmpty) {
      TDToast.showText('请输入员工代号', context: context);
      return;
    }
    final otQuantity = double.tryParse(_approvedHoursCtrl.text) ?? 0;
    Navigator.pop(
      context,
      OvertimeDetailData(
        empCode: _empCodeCtrl.text.trim(),
        shiftType: _shiftTypeCtrl.text,
        startDate: _startDate,
        endDate: _endDate,
        approvedHours: otQuantity,
        isApproved: _isApproved,
        directOt: _directOt,
        otQuantity: otQuantity,
        reason: _reasonCtrl.text,
        handleMethod: _handleMethodCtrl.text,
        chargeMethod: _chargeMethodCtrl.text,
        remark: _remarkCtrl.text,
        isClosed: _isClosed,
        outBillNo: _outBillNoCtrl.text,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;

    return AnimatedPadding(
      padding: EdgeInsets.only(
        bottom: MediaQuery.of(context).viewInsets.bottom,
      ),
      duration: const Duration(milliseconds: 200),
      child: SafeArea(
        child: ConstrainedBox(
          constraints: BoxConstraints(
            maxHeight: MediaQuery.of(context).size.height * 0.85,
          ),
          child: Container(
            decoration: BoxDecoration(
              color: colors.bgPage,
              borderRadius: const BorderRadius.vertical(
                top: Radius.circular(16),
              ),
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                _buildHeader(colors),
                Flexible(
                  child: GestureDetector(
                    onTap: () => FocusScope.of(context).unfocus(),
                    behavior: HitTestBehavior.translucent,
                    child: SingleChildScrollView(
                      controller: _scrollCtrl,
                      keyboardDismissBehavior:
                          ScrollViewKeyboardDismissBehavior.manual,
                      padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: [
                          _inputCard(
                            label: '员工代号',
                            required: true,
                            controller: _empCodeCtrl,
                            hintText: '请输入',
                          ),
                          const SizedBox(height: 12),
                          _inputCard(
                            label: '班别',
                            required: false,
                            controller: _shiftTypeCtrl,
                            hintText: '请输入',
                          ),
                          const SizedBox(height: 12),
                          _datePickerCard(
                            label: '开始日期',
                            value: _startDate,
                            hint: '请选择',
                            colors: colors,
                            onPick: (d) => setState(() => _startDate = d),
                            onClear: _startDate.isNotEmpty
                                ? () => setState(() => _startDate = '')
                                : null,
                          ),
                          const SizedBox(height: 12),
                          _datePickerCard(
                            label: '结束日期',
                            value: _endDate,
                            hint: '请选择',
                            colors: colors,
                            onPick: (d) => setState(() => _endDate = d),
                            onClear: _endDate.isNotEmpty
                                ? () => setState(() => _endDate = '')
                                : null,
                          ),
                          const SizedBox(height: 12),
                          _inputCard(
                            label: '加班核准量',
                            required: false,
                            controller: _approvedHoursCtrl,
                            hintText: '0',
                            keyboardType: const TextInputType.numberWithOptions(
                              decimal: true,
                            ),
                            inputFormatters: [
                              FilteringTextInputFormatter.allow(
                                RegExp(r'^\d*\.?\d{0,2}$'),
                              ),
                            ],
                            onChanged: () => setState(() {}),
                          ),
                          const SizedBox(height: 12),
                          _toggleCard(
                            label: '核准',
                            value: _isApproved,
                            options: const ['Y', 'N'],
                            onChanged: (v) => setState(() => _isApproved = v),
                          ),
                          const SizedBox(height: 12),
                          _toggleCard(
                            label: '直接转加班',
                            value: _directOt,
                            options: const ['Y', 'N'],
                            onChanged: (v) => setState(() => _directOt = v),
                          ),
                          const SizedBox(height: 12),
                          // 加班数量（只读，=核准量）
                          _readOnlyCard(
                            label: '加班数量',
                            value: _approvedHoursCtrl.text.isNotEmpty
                                ? _approvedHoursCtrl.text
                                : '0',
                          ),
                          const SizedBox(height: 12),
                          _inputCard(
                            label: '原因说明',
                            required: false,
                            controller: _reasonCtrl,
                            hintText: '请输入',
                          ),
                          const SizedBox(height: 12),
                          _inputCard(
                            label: '处理方式',
                            required: false,
                            controller: _handleMethodCtrl,
                            hintText: '请输入',
                          ),
                          const SizedBox(height: 12),
                          _inputCard(
                            label: '收费方式',
                            required: false,
                            controller: _chargeMethodCtrl,
                            hintText: '请输入',
                          ),
                          const SizedBox(height: 12),
                          _inputCard(
                            label: '备注',
                            required: false,
                            controller: _remarkCtrl,
                            hintText: '请输入',
                          ),
                          const SizedBox(height: 12),
                          _toggleCard(
                            label: '结案',
                            value: _isClosed,
                            options: const ['Y', 'N'],
                            onChanged: (v) => setState(() => _isClosed = v),
                          ),
                          const SizedBox(height: 12),
                          _inputCard(
                            label: '转出单号',
                            required: false,
                            controller: _outBillNoCtrl,
                            hintText: '请输入',
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
                Container(
                  padding: const EdgeInsets.fromLTRB(16, 12, 16, 16),
                  decoration: BoxDecoration(
                    color: colors.bgCard,
                    border: Border(
                      top: BorderSide(color: colors.border, width: 0.5),
                    ),
                  ),
                  child: Row(
                    children: [
                      Expanded(
                        child: TDButton(
                          text: _l10n.get('cancel'),
                          size: TDButtonSize.large,
                          type: TDButtonType.outline,
                          shape: TDButtonShape.rectangle,
                          theme: TDButtonTheme.defaultTheme,
                          onTap: () => Navigator.pop(context),
                        ),
                      ),
                      const SizedBox(width: 12),
                      Expanded(
                        child: TDButton(
                          text: _isEdit ? '确认修改' : '添加',
                          size: TDButtonSize.large,
                          type: TDButtonType.fill,
                          shape: TDButtonShape.rectangle,
                          theme: TDButtonTheme.primary,
                          onTap: _confirm,
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  // ── 标题栏 ──
  Widget _buildHeader(AppColorsExtension colors) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Center(
          child: Container(
            margin: const EdgeInsets.only(top: 8, bottom: 4),
            width: 36,
            height: 4,
            decoration: BoxDecoration(
              color: colors.border,
              borderRadius: BorderRadius.circular(2),
            ),
          ),
        ),
        Padding(
          padding: const EdgeInsets.fromLTRB(20, 8, 12, 16),
          child: Row(
            children: [
              const SizedBox(width: 24),
              Expanded(
                child: Center(
                  child: Text(
                    '加班明细',
                    style: TextStyle(
                      fontSize: AppFontSizes.title,
                      fontWeight: FontWeight.w600,
                      color: colors.textPrimary,
                    ),
                  ),
                ),
              ),
              GestureDetector(
                onTap: () => Navigator.pop(context),
                child: Padding(
                  padding: const EdgeInsets.all(4),
                  child: Icon(
                    Icons.close,
                    size: 20,
                    color: colors.textSecondary,
                  ),
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  // ── 通用输入卡片 ──
  Widget _inputCard({
    required String label,
    required bool required,
    required TextEditingController controller,
    required String hintText,
    TextInputType? keyboardType,
    List<TextInputFormatter>? inputFormatters,
    VoidCallback? onChanged,
  }) {
    final tdTheme = TDTheme.of(context);
    final hasValue = controller.text.isNotEmpty;
    return Container(
      padding: const EdgeInsets.only(left: 16, right: 10, top: 12, bottom: 12),
      decoration: BoxDecoration(
        color: tdTheme.bgColorContainer,
        borderRadius: BorderRadius.circular(tdTheme.radiusDefault),
        border: Border.all(color: tdTheme.componentStrokeColor),
      ),
      child: Row(
        children: [
          TDText(
            label,
            maxLines: 1,
            overflow: TextOverflow.visible,
            font: tdTheme.fontBodyLarge,
            fontWeight: FontWeight.w400,
            style: const TextStyle(letterSpacing: 0),
          ),
          if (required)
            Padding(
              padding: const EdgeInsets.only(left: 4),
              child: TDText(
                '*',
                font: tdTheme.fontBodyLarge,
                fontWeight: FontWeight.w400,
                style: TextStyle(color: tdTheme.errorColor6),
              ),
            ),
          const SizedBox(width: 12),
          Expanded(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              mainAxisSize: MainAxisSize.max,
              children: [
                Flexible(
                  child: TextField(
                    controller: controller,
                    textAlign: TextAlign.end,
                    keyboardType: keyboardType,
                    inputFormatters: inputFormatters,
                    style: TextStyle(
                      fontSize: 16,
                      color: tdTheme.textColorPrimary,
                    ),
                    decoration: InputDecoration(
                      hintText: hintText,
                      hintStyle: TextStyle(
                        fontSize: 16,
                        color: tdTheme.textColorPlaceholder,
                      ),
                      border: InputBorder.none,
                      isDense: true,
                      contentPadding: EdgeInsets.zero,
                    ),
                    onChanged: (_) => setState(() {}),
                  ),
                ),
                const SizedBox(width: 4),
                SizedBox(
                  width: 18,
                  height: 18,
                  child: hasValue
                      ? GestureDetector(
                          onTap: () {
                            controller.clear();
                            onChanged?.call();
                            setState(() {});
                          },
                          child: Icon(
                            Icons.close,
                            size: 18,
                            color: tdTheme.textColorPlaceholder,
                          ),
                        )
                      : null,
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  // ── 日期 Picker 卡片 ──
  Widget _datePickerCard({
    required String label,
    required String value,
    required String hint,
    required AppColorsExtension colors,
    required ValueChanged<String> onPick,
    VoidCallback? onClear,
  }) {
    final tdTheme = TDTheme.of(context);
    final hasValue = value.isNotEmpty;
    return GestureDetector(
      onTap: () => _pickDate(onPick),
      child: Container(
        padding: const EdgeInsets.only(
          left: 16,
          right: 10,
          top: 12,
          bottom: 12,
        ),
        decoration: BoxDecoration(
          color: tdTheme.bgColorContainer,
          borderRadius: BorderRadius.circular(tdTheme.radiusDefault),
          border: Border.all(color: tdTheme.componentStrokeColor),
        ),
        child: Row(
          children: [
            TDText(
              label,
              maxLines: 1,
              overflow: TextOverflow.visible,
              font: tdTheme.fontBodyLarge,
              fontWeight: FontWeight.w400,
              style: const TextStyle(letterSpacing: 0),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                mainAxisSize: MainAxisSize.max,
                children: [
                  Flexible(
                    child: TDText(
                      value.isEmpty ? hint : value,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      font: tdTheme.fontBodyLarge,
                      fontWeight: FontWeight.w400,
                      textColor: value.isEmpty
                          ? tdTheme.textColorPlaceholder
                          : tdTheme.textColorPrimary,
                      textAlign: TextAlign.end,
                    ),
                  ),
                  const SizedBox(width: 4),
                  SizedBox(
                    width: 18,
                    height: 18,
                    child: hasValue
                        ? GestureDetector(
                            onTap: onClear,
                            child: Icon(
                              Icons.close,
                              size: 18,
                              color: tdTheme.textColorPlaceholder,
                            ),
                          )
                        : Icon(
                            Icons.chevron_right,
                            size: 18,
                            color: tdTheme.textColorPlaceholder,
                          ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  // ── 切换卡片（Y/N） ──
  Widget _toggleCard({
    required String label,
    required String value,
    required List<String> options,
    required ValueChanged<String> onChanged,
  }) {
    final tdTheme = TDTheme.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return Container(
      padding: const EdgeInsets.only(left: 16, right: 10, top: 10, bottom: 10),
      decoration: BoxDecoration(
        color: tdTheme.bgColorContainer,
        borderRadius: BorderRadius.circular(tdTheme.radiusDefault),
        border: Border.all(color: tdTheme.componentStrokeColor),
      ),
      child: Row(
        children: [
          TDText(
            label,
            maxLines: 1,
            overflow: TextOverflow.visible,
            font: tdTheme.fontBodyLarge,
            fontWeight: FontWeight.w400,
            style: const TextStyle(letterSpacing: 0),
          ),
          const Spacer(),
          ...options.map((opt) {
            final sel = value == opt;
            return Padding(
              padding: const EdgeInsets.only(left: 8),
              child: GestureDetector(
                onTap: () => onChanged(opt),
                child: Container(
                  padding: const EdgeInsets.symmetric(
                    horizontal: 12,
                    vertical: 6,
                  ),
                  decoration: BoxDecoration(
                    color: sel
                        ? colors.primary.withValues(alpha: 0.1)
                        : tdTheme.bgColorContainer,
                    borderRadius: BorderRadius.circular(tdTheme.radiusDefault),
                    border: Border.all(
                      color: sel
                          ? colors.primary
                          : tdTheme.componentStrokeColor,
                    ),
                  ),
                  child: Text(
                    opt == 'Y' ? '是' : '否',
                    style: TextStyle(
                      fontSize: 14,
                      color: sel ? colors.primary : tdTheme.textColorPrimary,
                    ),
                  ),
                ),
              ),
            );
          }),
        ],
      ),
    );
  }

  // ── 只读卡片 ──
  Widget _readOnlyCard({required String label, required String value}) {
    final tdTheme = TDTheme.of(context);
    return Container(
      padding: const EdgeInsets.only(left: 16, right: 10, top: 12, bottom: 12),
      decoration: BoxDecoration(
        color: tdTheme.bgColorContainer,
        borderRadius: BorderRadius.circular(tdTheme.radiusDefault),
        border: Border.all(color: tdTheme.componentStrokeColor),
      ),
      child: Row(
        children: [
          TDText(
            label,
            maxLines: 1,
            overflow: TextOverflow.visible,
            font: tdTheme.fontBodyLarge,
            fontWeight: FontWeight.w400,
            style: const TextStyle(letterSpacing: 0),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              mainAxisSize: MainAxisSize.max,
              children: [
                Flexible(
                  child: TDText(
                    value,
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    font: tdTheme.fontBodyLarge,
                    fontWeight: FontWeight.w400,
                    textColor: tdTheme.textColorPrimary,
                    textAlign: TextAlign.end,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  void _pickDate(ValueChanged<String> onPick) {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final now = DateTime.now();
    FocusManager.instance.primaryFocus?.unfocus();
    TDPicker.showDatePicker(
      context,
      title: l10n.get('selectDate'),
      backgroundColor: colors.bgCard,
      useYear: true,
      useMonth: true,
      useDay: true,
      useHour: false,
      useMinute: false,
      useSecond: false,
      useWeekDay: false,
      dateStart: const [2020, 1, 1],
      dateEnd: [now.year + 1, 12, 31],
      initialDate: [now.year, now.month, now.day],
      onConfirm: (selected) {
        onPick(
          '${selected['year']}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}',
        );
        Navigator.of(context).pop();
      },
    );
  }
}
