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

import '../../../../../widgets/components/feedback.dart';
import '../../../../../widgets/components/superport_dialog.dart';
import '../../../shared/domain/entities/approval_approver_candidate.dart';
import '../../../shared/widgets/approver_autocomplete_field.dart';
import '../controllers/approval_request_controller.dart';
import 'approval_step_row.dart';
import 'approval_template_picker.dart';

/// 결재 단계 구성을 요약하고 모달을 통해 편집할 수 있는 UI 섹션.
class ApprovalStepConfigurator extends StatefulWidget {
  const ApprovalStepConfigurator({
    super.key,
    required this.controller,
    this.readOnly = false,
  });

  /// 결재 단계 상태를 제어하는 컨트롤러.
  final ApprovalRequestController controller;

  /// 읽기 전용 모드 여부.
  final bool readOnly;

  @override
  State<ApprovalStepConfigurator> createState() =>
      _ApprovalStepConfiguratorState();
}

class _ApprovalStepConfiguratorState extends State<ApprovalStepConfigurator> {
  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: widget.controller,
      builder: (context, _) {
        final theme = ShadTheme.of(context);
        final steps = widget.controller.steps;
        final requester = widget.controller.requester;
        final finalApprover = widget.controller.finalApprover;
        final templateSnapshot = widget.controller.templateSnapshot;

        return ShadCard(
          padding: const EdgeInsets.all(20),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          '결재 단계 구성',
                          style: theme.textTheme.h4.copyWith(
                            fontWeight: FontWeight.w700,
                          ),
                        ),
                        const SizedBox(height: 4),
                        Text(
                          '상신자, 중간 승인자, 최종 승인자를 정의하고 템플릿으로 저장할 수 있습니다.',
                          style: theme.textTheme.muted,
                        ),
                      ],
                    ),
                  ),
                  ShadButton(
                    onPressed: widget.readOnly
                        ? null
                        : () => _openConfiguratorDialog(context),
                    leading: const Icon(lucide.LucideIcons.settings2, size: 16),
                    child: const Text('단계 구성 편집'),
                  ),
                ],
              ),
              const SizedBox(height: 20),
              Wrap(
                spacing: 8,
                runSpacing: 8,
                children: [
                  _InfoBadge(
                    icon: lucide.LucideIcons.user,
                    label: '상신자',
                    value: requester?.name ?? '미지정',
                  ),
                  _InfoBadge(
                    icon: lucide.LucideIcons.badgeCheck,
                    label: '최종 승인자',
                    value: finalApprover?.name ?? '미지정',
                  ),
                  _InfoBadge(
                    icon: lucide.LucideIcons.listOrdered,
                    label: '총 단계',
                    value: '${steps.length}개',
                  ),
                  if (templateSnapshot != null)
                    _InfoBadge(
                      icon: lucide.LucideIcons.bookmarkCheck,
                      label: '적용 템플릿',
                      value: '#${templateSnapshot.templateId}',
                    ),
                ],
              ),
              const SizedBox(height: 16),
              if (steps.isEmpty)
                Container(
                  width: double.infinity,
                  padding: const EdgeInsets.symmetric(
                    horizontal: 16,
                    vertical: 20,
                  ),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(color: theme.colorScheme.border),
                  ),
                  child: Text(
                    '등록된 결재 단계가 없습니다. 단계 구성 편집을 눌러 승인자를 추가하세요.',
                    style: theme.textTheme.muted,
                  ),
                )
              else
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    ..._buildStepSummary(theme, steps),
                    if (steps.length > 4)
                      Padding(
                        padding: const EdgeInsets.only(top: 8),
                        child: Text(
                          '+ ${steps.length - 4}개 단계 더 있음',
                          style: theme.textTheme.muted,
                        ),
                      ),
                  ],
                ),
              if (widget.controller.errorMessage != null) ...[
                const SizedBox(height: 16),
                Text(
                  widget.controller.errorMessage!,
                  style: theme.textTheme.small.copyWith(
                    color: theme.colorScheme.destructive,
                  ),
                ),
              ],
            ],
          ),
        );
      },
    );
  }

  List<Widget> _buildStepSummary(
    ShadThemeData theme,
    List<ApprovalRequestStep> steps,
  ) {
    final limit = steps.length > 4 ? 4 : steps.length;
    return [
      for (var index = 0; index < limit; index++)
        Padding(
          padding: EdgeInsets.only(top: index == 0 ? 0 : 8),
          child: Row(
            children: [
              Container(
                width: 32,
                height: 32,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(10),
                  color: theme.colorScheme.secondary.withValues(alpha: 0.12),
                ),
                alignment: Alignment.center,
                child: Text(
                  '${steps[index].stepOrder}',
                  style: theme.textTheme.small.copyWith(
                    fontWeight: FontWeight.w700,
                  ),
                ),
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Text(
                  '${steps[index].approver.name} · ${steps[index].approver.employeeNo}',
                  style: theme.textTheme.small,
                ),
              ),
            ],
          ),
        ),
    ];
  }

  Future<void> _openConfiguratorDialog(BuildContext context) {
    return SuperportDialog.show<void>(
      context: context,
      barrierDismissible: true,
      dialog: SuperportDialog(
        title: '결재 단계 구성',
        description: '승인자 목록을 편집하고 템플릿을 적용하거나 저장합니다.',
        child: _ConfiguratorDialogBody(
          controller: widget.controller,
          readOnly: widget.readOnly,
        ),
      ),
    );
  }
}

class _ConfiguratorDialogBody extends StatefulWidget {
  const _ConfiguratorDialogBody({
    required this.controller,
    required this.readOnly,
  });

  final ApprovalRequestController controller;
  final bool readOnly;

  @override
  State<_ConfiguratorDialogBody> createState() =>
      _ConfiguratorDialogBodyState();
}

class _ConfiguratorDialogBodyState extends State<_ConfiguratorDialogBody> {
  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);

    return AnimatedBuilder(
      animation: widget.controller,
      builder: (context, _) {
        final steps = widget.controller.steps;
        final duplicates = _collectDuplicateApproverIds(steps);
        final isApplyingTemplate = widget.controller.isApplyingTemplate;
        final hasReachedLimit = widget.controller.hasReachedStepLimit;
        final requester = widget.controller.requester;
        final hasRequesterConflict = widget.controller.hasRequesterConflict;

        return ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 720),
          child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '상신자',
                  style: theme.textTheme.small.copyWith(
                    fontWeight: FontWeight.w600,
                  ),
                ),
                const SizedBox(height: 6),
                Container(
                  width: double.infinity,
                  padding: const EdgeInsets.symmetric(
                    horizontal: 12,
                    vertical: 14,
                  ),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(12),
                    border: Border.all(color: theme.colorScheme.border),
                  ),
                  child: Text(
                    requester == null
                        ? '상신자가 아직 지정되지 않았습니다.'
                        : '${requester.name} · ${requester.employeeNo}',
                    style: theme.textTheme.small,
                  ),
                ),
                const SizedBox(height: 20),
                IgnorePointer(
                  ignoring: widget.readOnly,
                  child: Opacity(
                    opacity: widget.readOnly ? 0.6 : 1,
                    child: ApprovalTemplatePicker(
                      controller: widget.controller,
                    ),
                  ),
                ),
                const SizedBox(height: 24),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text(
                      '결재 단계 목록',
                      style: theme.textTheme.small.copyWith(
                        fontWeight: FontWeight.w700,
                      ),
                    ),
                    Row(
                      children: [
                        if (isApplyingTemplate) ...[
                          SizedBox(
                            width: 16,
                            height: 16,
                            child: const CircularProgressIndicator(
                              strokeWidth: 2,
                            ),
                          ),
                          const SizedBox(width: 8),
                          Text(
                            '템플릿을 적용하는 중입니다...',
                            style: theme.textTheme.muted,
                          ),
                          const SizedBox(width: 16),
                        ],
                        ShadButton.outline(
                          onPressed: widget.readOnly || hasReachedLimit
                              ? null
                              : _openAddStepDialog,
                          child: Row(
                            mainAxisSize: MainAxisSize.min,
                            children: const [
                              Icon(lucide.LucideIcons.plus, size: 16),
                              SizedBox(width: 8),
                              Text('단계 추가'),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
                const SizedBox(height: 12),
                if (steps.isEmpty)
                  Container(
                    width: double.infinity,
                    padding: const EdgeInsets.symmetric(
                      horizontal: 16,
                      vertical: 24,
                    ),
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(12),
                      border: Border.all(color: theme.colorScheme.border),
                    ),
                    child: Text(
                      '결재 단계를 추가해 주세요. 마지막 단계가 자동으로 최종 승인자로 사용됩니다.',
                      style: theme.textTheme.muted,
                    ),
                  )
                else
                  ConstrainedBox(
                    constraints: const BoxConstraints(maxHeight: 420),
                    child: ListView.separated(
                      shrinkWrap: true,
                      itemCount: steps.length,
                      physics: const BouncingScrollPhysics(),
                      separatorBuilder: (_, __) => const SizedBox(height: 12),
                      itemBuilder: (context, index) {
                        final step = steps[index];
                        final isFinal = index == steps.length - 1;
                        return ApprovalStepRow(
                          key: ValueKey('approval_step_row_$index'),
                          controller: widget.controller,
                          step: step,
                          index: index,
                          isFinal: isFinal,
                          readOnly: widget.readOnly,
                          hasDuplicateApprover: duplicates.contains(
                            step.approverId,
                          ),
                          isRequesterConflict: requester?.id == step.approverId,
                          onRemove: widget.readOnly
                              ? null
                              : () => widget.controller.removeStepAt(index),
                        );
                      },
                    ),
                  ),
                if (steps.isNotEmpty)
                  Padding(
                    padding: const EdgeInsets.only(top: 12),
                    child: Text(
                      '각 단계 오른쪽 화살표 버튼으로 순서를 조정할 수 있습니다.',
                      style: theme.textTheme.muted,
                    ),
                  ),
                if (duplicates.isNotEmpty)
                  Padding(
                    padding: const EdgeInsets.only(top: 12),
                    child: Text(
                      '동일한 승인자가 중복된 단계가 있습니다. 승인자를 조정해 주세요.',
                      style: theme.textTheme.small.copyWith(
                        color: theme.colorScheme.destructive,
                      ),
                    ),
                  ),
                if (hasRequesterConflict)
                  Padding(
                    padding: const EdgeInsets.only(top: 12),
                    child: Text(
                      '상신자와 동일한 승인자는 구성에 포함될 수 없습니다. 다른 승인자를 선택하세요.',
                      style: theme.textTheme.small.copyWith(
                        color: theme.colorScheme.destructive,
                      ),
                    ),
                  ),
                if (hasReachedLimit)
                  Padding(
                    padding: const EdgeInsets.only(top: 12),
                    child: Text(
                      '결재 단계는 최대 ${widget.controller.maxSteps}개까지 추가할 수 있습니다.',
                      style: theme.textTheme.small.copyWith(
                        color: theme.colorScheme.mutedForeground,
                      ),
                    ),
                  ),
                if (widget.controller.errorMessage != null) ...[
                  const SizedBox(height: 12),
                  Text(
                    widget.controller.errorMessage!,
                    style: theme.textTheme.small.copyWith(
                      color: theme.colorScheme.destructive,
                    ),
                  ),
                ],
              ],
            ),
          ),
        );
      },
    );
  }

  Set<int> _collectDuplicateApproverIds(List<ApprovalRequestStep> steps) {
    final seen = <int>{};
    final duplicates = <int>{};
    for (final step in steps) {
      final id = step.approverId;
      if (!seen.add(id)) {
        duplicates.add(id);
      }
    }
    return duplicates;
  }

  Future<void> _openAddStepDialog() async {
    ApprovalApproverCandidate? selected;
    final idController = TextEditingController();

    final result = await SuperportDialog.show<bool>(
      context: context,
      barrierDismissible: false,
      dialog: SuperportDialog(
        title: '결재 단계 추가',
        description: '승인자를 검색해 새로운 결재 단계를 추가합니다.',
        primaryAction: ShadButton(
          onPressed: () => Navigator.of(context, rootNavigator: true).pop(true),
          child: const Text('추가'),
        ),
        secondaryAction: ShadButton.ghost(
          onPressed: () =>
              Navigator.of(context, rootNavigator: true).pop(false),
          child: const Text('취소'),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text('승인자'),
            const SizedBox(height: 8),
            ApprovalApproverAutocompleteField(
              idController: idController,
              onSelected: (item) => selected = item,
            ),
            const SizedBox(height: 12),
            Text(
              '상신자와 중복되지 않도록 다른 승인자를 선택해야 합니다.',
              style: ShadTheme.of(context).textTheme.muted,
            ),
          ],
        ),
      ),
    );

    if (!mounted) {
      idController.dispose();
      return;
    }

    if (result != true) {
      idController.dispose();
      return;
    }

    final selection = selected;
    if (selection == null) {
      SuperportToast.warning(context, '유효한 승인자를 선택해주세요.');
      idController.dispose();
      return;
    }

    final participant = ApprovalRequestParticipant(
      id: selection.id,
      name: selection.name,
      employeeNo: selection.employeeNo,
    );

    final added = widget.controller.addStep(approver: participant);
    if (!added) {
      final message = widget.controller.errorMessage ?? '결재 단계를 추가하지 못했습니다.';
      SuperportToast.error(context, message);
    } else {
      SuperportToast.success(
        context,
        '"${participant.name}" 님을 단계 ${widget.controller.totalSteps}에 추가했습니다.',
      );
    }
    idController.dispose();
  }
}

class _InfoBadge extends StatelessWidget {
  const _InfoBadge({
    required this.icon,
    required this.label,
    required this.value,
  });

  final IconData icon;
  final String label;
  final String value;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(10),
        border: Border.all(color: theme.colorScheme.border),
        color: theme.colorScheme.muted.withValues(alpha: 0.12),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(icon, size: 16, color: theme.colorScheme.mutedForeground),
          const SizedBox(width: 6),
          Text('$label: $value', style: theme.textTheme.small),
        ],
      ),
    );
  }
}
