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

import '../../../../../core/config/environment.dart';
import '../../../../../core/constants/app_sections.dart';
import '../../../../../widgets/app_layout.dart';
import '../../../../../widgets/components/filter_bar.dart';
import '../../../../../widgets/components/superport_table.dart';
import '../../../../../widgets/components/feature_disabled_placeholder.dart';
import '../../../domain/entities/approval_template.dart';
import '../../../domain/repositories/approval_template_repository.dart';
import '../../../domain/usecases/apply_approval_template_use_case.dart';
import '../../../domain/usecases/save_approval_template_use_case.dart';
import '../controllers/approval_template_controller.dart';
import '../dialogs/approval_template_detail_dialog.dart';

/// 결재 템플릿 관리 페이지. 기능 플래그에 따라 준비중 화면을 노출한다.
class ApprovalTemplatePage extends StatelessWidget {
  const ApprovalTemplatePage({super.key});

  @override
  Widget build(BuildContext context) {
    final enabled = Environment.flag('FEATURE_APPROVALS_ENABLED');
    if (!enabled) {
      return AppLayout(
        title: '결재 템플릿 관리',
        subtitle: '반복되는 결재 단계를 템플릿으로 저장하고 재사용합니다.',
        breadcrumbs: const [
          AppBreadcrumbItem(label: '대시보드', path: dashboardRoutePath),
          AppBreadcrumbItem(label: '결재', path: '/approvals/templates'),
          AppBreadcrumbItem(label: '결재 템플릿'),
        ],
        actions: [
          Tooltip(
            message: '템플릿 생성은 서버 연동 후 지원됩니다.',
            child: ShadButton(
              onPressed: null,
              leading: const Icon(lucide.LucideIcons.plus, size: 16),
              child: const Text('템플릿 생성'),
            ),
          ),
        ],
        child: const FeatureDisabledPlaceholder(
          title: '결재 템플릿 기능 준비 중',
          description: '백엔드 템플릿 API가 연동되면 템플릿 생성과 단계 구성 기능이 활성화됩니다.',
        ),
      );
    }

    return const _ApprovalTemplateEnabledPage();
  }
}

/// 결재 템플릿 기능이 활성화된 경우 사용하는 실제 화면 위젯.
class _ApprovalTemplateEnabledPage extends StatefulWidget {
  const _ApprovalTemplateEnabledPage();

  @override
  State<_ApprovalTemplateEnabledPage> createState() =>
      _ApprovalTemplateEnabledPageState();
}

/// 템플릿 목록/필터/폼 상태를 관리하는 상태 클래스.
class _ApprovalTemplateEnabledPageState
    extends State<_ApprovalTemplateEnabledPage> {
  late final ApprovalTemplateController _controller;
  final TextEditingController _searchController = TextEditingController();
  final FocusNode _searchFocus = FocusNode();
  final intl.DateFormat _dateFormat = intl.DateFormat('yyyy-MM-dd HH:mm');
  String? _lastError;
  static const _pageSizeOptions = [10, 20, 50];

  @override
  void initState() {
    super.initState();
    _controller = ApprovalTemplateController(
      repository: GetIt.I<ApprovalTemplateRepository>(),
      saveTemplateUseCase: GetIt.I<SaveApprovalTemplateUseCase>(),
      applyTemplateUseCase: GetIt.I<ApplyApprovalTemplateUseCase>(),
    )..addListener(_handleControllerUpdate);
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      await _controller.fetch();
    });
  }

  void _handleControllerUpdate() {
    final error = _controller.errorMessage;
    if (error != null && error != _lastError && mounted) {
      _lastError = error;
      final messenger = ScaffoldMessenger.maybeOf(context);
      if (messenger != null) {
        messenger.showSnackBar(SnackBar(content: Text(error)));
      }
      _controller.clearError();
    }
  }

  @override
  void dispose() {
    _controller.removeListener(_handleControllerUpdate);
    _controller.dispose();
    _searchController.dispose();
    _searchFocus.dispose();
    super.dispose();
  }

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

    return AnimatedBuilder(
      animation: _controller,
      builder: (context, _) {
        final result = _controller.result;
        final templates = result?.items ?? const <ApprovalTemplate>[];
        final totalCount = result?.total ?? 0;
        final currentPage = result?.page ?? 1;
        final totalPages = result == null || result.pageSize == 0
            ? 1
            : (result.total / result.pageSize).ceil().clamp(1, 9999);
        final showReset =
            _searchController.text.trim().isNotEmpty ||
            _controller.statusFilter != ApprovalTemplateStatusFilter.all;

        return AppLayout(
          title: '결재 템플릿 관리',
          subtitle: '결재 단계 구성을 템플릿으로 저장하고 재사용합니다.',
          breadcrumbs: const [
            AppBreadcrumbItem(label: '대시보드', path: dashboardRoutePath),
            AppBreadcrumbItem(label: '결재', path: '/approvals/templates'),
            AppBreadcrumbItem(label: '결재 템플릿'),
          ],
          actions: [
            ShadButton(
              leading: const Icon(lucide.LucideIcons.plus, size: 16),
              onPressed: _controller.isSubmitting ? null : _openCreateTemplate,
              child: const Text('템플릿 생성'),
            ),
          ],
          toolbar: FilterBar(
            actions: [
              ShadButton.outline(
                onPressed: _controller.isLoading ? null : _applyFilters,
                child: const Text('검색 적용'),
              ),
              ShadButton.ghost(
                onPressed: !_controller.isLoading && showReset
                    ? _resetFilters
                    : null,
                child: const Text('필터 초기화'),
              ),
            ],
            children: [
              SizedBox(
                width: 260,
                child: ShadInput(
                  controller: _searchController,
                  focusNode: _searchFocus,
                  placeholder: const Text('템플릿코드, 템플릿명 검색'),
                  leading: const Icon(lucide.LucideIcons.search, size: 16),
                  onSubmitted: (_) => _applyFilters(),
                ),
              ),
              SizedBox(
                width: 180,
                child: ShadSelect<ApprovalTemplateStatusFilter>(
                  key: ValueKey(_controller.statusFilter),
                  initialValue: _controller.statusFilter,
                  selectedOptionBuilder: (context, value) =>
                      Text(_statusLabel(value)),
                  onChanged: (value) {
                    if (value == null) return;
                    _controller.updateStatusFilter(value);
                  },
                  options: ApprovalTemplateStatusFilter.values
                      .map(
                        (filter) => ShadOption(
                          value: filter,
                          child: Text(_statusLabel(filter)),
                        ),
                      )
                      .toList(),
                ),
              ),
            ],
          ),
          child: ShadCard(
            child: _controller.isLoading
                ? const Padding(
                    padding: EdgeInsets.all(48),
                    child: Center(child: CircularProgressIndicator()),
                  )
                : templates.isEmpty
                ? Padding(
                    padding: const EdgeInsets.all(32),
                    child: Text(
                      '등록된 결재 템플릿이 없습니다.',
                      style: theme.textTheme.muted,
                    ),
                  )
                : Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      SuperportTable.fromCells(
                        header: const [
                          ShadTableCell.header(child: Text('ID')),
                          ShadTableCell.header(child: Text('템플릿코드')),
                          ShadTableCell.header(child: Text('템플릿명')),
                          ShadTableCell.header(child: Text('결재 단계 요약')),
                          ShadTableCell.header(child: Text('설명')),
                          ShadTableCell.header(child: Text('사용')),
                          ShadTableCell.header(child: Text('변경일시')),
                        ],
                        rows: templates.map((template) {
                          return [
                            ShadTableCell(child: Text('${template.id}')),
                            ShadTableCell(child: Text(template.code)),
                            ShadTableCell(child: Text(template.name)),
                            ShadTableCell(
                              child: _TemplateStepSummaryCell(
                                key: ValueKey('template_steps_${template.id}'),
                                controller: _controller,
                                template: template,
                              ),
                            ),
                            ShadTableCell(
                              child: Text(
                                template.description?.isNotEmpty == true
                                    ? template.description!
                                    : '-',
                              ),
                            ),
                            ShadTableCell(
                              child: template.isActive
                                  ? const ShadBadge(child: Text('사용'))
                                  : const ShadBadge.outline(child: Text('미사용')),
                            ),
                            ShadTableCell(
                              child: Text(
                                template.updatedAt == null
                                    ? '-'
                                    : _dateFormat.format(
                                        template.updatedAt!.toLocal(),
                                      ),
                              ),
                            ),
                          ];
                        }).toList(),
                        rowHeight: 58,
                        maxHeight: 520,
                        columnSpanExtent: (index) {
                          switch (index) {
                            case 0:
                              return const FixedTableSpanExtent(80);
                            case 1:
                              return const FixedTableSpanExtent(160);
                            case 2:
                              return const FixedTableSpanExtent(200);
                            case 3:
                              return const FixedTableSpanExtent(300);
                            case 4:
                              return const FixedTableSpanExtent(220);
                            case 5:
                              return const FixedTableSpanExtent(100);
                            case 6:
                              return const FixedTableSpanExtent(180);
                            default:
                              return const FixedTableSpanExtent(140);
                          }
                        },
                        pagination: SuperportTablePagination(
                          currentPage: currentPage,
                          totalPages: totalPages,
                          totalItems: totalCount,
                          pageSize: _controller.pageSize,
                          pageSizeOptions: _pageSizeOptions,
                        ),
                        onPageChange: (page) => _controller.fetch(page: page),
                        onPageSizeChange: (size) {
                          _controller.updatePageSize(size);
                          _controller.fetch(page: 1);
                        },
                        isLoading: _controller.isLoading,
                        onRowTap: _controller.isSubmitting
                            ? null
                            : (index) {
                                if (templates.isEmpty) {
                                  return;
                                }
                                final int safeIndex;
                                if (index < 0) {
                                  safeIndex = 0;
                                } else if (index >= templates.length) {
                                  safeIndex = templates.length - 1;
                                } else {
                                  safeIndex = index;
                                }
                                _openTemplateDetail(templates[safeIndex]);
                              },
                      ),
                    ],
                  ),
          ),
        );
      },
    );
  }

  void _applyFilters() {
    _controller.updateQuery(_searchController.text.trim());
    _controller.fetch(page: 1);
  }

  void _resetFilters() {
    _searchController.clear();
    _controller.resetFilters();
    _controller.fetch(page: 1);
    _searchFocus.requestFocus();
  }

  String _statusLabel(ApprovalTemplateStatusFilter filter) {
    switch (filter) {
      case ApprovalTemplateStatusFilter.all:
        return '전체(사용/미사용)';
      case ApprovalTemplateStatusFilter.activeOnly:
        return '사용중';
      case ApprovalTemplateStatusFilter.inactiveOnly:
        return '미사용';
    }
  }

  Future<void> _openTemplateDetail(ApprovalTemplate template) async {
    showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (_) => const Center(child: CircularProgressIndicator()),
    );
    final detail = await _controller.fetchDetail(template.id);
    if (mounted) {
      Navigator.of(context, rootNavigator: true).pop();
    }
    if (!mounted) {
      return;
    }
    if (detail == null) {
      _showSnack('템플릿 정보를 불러오지 못했습니다. 다시 시도하세요.');
      return;
    }
    final result = await showApprovalTemplateDetailDialog(
      context: context,
      dateFormat: _dateFormat,
      template: detail,
      onCreate: _controller.create,
      onUpdate: _controller.update,
      onDelete: _controller.delete,
      onRestore: _controller.restore,
    );
    if (result != null && mounted) {
      _showSnack(result.message);
    }
  }

  Future<void> _openCreateTemplate() async {
    final result = await showApprovalTemplateDetailDialog(
      context: context,
      dateFormat: _dateFormat,
      onCreate: _controller.create,
      onUpdate: _controller.update,
      onDelete: _controller.delete,
      onRestore: _controller.restore,
    );
    if (result != null && mounted) {
      _showSnack(result.message);
    }
  }

  void _showSnack(String message) {
    final messenger = ScaffoldMessenger.maybeOf(context);
    messenger?.showSnackBar(SnackBar(content: Text(message)));
  }
}

class _TemplateStepSummaryCell extends StatefulWidget {
  const _TemplateStepSummaryCell({
    super.key,
    required this.controller,
    required this.template,
  });

  final ApprovalTemplateController controller;
  final ApprovalTemplate template;

  @override
  State<_TemplateStepSummaryCell> createState() =>
      _TemplateStepSummaryCellState();
}

class _TemplateStepSummaryCellState extends State<_TemplateStepSummaryCell> {
  bool _isLoading = false;

  Future<void> _loadSummary() async {
    if (_isLoading) return;
    setState(() {
      _isLoading = true;
    });
    try {
      await widget.controller.ensureStepSummary(widget.template.id);
    } finally {
      if (mounted) {
        setState(() {
          _isLoading = false;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return AnimatedBuilder(
      animation: widget.controller,
      builder: (context, _) {
        final steps =
            widget.controller.stepSummaryOf(widget.template.id) ??
            widget.template.steps;
        if (steps.isEmpty) {
          return ShadButton.outline(
            size: ShadButtonSize.sm,
            onPressed: _isLoading ? null : _loadSummary,
            child: _isLoading
                ? const SizedBox(
                    width: 14,
                    height: 14,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  )
                : const Text('단계 불러오기'),
          );
        }

        final displaySteps = steps.take(3).toList();
        final overflow = steps.length - displaySteps.length;
        final summaryText = steps
            .map((step) => '${step.stepOrder}. ${step.approver.name}')
            .join(' → ');

        return Tooltip(
          message: summaryText,
          preferBelow: false,
          child: Wrap(
            spacing: 6,
            runSpacing: 6,
            crossAxisAlignment: WrapCrossAlignment.center,
            children: [
              for (final step in displaySteps)
                ShadBadge(
                  child: Text(
                    '${step.stepOrder}. ${step.approver.name}',
                    style: theme.textTheme.small,
                  ),
                ),
              if (overflow > 0)
                ShadBadge.outline(
                  child: Text('+$overflow', style: theme.textTheme.small),
                ),
            ],
          ),
        );
      },
    );
  }
}
