import 'dart:async';

import 'package:flutter/material.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_step_input.dart';
import '../../domain/entities/approval_step_record.dart';

/// 결재 단계 상세 다이얼로그 내 액션 구분값이다.
enum ApprovalStepDetailAction { updated, deleted, restored }

/// 결재 단계 상세 다이얼로그 종료 시 전달되는 결과 모델이다.
class ApprovalStepDetailResult {
  const ApprovalStepDetailResult({required this.action, required this.message});

  /// 수행된 액션 종류.
  final ApprovalStepDetailAction action;

  /// 사용자에게 노출할 완료 메시지.
  final String message;
}

typedef ApprovalStepUpdateCallback =
    Future<ApprovalStepRecord?> Function(int id, ApprovalStepInput input);
typedef ApprovalStepDeleteCallback = Future<bool> Function(int id);
typedef ApprovalStepRestoreCallback =
    Future<ApprovalStepRecord?> Function(int id);

/// 결재 단계 상세 다이얼로그를 노출한다.
Future<ApprovalStepDetailResult?> showApprovalStepDetailDialog({
  required BuildContext context,
  required ApprovalStepRecord record,
  required intl.DateFormat dateFormat,
  required ApprovalStepUpdateCallback onUpdate,
  required ApprovalStepDeleteCallback onDelete,
  required ApprovalStepRestoreCallback onRestore,
  bool canEdit = true,
  bool canDelete = true,
  bool canRestore = true,
}) {
  final step = record.step;
  final metadata = <SuperportDetailMetadata>[
    SuperportDetailMetadata.text(label: '결재 ID', value: '${record.approvalId}'),
    SuperportDetailMetadata.text(
      label: '트랜잭션번호',
      value: record.transactionNo ?? '-',
    ),
    SuperportDetailMetadata.text(
      label: '템플릿',
      value: record.templateName ?? '-',
    ),
    SuperportDetailMetadata.text(label: '단계 순서', value: '${step.stepOrder}'),
    SuperportDetailMetadata.text(label: '상태', value: step.status.name),
    SuperportDetailMetadata.text(label: '승인자', value: step.approver.name),
    SuperportDetailMetadata.text(
      label: '승인자 사번',
      value: step.approver.employeeNo,
    ),
    SuperportDetailMetadata.text(
      label: '배정일시',
      value: dateFormat.format(step.assignedAt.toLocal()),
    ),
    SuperportDetailMetadata.text(
      label: '결정일시',
      value: step.decidedAt == null
          ? '-'
          : dateFormat.format(step.decidedAt!.toLocal()),
    ),
    SuperportDetailMetadata.text(
      label: '비고',
      value: step.note?.isNotEmpty == true ? step.note! : '-',
    ),
  ];

  final sections = <SuperportDetailDialogSection>[
    if (canEdit)
      SuperportDetailDialogSection(
        key: const ValueKey('approval_step_section_edit'),
        id: _ApprovalStepSections.edit,
        label: '수정',
        icon: lucide.LucideIcons.pencil,
        builder: (_) => _ApprovalStepEditSection(
          record: record,
          onSubmit: (input) async {
            final stepId = step.id;
            if (stepId == null) {
              return null;
            }
            final updated = await onUpdate(stepId, input);
            if (updated == null) {
              return null;
            }
            return ApprovalStepDetailResult(
              action: ApprovalStepDetailAction.updated,
              message: '결재 단계 정보를 수정했습니다.',
            );
          },
        ),
      ),
    if (step.isDeleted ? canRestore : canDelete)
      SuperportDetailDialogSection(
        key: ValueKey(
          step.isDeleted
              ? 'approval_step_section_restore'
              : 'approval_step_section_delete',
        ),
        id: step.isDeleted
            ? _ApprovalStepSections.restore
            : _ApprovalStepSections.delete,
        label: step.isDeleted ? '복구' : '삭제',
        icon: step.isDeleted
            ? lucide.LucideIcons.history
            : lucide.LucideIcons.trash2,
        scrollable: false,
        builder: (_) => _ApprovalStepDangerSection(
          record: record,
          canDelete: canDelete,
          canRestore: canRestore,
          onDelete: () async {
            final stepId = step.id;
            if (stepId == null) {
              return null;
            }
            final success = await onDelete(stepId);
            if (!success) {
              return null;
            }
            return ApprovalStepDetailResult(
              action: ApprovalStepDetailAction.deleted,
              message: '결재 단계를 삭제했습니다.',
            );
          },
          onRestore: () async {
            final stepId = step.id;
            if (stepId == null) {
              return null;
            }
            final restored = await onRestore(stepId);
            if (restored == null) {
              return null;
            }
            return ApprovalStepDetailResult(
              action: ApprovalStepDetailAction.restored,
              message: '결재 단계를 복구했습니다.',
            );
          },
        ),
      ),
  ];

  final initialSectionId = sections.isEmpty ? null : sections.first.id;

  final badges = <Widget>[
    ShadBadge.outline(child: Text('단계 ${step.stepOrder}')),
    ShadBadge(child: Text(step.status.name)),
    if (step.isDeleted) const ShadBadge.destructive(child: Text('삭제됨')),
  ];

  return showSuperportDetailDialog<ApprovalStepDetailResult>(
    context: context,
    title: '결재 단계 상세',
    description: '결재번호 ${record.approvalNo}',
    sections: sections,
    summary: _ApprovalStepSummary(record: record),
    summaryBadges: badges,
    metadata: metadata,
    emptyPlaceholder: const Text('표시할 상세 정보가 없습니다.'),
    initialSectionId: initialSectionId,
  );
}

/// 다이얼로그 섹션 ID 상수 모음이다.
class _ApprovalStepSections {
  static const edit = 'edit';
  static const delete = 'delete';
  static const restore = 'restore';
}

/// 결재 단계 요약 정보를 구성하는 위젯이다.
class _ApprovalStepSummary extends StatelessWidget {
  const _ApprovalStepSummary({required this.record});

  final ApprovalStepRecord record;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    final step = record.step;
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text('결재 단계 ${step.stepOrder}', style: theme.textTheme.h4),
        const SizedBox(height: 4),
        Text(
          '${step.approver.name} · ${step.approver.employeeNo}',
          style: theme.textTheme.small,
        ),
        if (step.note?.isNotEmpty == true) ...[
          const SizedBox(height: 8),
          Text(step.note!, style: theme.textTheme.muted),
        ],
      ],
    );
  }
}

/// 결재 단계 수정 폼 섹션이다.
class _ApprovalStepEditSection extends StatefulWidget {
  const _ApprovalStepEditSection({
    required this.record,
    required this.onSubmit,
  });

  final ApprovalStepRecord record;
  final Future<ApprovalStepDetailResult?> Function(ApprovalStepInput input)
  onSubmit;

  @override
  State<_ApprovalStepEditSection> createState() =>
      _ApprovalStepEditSectionState();
}

class _ApprovalStepEditSectionState extends State<_ApprovalStepEditSection> {
  late final TextEditingController _stepOrderController;
  late final TextEditingController _approverIdController;
  late final TextEditingController _noteController;
  bool _isSubmitting = false;
  String? _stepOrderError;
  String? _approverIdError;
  String? _submitError;

  ApprovalStepRecord get _record => widget.record;

  @override
  void initState() {
    super.initState();
    _stepOrderController = TextEditingController(
      text: _record.step.stepOrder.toString(),
    );
    _approverIdController = TextEditingController(
      text: _record.step.approver.id.toString(),
    );
    _noteController = TextEditingController(text: _record.step.note ?? '');
  }

  @override
  void dispose() {
    _stepOrderController.dispose();
    _approverIdController.dispose();
    _noteController.dispose();
    super.dispose();
  }

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

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _ReadOnlyField(label: '결재 ID', value: '${_record.approvalId}'),
        const SizedBox(height: 12),
        _ReadOnlyField(label: '결재번호', value: _record.approvalNo),
        const SizedBox(height: 16),
        _EditableField(
          label: '단계 순서',
          controller: _stepOrderController,
          errorText: _stepOrderError,
          keyboardType: TextInputType.number,
          fieldKey: const ValueKey('approval_step_detail_step_order'),
          onChanged: (_) {
            if (_stepOrderError != null) {
              setState(() => _stepOrderError = null);
            }
          },
        ),
        const SizedBox(height: 16),
        _EditableField(
          label: '승인자 ID',
          controller: _approverIdController,
          errorText: _approverIdError,
          keyboardType: TextInputType.number,
          fieldKey: const ValueKey('approval_step_detail_approver_id'),
          onChanged: (_) {
            if (_approverIdError != null) {
              setState(() => _approverIdError = null);
            }
          },
        ),
        const SizedBox(height: 16),
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '비고',
              style: theme.textTheme.small.copyWith(
                fontWeight: FontWeight.w600,
              ),
            ),
            const SizedBox(height: 8),
            ShadTextarea(
              key: const ValueKey('approval_step_detail_note'),
              controller: _noteController,
              minHeight: 96,
              maxHeight: 200,
            ),
          ],
        ),
        if (_submitError != null) ...[
          const SizedBox(height: 12),
          Text(
            _submitError!,
            style: theme.textTheme.small.copyWith(
              color: theme.colorScheme.destructive,
            ),
          ),
        ],
        const SizedBox(height: 20),
        Align(
          alignment: Alignment.centerRight,
          child: ShadButton(
            key: const ValueKey('approval_step_detail_submit'),
            onPressed: _isSubmitting ? null : _handleSubmit,
            child: Text(_isSubmitting ? '저장 중...' : '저장'),
          ),
        ),
      ],
    );
  }

  Future<void> _handleSubmit() async {
    final stepOrder = int.tryParse(_stepOrderController.text.trim());
    final approverId = int.tryParse(_approverIdController.text.trim());

    setState(() {
      _stepOrderError = stepOrder == null || stepOrder <= 0
          ? '1 이상의 숫자를 입력하세요.'
          : null;
      _approverIdError = approverId == null || approverId <= 0
          ? '1 이상의 숫자를 입력하세요.'
          : null;
      _submitError = null;
    });

    if (_stepOrderError != null || _approverIdError != null) {
      return;
    }

    setState(() => _isSubmitting = true);

    final input = ApprovalStepInput(
      approvalId: _record.approvalId,
      stepOrder: stepOrder!,
      approverId: approverId!,
      note: _noteController.text.trim().isEmpty
          ? null
          : _noteController.text.trim(),
      statusId: _record.step.status.id,
    );

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

    try {
      result = await widget.onSubmit(input);
    } finally {
      if (mounted) {
        setState(() => _isSubmitting = false);
      }
    }

    if (!mounted) {
      return;
    }

    if (result == null) {
      setState(() {
        _submitError = '요청 처리에 실패했습니다. 다시 시도해 주세요.';
      });
      return;
    }

    if (navigator.mounted) {
      navigator.pop(result);
    }
  }
}

/// 삭제/복구 섹션을 담당하는 위젯이다.
class _ApprovalStepDangerSection extends StatelessWidget {
  const _ApprovalStepDangerSection({
    required this.record,
    required this.canDelete,
    required this.canRestore,
    required this.onDelete,
    required this.onRestore,
  });

  final ApprovalStepRecord record;
  final bool canDelete;
  final bool canRestore;
  final Future<ApprovalStepDetailResult?> Function() onDelete;
  final Future<ApprovalStepDetailResult?> Function() onRestore;

  @override
  Widget build(BuildContext context) {
    final step = record.step;
    final theme = ShadTheme.of(context);
    final navigator = Navigator.of(context, rootNavigator: true);
    final description = step.isDeleted
        ? '복구하면 결재 단계가 다시 활성화됩니다.'
        : '삭제 시 단계는 목록에서 숨겨지지만, 필요 시 복구할 수 있습니다.';

    Future<void> handleAction(
      Future<ApprovalStepDetailResult?> Function() callback,
    ) async {
      final result = await callback();
      if (result != null && navigator.mounted) {
        navigator.pop(result);
      }
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(description, style: theme.textTheme.small),
        const SizedBox(height: 16),
        if (step.isDeleted)
          ShadButton(
            key: const ValueKey('approval_step_detail_restore'),
            onPressed: canRestore ? () => handleAction(onRestore) : null,
            child: const Text('복구'),
          )
        else
          ShadButton.destructive(
            key: const ValueKey('approval_step_detail_delete'),
            onPressed: canDelete ? () => handleAction(onDelete) : null,
            child: const Text('삭제'),
          ),
      ],
    );
  }
}

/// 읽기 전용 필드 레이아웃을 제공한다.
class _ReadOnlyField extends StatelessWidget {
  const _ReadOnlyField({required this.label, required this.value});

  final String label;
  final String value;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    final background = theme.colorScheme.secondary.withValues(alpha: 0.05);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          label,
          style: theme.textTheme.small.copyWith(fontWeight: FontWeight.w600),
        ),
        const SizedBox(height: 8),
        Container(
          width: double.infinity,
          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
          decoration: BoxDecoration(
            color: background,
            borderRadius: BorderRadius.circular(8),
            border: Border.all(color: theme.colorScheme.border),
          ),
          child: Text(
            value.isEmpty ? '-' : value,
            style: theme.textTheme.small,
          ),
        ),
      ],
    );
  }
}

/// 편집 필드 공통 레이아웃 위젯이다.
class _EditableField extends StatelessWidget {
  const _EditableField({
    required this.label,
    required this.controller,
    this.errorText,
    this.keyboardType,
    this.onChanged,
    this.fieldKey,
  });

  final String label;
  final TextEditingController controller;
  final String? errorText;
  final TextInputType? keyboardType;
  final ValueChanged<String>? onChanged;
  final Key? fieldKey;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          label,
          style: theme.textTheme.small.copyWith(fontWeight: FontWeight.w600),
        ),
        const SizedBox(height: 8),
        ShadInput(
          key: fieldKey,
          controller: controller,
          keyboardType: keyboardType,
          onChanged: onChanged,
        ),
        if (errorText != null) ...[
          const SizedBox(height: 6),
          Text(
            errorText!,
            style: theme.textTheme.small.copyWith(
              color: theme.colorScheme.destructive,
            ),
          ),
        ],
      ],
    );
  }
}

/// 개요 섹션에서 사용하는 단순 레코드 모델이다.
