import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import '../../shared/widgets/nav_bar_config.dart';
import '../../core/utils/date_utils.dart' as du;
import '../../shared/widgets/action_bar.dart';
import '../../shared/widgets/form_section.dart';
import '../../shared/widgets/form_field_row.dart';
import '../../core/i18n/app_localizations.dart';
import 'overtime_create_controller.dart';
import '../../core/theme/app_colors.dart';
import '../../core/theme/app_colors_extension.dart';

class OvertimeCreatePage extends ConsumerStatefulWidget {
  final String? editId;
  const OvertimeCreatePage({super.key, this.editId});
  @override
  ConsumerState<OvertimeCreatePage> createState() => _OvertimeCreatePageState();
}

class _OvertimeCreatePageState extends ConsumerState<OvertimeCreatePage> {
  final _reasonController = TextEditingController();
  final _reasonFocus = FocusNode();
  final _scrollCtrl = ScrollController();
  static const _typeKeys = ['workday', 'weekend', 'holiday'];
  static const _compensationKeys = ['overtime_pay', 'comp_leave'];

  @override
  void initState() {
    super.initState();
    final state = ref.read(overtimeCreateProvider(widget.editId));
    _reasonController.text = state.overtime.reason;
    _reasonController.addListener(_onReasonChanged);
  }

  @override
  void dispose() {
    _reasonController.removeListener(_onReasonChanged);
    _reasonController.dispose();
    _reasonFocus.dispose();
    _scrollCtrl.dispose();
    super.dispose();
  }

  void _onReasonChanged() {
    final ctrl = ref.read(overtimeCreateProvider(widget.editId).notifier);
    ctrl.updateReason(_reasonController.text);
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final ctrl = ref.watch(overtimeCreateProvider(widget.editId).notifier);
    final state = ref.watch(overtimeCreateProvider(widget.editId));
    final l10n = AppLocalizations.of(context);

    ref
        .read(navBarConfigProvider.notifier)
        .update(
          NavBarConfig(
            title: l10n.get('overtimeApply'),
            showBack: true,
            onBack: () {
              if (_hasUnsaved()) {
                _showConfirmDialog(
                  l10n.get('confirmExit'),
                  l10n.get('unsavedContentWarning'),
                  l10n.get('continueEditing'),
                  l10n.get('discardAndExit'),
                  () => context.pop(),
                );
              } else {
                context.pop();
              }
            },
          ),
        );

    return PopScope(
      canPop: false,
      onPopInvokedWithResult: (didPop, _) {
        if (!didPop) {
          if (_hasUnsaved()) {
            _showConfirmDialog(
              l10n.get('confirmExit'),
              l10n.get('unsavedContentWarning'),
              l10n.get('continueEditing'),
              l10n.get('discardAndExit'),
              () => context.pop(),
            );
          } else {
            context.pop();
          }
        }
      },
      child: Column(
        children: [
          Expanded(
            child: GestureDetector(
              onTap: () => FocusScope.of(context).unfocus(),
              child: SingleChildScrollView(
                controller: _scrollCtrl,
                padding: const EdgeInsets.all(16),
                child: Column(
                  children: [
                    FormSection(
                      title: l10n.get('overtimeInfo'),
                      leadingIcon: Icons.more_time_outlined,
                      children: [
                        FormFieldRow(
                          label: l10n.get('overtimeType'),
                          value: _typeLabel(state.overtime.otType),
                          onTap: () => _showPicker(
                            _typeKeys,
                            _typeLabel,
                            ctrl.updateType,
                            title: l10n.get('selectOvertimeType'),
                          ),
                        ),
                        const SizedBox(height: 16),
                        FormFieldRow(
                          label: l10n.get('compensationMethod'),
                          value: _compensationLabel(
                              state.overtime.compensationType),
                          onTap: () => _showPicker(
                            _compensationKeys,
                            _compensationLabel,
                            ctrl.updateCompensation,
                            title: l10n.get('selectCompensationMethod'),
                          ),
                        ),
                        const SizedBox(height: 16),
                        FormFieldRow(
                          label: l10n.get('startTime'),
                          value:
                              du.DateUtils.formatDateTime(state.overtime.startTime),
                          onTap: () => _pickDateTime(
                            ctrl.updateStartTime,
                            state.overtime.startTime,
                          ),
                        ),
                        const SizedBox(height: 16),
                        FormFieldRow(
                          label: l10n.get('endTime'),
                          value:
                              du.DateUtils.formatDateTime(state.overtime.endTime),
                          onTap: () => _pickDateTime(
                            ctrl.updateEndTime,
                            state.overtime.endTime,
                          ),
                        ),
                        const SizedBox(height: 16),
                        FormFieldRow(
                          label: l10n.get('netOvertimeHours'),
                          value:
                              '${state.overtime.otHours.toStringAsFixed(1)} ${l10n.get('hours')}',
                          readOnly: true,
                          showArrow: false,
                        ),
                        const SizedBox(height: 16),
                        _label(l10n.get('overtimeReason')),
                        const SizedBox(height: 8),
                        TDTextarea(
                          controller: _reasonController,
                          focusNode: _reasonFocus,
                          hintText: l10n.get('enterOvertimeReason'),
                          maxLines: 4,
                          minLines: 1,
                          maxLength: 500,
                          indicator: true,
                          padding: EdgeInsets.zero,
                          bordered: true,
                          backgroundColor: colors.bgPage,
                        ),
                      ],
                    ),
                    const SizedBox(height: 80),
                  ],
                ),
              ),
            ),
          ),
          ActionBar(
            showLeft: false,
            centerLabel: l10n.get('saveDraftShort'),
            rightLabel: l10n.get('submitApproval'),
            onCenterTap: state.isSubmitting
                ? null
                : () async {
                    await ctrl.saveDraft();
                    if (context.mounted) context.pop();
                  },
            onRightTap: state.isSubmitting
                ? null
                : () async {
                    final ok = await ctrl.submit();
                    if (context.mounted && ok) context.pop();
                  },
          ),
        ],
      ),
    );
  }

  bool _hasUnsaved() => _reasonController.text.isNotEmpty;

  void _unfocus() => FocusScope.of(context).unfocus();

  void _showConfirmDialog(
    String title,
    String content,
    String leftText,
    String rightText,
    VoidCallback onConfirm,
  ) {
    _unfocus();
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    showDialog(
      context: context,
      builder: (ctx) => TDAlertDialog(
        title: title,
        content: content,
        buttonStyle: TDDialogButtonStyle.text,
        leftBtn: TDDialogButtonOptions(
          title: leftText,
          titleColor: colors.primary,
          action: () => Navigator.pop(ctx),
        ),
        rightBtn: TDDialogButtonOptions(
          title: rightText,
          titleColor: colors.danger,
          action: () {
            Navigator.pop(ctx);
            onConfirm();
          },
        ),
      ),
    );
  }

  String _typeLabel(String key) {
    final l10n = AppLocalizations.of(context);
    switch (key) {
      case 'workday':
        return l10n.get('overtimeWorkday');
      case 'weekend':
        return l10n.get('overtimeWeekend');
      case 'holiday':
        return l10n.get('overtimeHoliday');
      default:
        return key;
    }
  }

  String _compensationLabel(String key) {
    final l10n = AppLocalizations.of(context);
    switch (key) {
      case 'overtime_pay':
        return l10n.get('overtimePay');
      case 'comp_leave':
        return l10n.get('compLeave');
      default:
        return key;
    }
  }

  Widget _label(String t, {bool required = false}) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return Text.rich(
      TextSpan(
        children: [
          TextSpan(
            text: t,
            style: TextStyle(
              fontSize: AppFontSizes.subtitle,
              color: colors.textSecondary,
            ),
          ),
          if (required)
            TextSpan(
              text: ' *',
              style: TextStyle(
                fontSize: AppFontSizes.subtitle,
                color: colors.danger,
              ),
            ),
        ],
      ),
    );
  }

  void _showPicker(
    List<String> optionKeys,
    String Function(String) labelFn,
    void Function(String) onPick, {
    String title = '',
  }) {
    final l10n = AppLocalizations.of(context);
    if (title.isEmpty) title = l10n.get('pleaseSelect');
    final displayValues = optionKeys.map(labelFn).toList();
    TDPicker.showMultiPicker(
      context,
      title: title,
      data: [displayValues],
      onConfirm: (selected) {
        final idx = displayValues.indexOf(selected.first);
        if (idx >= 0) onPick(optionKeys[idx]);
      },
    );
  }

  void _pickDateTime(void Function(DateTime) onPicked, DateTime initial) {
    final l10n = AppLocalizations.of(context);
    TDPicker.showDatePicker(
      context,
      title: l10n.get('selectDateTime'),
      useYear: true,
      useMonth: true,
      useDay: true,
      useHour: true,
      useMinute: true,
      initialDate: [
        initial.year,
        initial.month,
        initial.day,
        initial.hour,
        initial.minute,
      ],
      onConfirm: (selected) {
        onPicked(
          DateTime(
            selected['year']!,
            selected['month']!,
            selected['day']!,
            selected['hour']!,
            selected['minute']!,
          ),
        );
      },
    );
  }
}
