import 'dart:async';

import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:intl/intl.dart' as intl;
import 'package:lucide_icons_flutter/lucide_icons.dart' as lucide;
import 'package:shadcn_ui/shadcn_ui.dart';

import '../../../../../widgets/components/superport_detail_dialog.dart';
import '../../../domain/entities/approval_template.dart';
import '../../../../auth/application/auth_service.dart';
import '../../../shared/widgets/approver_autocomplete_field.dart';

/// 결재 템플릿 상세 다이얼로그에서 발생 가능한 액션 종류이다.
enum ApprovalTemplateDetailAction { created, updated, deleted, restored }

/// 결재 템플릿 상세 다이얼로그 결과 모델이다.
class ApprovalTemplateDetailResult {
  const ApprovalTemplateDetailResult({
    required this.action,
    required this.message,
  });

  final ApprovalTemplateDetailAction action;
  final String message;
}

typedef ApprovalTemplateCreateCallback =
    Future<ApprovalTemplate?> Function(
      ApprovalTemplateInput input,
      List<ApprovalTemplateStepInput> steps,
    );

typedef ApprovalTemplateUpdateCallback =
    Future<ApprovalTemplate?> Function(
      int id,
      ApprovalTemplateInput input,
      List<ApprovalTemplateStepInput> steps,
    );

typedef ApprovalTemplateDeleteCallback = Future<bool> Function(int id);
typedef ApprovalTemplateRestoreCallback =
    Future<ApprovalTemplate?> Function(int id);

/// 결재 템플릿 상세 다이얼로그를 표시한다.
Future<ApprovalTemplateDetailResult?> showApprovalTemplateDetailDialog({
  required BuildContext context,
  required intl.DateFormat dateFormat,
  ApprovalTemplate? template,
  required ApprovalTemplateCreateCallback onCreate,
  required ApprovalTemplateUpdateCallback onUpdate,
  required ApprovalTemplateDeleteCallback onDelete,
  required ApprovalTemplateRestoreCallback onRestore,
}) {
  final isCreate = template == null;
  final summaryBadges = <Widget>[
    if (template?.isActive == true)
      const ShadBadge(child: Text('사용'))
    else if (template != null)
      const ShadBadge.outline(child: Text('미사용')),
  ];
  final metadata = template == null
      ? const <SuperportDetailMetadata>[]
      : [
          SuperportDetailMetadata.text(label: 'ID', value: '${template.id}'),
          SuperportDetailMetadata.text(label: '코드', value: template.code),
          SuperportDetailMetadata.text(
            label: '상태',
            value: template.isActive ? '사용' : '미사용',
          ),
          SuperportDetailMetadata.text(
            label: '생성일시',
            value: template.createdAt == null
                ? '-'
                : dateFormat.format(template.createdAt!.toLocal()),
          ),
          SuperportDetailMetadata.text(
            label: '변경일시',
            value: template.updatedAt == null
                ? '-'
                : dateFormat.format(template.updatedAt!.toLocal()),
          ),
          SuperportDetailMetadata.text(
            label: '비고',
            value: template.note?.isNotEmpty == true ? template.note! : '-',
          ),
        ];

  final sections = <SuperportDetailDialogSection>[
    if (!isCreate)
      SuperportDetailDialogSection(
        id: _TemplateSections.steps,
        label: '단계',
        icon: lucide.LucideIcons.listTree,
        builder: (_) => _TemplateStepsSection(template: template),
      ),
    SuperportDetailDialogSection(
      id: isCreate ? _TemplateSections.create : _TemplateSections.edit,
      label: isCreate ? '생성' : '수정',
      icon: lucide.LucideIcons.pencil,
      builder: (_) => _TemplateFormSection(
        template: template,
        onCreate: onCreate,
        onUpdate: onUpdate,
      ),
    ),
    if (!isCreate)
      SuperportDetailDialogSection(
        id: template.isActive
            ? _TemplateSections.delete
            : _TemplateSections.restore,
        label: template.isActive ? '삭제' : '복구',
        icon: template.isActive
            ? lucide.LucideIcons.trash2
            : lucide.LucideIcons.history,
        scrollable: false,
        builder: (_) => _TemplateDangerSection(
          template: template,
          onDelete: onDelete,
          onRestore: onRestore,
        ),
      ),
  ];

  return showSuperportDetailDialog<ApprovalTemplateDetailResult>(
    context: context,
    title: isCreate ? '결재 템플릿 생성' : '결재 템플릿 상세',
    description: isCreate
        ? '반복되는 결재 단계를 템플릿으로 등록합니다.'
        : '템플릿 정보를 확인하고 수정하거나 삭제/복구할 수 있습니다.',
    summary: template == null
        ? null
        : Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(template.name, style: ShadTheme.of(context).textTheme.h4),
              if (template.description?.isNotEmpty == true) ...[
                const SizedBox(height: 4),
                Text(
                  template.description!,
                  style: ShadTheme.of(context).textTheme.muted,
                ),
              ],
            ],
          ),
    summaryBadges: summaryBadges,
    metadata: metadata,
    sections: sections,
    initialSectionId: isCreate
        ? _TemplateSections.create
        : _TemplateSections.steps,
  );
}

/// 다이얼로그 섹션 식별자 상수 모음이다.
class _TemplateSections {
  static const steps = 'steps';
  static const edit = 'edit';
  static const create = 'create';
  static const delete = 'delete';
  static const restore = 'restore';
}

/// 템플릿 단계 목록을 표시하는 섹션이다.
class _TemplateStepsSection extends StatelessWidget {
  const _TemplateStepsSection({required this.template});

  final ApprovalTemplate template;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    if (template.steps.isEmpty) {
      return Container(
        width: double.infinity,
        padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 32),
        decoration: BoxDecoration(
          color: theme.colorScheme.secondary.withValues(alpha: 0.05),
          borderRadius: BorderRadius.circular(12),
          border: Border.all(color: theme.colorScheme.border),
        ),
        child: Center(
          child: Text('등록된 결재 단계가 없습니다.', style: theme.textTheme.muted),
        ),
      );
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        for (final step in template.steps) ...[
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                width: 36,
                height: 36,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(10),
                  color: theme.colorScheme.secondary.withValues(alpha: 0.12),
                ),
                alignment: Alignment.center,
                child: Text(
                  '${step.stepOrder}',
                  style: theme.textTheme.small.copyWith(
                    fontWeight: FontWeight.w700,
                  ),
                ),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      step.approver.name,
                      style: theme.textTheme.small.copyWith(
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                    Text(
                      '사번 ${step.approver.employeeNo}',
                      style: theme.textTheme.muted,
                    ),
                    if (step.note?.isNotEmpty ?? false)
                      Text(step.note!, style: theme.textTheme.muted),
                  ],
                ),
              ),
            ],
          ),
          const SizedBox(height: 12),
        ],
      ],
    );
  }
}

/// 템플릿 등록/수정 폼 섹션이다.
class _TemplateFormSection extends StatefulWidget {
  const _TemplateFormSection({
    required this.template,
    required this.onCreate,
    required this.onUpdate,
  });

  final ApprovalTemplate? template;
  final ApprovalTemplateCreateCallback onCreate;
  final ApprovalTemplateUpdateCallback onUpdate;

  @override
  State<_TemplateFormSection> createState() => _TemplateFormSectionState();
}

class _TemplateFormSectionState extends State<_TemplateFormSection> {
  late final TextEditingController _codeController;
  late final TextEditingController _nameController;
  late final TextEditingController _descriptionController;
  late final TextEditingController _noteController;
  late final ValueNotifier<bool> _isActiveNotifier;
  late final List<_TemplateStepField> _steps;
  bool _isSubmitting = false;
  String? _errorText;

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

  @override
  void initState() {
    super.initState();
    final template = widget.template;
    _codeController = TextEditingController(
      text: template?.code ?? _generateTemplateCode(),
    );
    _nameController = TextEditingController(text: template?.name ?? '');
    _descriptionController = TextEditingController(
      text: template?.description ?? '',
    );
    _noteController = TextEditingController(text: template?.note ?? '');
    _isActiveNotifier = ValueNotifier<bool>(template?.isActive ?? true);
    _steps = _buildInitialStepFields(template);
  }

  @override
  void dispose() {
    _codeController.dispose();
    _nameController.dispose();
    _descriptionController.dispose();
    _noteController.dispose();
    _isActiveNotifier.dispose();
    for (final step in _steps) {
      step.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        if (!_isEdit)
          _FormField(
            label: '템플릿 코드',
            child: ShadInput(
              controller: _codeController,
              readOnly: true,
              enabled: false,
            ),
          ),
        _FormField(
          label: '템플릿명',
          required: true,
          child: ShadInput(
            key: const ValueKey('template_form_name'),
            controller: _nameController,
          ),
        ),
        _FormField(
          label: '설명',
          child: ShadTextarea(
            key: const ValueKey('template_form_description'),
            controller: _descriptionController,
            minHeight: 80,
            maxHeight: 200,
          ),
        ),
        _FormField(
          label: '사용 여부',
          child: ValueListenableBuilder<bool>(
            valueListenable: _isActiveNotifier,
            builder: (_, value, __) {
              return Row(
                children: [
                  ShadSwitch(
                    value: value,
                    onChanged: _isSubmitting
                        ? null
                        : (next) => _isActiveNotifier.value = next,
                  ),
                  const SizedBox(width: 8),
                  Text(value ? '사용' : '미사용'),
                ],
              );
            },
          ),
        ),
        _FormField(
          label: '비고',
          child: ShadTextarea(
            key: const ValueKey('template_form_note'),
            controller: _noteController,
            minHeight: 80,
            maxHeight: 200,
          ),
        ),
        const SizedBox(height: 16),
        Text(
          '결재 단계',
          style: theme.textTheme.small.copyWith(fontWeight: FontWeight.w600),
        ),
        const SizedBox(height: 8),
        Column(
          children: [
            for (var index = 0; index < _steps.length; index++)
              _StepEditorRow(
                key: ValueKey('template_step_$index'),
                field: _steps[index],
                index: index,
                isEdit: _isEdit,
                isDisabled: _isSubmitting,
                onRemove: _steps.length <= 1 || _isSubmitting
                    ? null
                    : () {
                        setState(() {
                          final removed = _steps.removeAt(index);
                          removed.dispose();
                        });
                      },
              ),
            const SizedBox(height: 8),
            Align(
              alignment: Alignment.centerLeft,
              child: ShadButton.outline(
                onPressed: _isSubmitting
                    ? null
                    : () {
                        setState(() {
                          _steps.add(
                            _TemplateStepField.create(order: _steps.length + 1),
                          );
                        });
                      },
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: const [
                    Icon(lucide.LucideIcons.plus, size: 16),
                    SizedBox(width: 8),
                    Text('단계 추가'),
                  ],
                ),
              ),
            ),
          ],
        ),
        if (_errorText != null) ...[
          const SizedBox(height: 16),
          Text(
            _errorText!,
            style: theme.textTheme.small.copyWith(
              color: theme.colorScheme.destructive,
            ),
          ),
        ],
        const SizedBox(height: 20),
        Align(
          alignment: Alignment.centerRight,
          child: ShadButton(
            onPressed: _isSubmitting ? null : _handleSubmit,
            child: Text(_isSubmitting ? '저장 중...' : (_isEdit ? '저장' : '등록')),
          ),
        ),
      ],
    );
  }

  List<_TemplateStepField> _buildInitialStepFields(ApprovalTemplate? template) {
    if (template == null || template.steps.isEmpty) {
      return [_TemplateStepField.create(order: 1)];
    }
    return template.steps
        .map(
          (step) => _TemplateStepField(
            id: step.id,
            orderController: TextEditingController(
              text: step.stepOrder.toString(),
            ),
            approverController: TextEditingController(
              text: step.approver.id.toString(),
            ),
            noteController: TextEditingController(text: step.note ?? ''),
          ),
        )
        .toList();
  }

  String _generateTemplateCode() {
    final authService = GetIt.I<AuthService>();
    final session = authService.session;
    String normalizedEmployee = '';

    final candidateValues = <String?>[
      session?.user.employeeNo,
      session?.user.email,
      session?.user.name,
    ];
    for (final candidate in candidateValues) {
      if (candidate == null) {
        continue;
      }
      var source = candidate.trim();
      final atIndex = source.indexOf('@');
      if (atIndex > 0) {
        source = source.substring(0, atIndex);
      }
      final normalized = source.toUpperCase().replaceAll(
        RegExp(r'[^A-Z0-9]'),
        '',
      );
      if (normalized.isNotEmpty) {
        normalizedEmployee = normalized;
        break;
      }
    }
    final userId = session?.user.id;
    if (normalizedEmployee.isEmpty && userId != null) {
      normalizedEmployee = userId.toString();
    }

    final suffixSource = normalizedEmployee.isEmpty
        ? '0000'
        : normalizedEmployee;
    final suffix = suffixSource.length >= 4
        ? suffixSource.substring(suffixSource.length - 4)
        : suffixSource.padLeft(4, '0');
    final timestamp = intl.DateFormat(
      'yyMMddHHmmssSSS',
    ).format(DateTime.now().toUtc());
    return 'AP_TEMP_${suffix}_$timestamp';
  }

  Future<void> _handleSubmit() async {
    final isEdit = _isEdit;
    final nameValue = _nameController.text.trim();
    if (nameValue.isEmpty) {
      setState(() => _errorText = '템플릿명을 입력하세요.');
      return;
    }
    final validation = _validateSteps(_steps);
    if (validation != null) {
      setState(() => _errorText = validation);
      return;
    }
    setState(() {
      _errorText = null;
      _isSubmitting = true;
    });

    final steps = _steps
        .map(
          (field) => ApprovalTemplateStepInput(
            id: field.id,
            stepOrder: int.parse(field.orderController.text.trim()),
            approverId: int.parse(field.approverController.text.trim()),
            note: field.noteController.text.trim().isEmpty
                ? null
                : field.noteController.text.trim(),
          ),
        )
        .toList();

    final existingTemplate = widget.template;
    final input = ApprovalTemplateInput(
      code: isEdit && existingTemplate != null
          ? existingTemplate.code
          : _codeController.text.trim(),
      name: nameValue,
      description: _descriptionController.text.trim().isEmpty
          ? null
          : _descriptionController.text.trim(),
      note: _noteController.text.trim().isEmpty
          ? null
          : _noteController.text.trim(),
      isActive: _isActiveNotifier.value,
    );

    final navigator = Navigator.of(context, rootNavigator: true);
    ApprovalTemplate? result;

    try {
      if (isEdit && existingTemplate != null) {
        result = await widget.onUpdate(existingTemplate.id, input, steps);
        if (result != null && navigator.mounted) {
          navigator.pop(
            ApprovalTemplateDetailResult(
              action: ApprovalTemplateDetailAction.updated,
              message: '템플릿 "${result.name}"을(를) 수정했습니다.',
            ),
          );
          return;
        }
      } else {
        result = await widget.onCreate(input, steps);
        if (result != null && navigator.mounted) {
          navigator.pop(
            ApprovalTemplateDetailResult(
              action: ApprovalTemplateDetailAction.created,
              message: '템플릿 "${result.name}"을(를) 생성했습니다.',
            ),
          );
          return;
        }
      }
      setState(() {
        _errorText = '요청 처리에 실패했습니다. 입력값을 확인한 뒤 다시 시도하세요.';
        _isSubmitting = false;
      });
    } catch (_) {
      if (mounted) {
        setState(() {
          _errorText = '요청 처리 중 오류가 발생했습니다. 다시 시도하세요.';
          _isSubmitting = false;
        });
      }
    }
  }

  String? _validateSteps(List<_TemplateStepField> fields) {
    if (fields.isEmpty) {
      return '최소 1개 이상의 결재 단계를 입력하세요.';
    }
    final orders = <int>{};
    for (final field in fields) {
      final order = int.tryParse(field.orderController.text.trim());
      final approver = int.tryParse(field.approverController.text.trim());
      if (order == null || order <= 0) {
        return '모든 단계의 순서를 1 이상의 숫자로 입력하세요.';
      }
      if (approver == null || approver <= 0) {
        return '모든 단계의 승인자 ID를 1 이상의 숫자로 입력하세요.';
      }
      if (!orders.add(order)) {
        return '단계 순서는 중복될 수 없습니다.';
      }
    }
    return null;
  }
}

/// 템플릿 삭제/복구 섹션이다.
class _TemplateDangerSection extends StatelessWidget {
  const _TemplateDangerSection({
    required this.template,
    required this.onDelete,
    required this.onRestore,
  });

  final ApprovalTemplate template;
  final ApprovalTemplateDeleteCallback onDelete;
  final ApprovalTemplateRestoreCallback onRestore;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    final navigator = Navigator.of(context, rootNavigator: true);
    final isActive = template.isActive;

    Future<void> handleAction(
      Future<ApprovalTemplate?> Function() callback,
      ApprovalTemplateDetailAction action,
      String message,
    ) async {
      final result = await callback();
      if (result != null && navigator.mounted) {
        navigator.pop(
          ApprovalTemplateDetailResult(action: action, message: message),
        );
      }
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          isActive
              ? '삭제하면 템플릿은 미사용 상태로 전환됩니다. 필요 시 복구할 수 있습니다.'
              : '복구하면 템플릿이 다시 사용 상태로 전환됩니다.',
          style: theme.textTheme.small,
        ),
        const SizedBox(height: 16),
        if (isActive)
          ShadButton.destructive(
            onPressed: () => handleAction(
              () async {
                final success = await onDelete(template.id);
                return success ? template.copyWith(isActive: false) : null;
              },
              ApprovalTemplateDetailAction.deleted,
              '템플릿 "${template.name}"을(를) 삭제했습니다.',
            ),
            child: const Text('삭제'),
          )
        else
          ShadButton(
            onPressed: () => handleAction(
              () async => onRestore(template.id),
              ApprovalTemplateDetailAction.restored,
              '템플릿 "${template.name}"을(를) 복구했습니다.',
            ),
            child: const Text('복구'),
          ),
      ],
    );
  }
}

/// 폼 필드 레이아웃 위젯이다.
class _FormField extends StatelessWidget {
  const _FormField({
    required this.label,
    required this.child,
    this.required = false,
  });

  final String label;
  final Widget child;
  final bool required;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return Padding(
      padding: const EdgeInsets.only(bottom: 16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Text(
                label,
                style: theme.textTheme.small.copyWith(
                  fontWeight: FontWeight.w600,
                ),
              ),
              if (required) ...[
                const SizedBox(width: 4),
                Text('*', style: theme.textTheme.small),
              ],
            ],
          ),
          const SizedBox(height: 8),
          child,
        ],
      ),
    );
  }
}

/// 템플릿 단계 편집 행을 렌더링한다.
class _StepEditorRow extends StatelessWidget {
  const _StepEditorRow({
    super.key,
    required this.field,
    required this.index,
    required this.isEdit,
    required this.isDisabled,
    this.onRemove,
  });

  final _TemplateStepField field;
  final int index;
  final bool isEdit;
  final bool isDisabled;
  final VoidCallback? onRemove;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return Container(
      margin: const EdgeInsets.symmetric(vertical: 6),
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(12),
        border: Border.all(
          color: theme.colorScheme.border.withValues(alpha: 0.6),
        ),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Expanded(
                child: ShadInput(
                  key: ValueKey('template_step_${index}_order'),
                  controller: field.orderController,
                  keyboardType: TextInputType.number,
                  placeholder: const Text('단계 순서'),
                  enabled: !isDisabled,
                ),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: IgnorePointer(
                  ignoring: isDisabled,
                  child: ApprovalApproverAutocompleteField(
                    key: ValueKey('template_step_${index}_approver'),
                    idController: field.approverController,
                    hintText: '승인자 검색',
                    onSelected: (_) {},
                  ),
                ),
              ),
              const SizedBox(width: 12),
              if (onRemove != null)
                ShadButton.ghost(
                  size: ShadButtonSize.sm,
                  onPressed: onRemove,
                  child: const Icon(lucide.LucideIcons.trash2, size: 16),
                ),
            ],
          ),
          const SizedBox(height: 8),
          IgnorePointer(
            ignoring: isDisabled,
            child: ShadTextarea(
              controller: field.noteController,
              minHeight: 60,
              maxHeight: 160,
              placeholder: const Text('비고 (선택)'),
            ),
          ),
          if (isEdit && field.id != null)
            Padding(
              padding: const EdgeInsets.only(top: 4),
              child: Text('단계 ID: ${field.id}', style: theme.textTheme.small),
            ),
        ],
      ),
    );
  }
}

/// 템플릿 단계 필드 상태를 보관한다.
class _TemplateStepField {
  _TemplateStepField({
    this.id,
    required this.orderController,
    required this.approverController,
    required this.noteController,
  });

  final int? id;
  final TextEditingController orderController;
  final TextEditingController approverController;
  final TextEditingController noteController;

  factory _TemplateStepField.create({required int order}) {
    return _TemplateStepField(
      orderController: TextEditingController(text: '$order'),
      approverController: TextEditingController(),
      noteController: TextEditingController(),
    );
  }

  void dispose() {
    orderController.dispose();
    approverController.dispose();
    noteController.dispose();
  }
}

/// 단순 레이블/값 모델이다.
