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 '../../../../../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_date_picker.dart';
import '../../../../../widgets/components/superport_table.dart';
import '../../../../../widgets/components/feature_disabled_placeholder.dart';
import '../../../../auth/application/auth_service.dart';
import '../../../../auth/domain/entities/authenticated_user.dart';
import '../../domain/entities/approval_history_record.dart';
import '../../domain/repositories/approval_history_repository.dart';
import '../../../domain/repositories/approval_repository.dart';
import '../../../domain/usecases/recall_approval_use_case.dart';
import '../../../domain/usecases/resubmit_approval_use_case.dart';
import '../../../shared/widgets/widgets.dart';
import '../controllers/approval_history_controller.dart';
import '../dialogs/approval_history_detail_dialog.dart';

class ApprovalHistoryPage extends StatelessWidget {
  const ApprovalHistoryPage({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/history'),
          AppBreadcrumbItem(label: '결재 이력'),
        ],
        actions: [
          Tooltip(
            message: '다운로드는 API 연동 이후 제공됩니다.',
            child: ShadButton(
              onPressed: null,
              leading: const Icon(lucide.LucideIcons.download, size: 16),
              child: const Text('엑셀 다운로드'),
            ),
          ),
        ],
        child: const FeatureDisabledPlaceholder(
          title: '결재 이력 기능 준비 중',
          description: '결재 이력 API가 공개되면 검색과 엑셀 다운로드 기능이 활성화됩니다.',
        ),
      );
    }

    return const _ApprovalHistoryEnabledPage();
  }
}

class _ApprovalHistoryEnabledPage extends StatefulWidget {
  const _ApprovalHistoryEnabledPage();

  @override
  State<_ApprovalHistoryEnabledPage> createState() =>
      _ApprovalHistoryEnabledPageState();
}

class _ApprovalHistoryEnabledPageState
    extends State<_ApprovalHistoryEnabledPage> {
  late final ApprovalHistoryController _controller;
  final TextEditingController _searchController = TextEditingController();
  final FocusNode _searchFocus = FocusNode();
  final intl.DateFormat _dateTimeFormat = intl.DateFormat('yyyy-MM-dd HH:mm');
  DateTimeRange? _dateRange;
  String? _lastError;
  static const _pageSizeOptions = [10, 20, 50];
  int? _sortColumnIndex;
  bool _sortAscending = true;
  static const _sortableColumns = {0, 1, 2, 3, 4, 5};
  AuthenticatedUser? _currentUser;

  @override
  void initState() {
    super.initState();
    final sl = GetIt.I;
    _controller = ApprovalHistoryController(
      repository: sl<ApprovalHistoryRepository>(),
      approvalRepository: sl<ApprovalRepository>(),
      recallUseCase: sl<RecallApprovalUseCase>(),
      resubmitUseCase: sl<ResubmitApprovalUseCase>(),
    )..addListener(_handleUpdate);
    _currentUser = sl<AuthService>().session?.user;
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      await _controller.fetch();
    });
  }

  void _handleUpdate() {
    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(_handleUpdate);
    _controller.dispose();
    _searchController.dispose();
    _searchFocus.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, _) {
        final theme = ShadTheme.of(context);
        final result = _controller.result;
        final histories = result?.items ?? const <ApprovalHistoryRecord>[];
        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 sortedHistories = _applySorting(histories);

        return AppLayout(
          title: '결재 이력 조회',
          subtitle: '결재 단계 변경 기록을 결재번호·행위·기간으로 조회합니다.',
          breadcrumbs: const [
            AppBreadcrumbItem(label: '대시보드', path: dashboardRoutePath),
            AppBreadcrumbItem(label: '결재', path: '/approvals/history'),
            AppBreadcrumbItem(label: '결재 이력'),
          ],
          actions: [
            Tooltip(
              message: '다운로드 기능은 API 연동 후 제공됩니다.',
              child: ShadButton(
                onPressed: null,
                leading: const Icon(lucide.LucideIcons.download, size: 16),
                child: const Text('엑셀 다운로드'),
              ),
            ),
          ],
          toolbar: FilterBar(
            actions: [
              ShadButton.outline(
                onPressed: _controller.isLoading ? null : _applyFilters,
                child: const Text('검색 적용'),
              ),
              ShadButton.ghost(
                onPressed:
                    _controller.isLoading || !_controller.hasActiveFilters
                    ? null
                    : _resetFilters,
                child: const Text('필터 초기화'),
              ),
            ],
            children: [
              SizedBox(
                width: 240,
                child: ShadInput(
                  controller: _searchController,
                  focusNode: _searchFocus,
                  placeholder: const Text('결재번호, 승인자 검색'),
                  leading: const Icon(lucide.LucideIcons.search, size: 16),
                  onSubmitted: (_) => _applyFilters(),
                ),
              ),
              SizedBox(
                width: 200,
                child: ShadSelect<ApprovalHistoryActionFilter>(
                  key: ValueKey(_controller.actionFilter),
                  initialValue: _controller.actionFilter,
                  selectedOptionBuilder: (context, value) =>
                      Text(_actionLabel(value)),
                  onChanged: (value) {
                    if (value == null) return;
                    _controller.updateActionFilter(value);
                    _controller.fetch(page: 1);
                  },
                  options: ApprovalHistoryActionFilter.values
                      .map(
                        (filter) => ShadOption(
                          value: filter,
                          child: Text(_actionLabel(filter)),
                        ),
                      )
                      .toList(),
                ),
              ),
              SizedBox(
                width: 220,
                child: SuperportDateRangePickerButton(
                  value: _dateRange,
                  dateFormat: intl.DateFormat('yyyy-MM-dd'),
                  enabled: !_controller.isLoading,
                  firstDate: DateTime(DateTime.now().year - 5),
                  lastDate: DateTime(DateTime.now().year + 1),
                  initialDateRange:
                      _dateRange ??
                      DateTimeRange(
                        start: DateTime.now().subtract(const Duration(days: 7)),
                        end: DateTime.now(),
                      ),
                  onChanged: (range) {
                    if (range == null) return;
                    setState(() => _dateRange = range);
                    _controller.updateDateRange(range.start, range.end);
                    _controller.fetch(page: 1);
                  },
                ),
              ),
              if (_dateRange != null)
                ShadButton.ghost(
                  onPressed: _controller.isLoading ? null : _clearDateRange,
                  child: const Text('기간 초기화'),
                ),
            ],
          ),
          child: _buildHistoryTableCard(
            context,
            theme,
            sortedHistories,
            totalCount,
            currentPage,
            totalPages,
            result?.pageSize ?? _controller.pageSize,
          ),
        );
      },
    );
  }

  void _applyFilters() {
    _controller.updateQuery(_searchController.text.trim());
    if (_dateRange != null) {
      _controller.updateDateRange(_dateRange!.start, _dateRange!.end);
    }
    _controller.fetch(page: 1);
  }

  void _clearDateRange() {
    setState(() => _dateRange = null);
    _controller.updateDateRange(null, null);
    _controller.fetch(page: 1);
  }

  void _resetFilters() {
    _searchController.clear();
    _searchFocus.requestFocus();
    _dateRange = null;
    _controller.clearFilters();
    _controller.fetch(page: 1);
  }

  void _handleSortChange(int columnIndex, bool ascending) {
    setState(() {
      _sortColumnIndex = columnIndex;
      _sortAscending = ascending;
    });
  }

  List<ApprovalHistoryRecord> _applySorting(List<ApprovalHistoryRecord> items) {
    final columnIndex = _sortColumnIndex;
    if (columnIndex == null) {
      return items;
    }
    final sorted = List<ApprovalHistoryRecord>.from(items);
    sorted.sort((a, b) {
      int compare;
      switch (columnIndex) {
        case 0:
          compare = a.approvalNo.toLowerCase().compareTo(
            b.approvalNo.toLowerCase(),
          );
          break;
        case 1:
          final left = a.stepOrder ?? 0;
          final right = b.stepOrder ?? 0;
          compare = left.compareTo(right);
          break;
        case 2:
          compare = a.approver.name.toLowerCase().compareTo(
            b.approver.name.toLowerCase(),
          );
          break;
        case 3:
          compare = a.action.name.toLowerCase().compareTo(
            b.action.name.toLowerCase(),
          );
          break;
        case 4:
          compare = a.toStatus.name.toLowerCase().compareTo(
            b.toStatus.name.toLowerCase(),
          );
          break;
        case 5:
          compare = a.actionAt.compareTo(b.actionAt);
          break;
        default:
          compare = 0;
      }
      return _sortAscending ? compare : -compare;
    });
    return sorted;
  }

  String _actionLabel(ApprovalHistoryActionFilter filter) {
    switch (filter) {
      case ApprovalHistoryActionFilter.all:
        return '전체 행위';
      case ApprovalHistoryActionFilter.approve:
        return '승인';
      case ApprovalHistoryActionFilter.reject:
        return '반려';
      case ApprovalHistoryActionFilter.comment:
        return '코멘트';
    }
  }

  Widget _buildHistoryTableCard(
    BuildContext context,
    ShadThemeData theme,
    List<ApprovalHistoryRecord> histories,
    int totalCount,
    int currentPage,
    int totalPages,
    int pageSize,
  ) {
    final normalizedQuery = _controller.query.trim().toLowerCase();
    final rows = <List<ShadTableCell>>[];
    for (final record in histories) {
      final approvalNo = record.approvalNo;
      final highlight =
          normalizedQuery.isNotEmpty &&
          approvalNo.toLowerCase().contains(normalizedQuery);
      final approvalStyle = highlight
          ? theme.textTheme.small.copyWith(
              fontWeight: FontWeight.w700,
              color: theme.colorScheme.foreground,
            )
          : theme.textTheme.small;
      rows.add([
        _buildTableCell(theme, Text(approvalNo, style: approvalStyle)),
        _buildTableCell(
          theme,
          _buildStepBadge(theme, record),
          alignment: Alignment.centerLeft,
        ),
        _buildTableCell(
          theme,
          ApprovalApproverCell(
            name: record.approver.name,
            employeeNo: record.approver.employeeNo,
          ),
        ),
        _buildTableCell(
          theme,
          ShadBadge.outline(child: Text(record.action.name)),
        ),
        _buildTableCell(
          theme,
          Text(_statusLabel(record), style: theme.textTheme.small),
        ),
        _buildTableCell(
          theme,
          Text(_dateTimeFormat.format(record.actionAt.toLocal())),
        ),
        _buildTableCell(theme, ApprovalNoteTooltip(note: record.note)),
      ]);
    }

    final header = const [
      ShadTableCell.header(child: Text('결재번호')),
      ShadTableCell.header(child: Text('단계')),
      ShadTableCell.header(child: Text('승인자')),
      ShadTableCell.header(child: Text('행위')),
      ShadTableCell.header(child: Text('변경 상태')),
      ShadTableCell.header(child: Text('일시')),
      ShadTableCell.header(child: Text('메모')),
    ];

    final pagination = SuperportTablePagination(
      currentPage: currentPage,
      totalPages: totalPages,
      totalItems: totalCount,
      pageSize: pageSize,
      pageSizeOptions: _pageSizeOptions,
    );

    return ShadCard(
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('결재 이력', style: theme.textTheme.h3),
                    const SizedBox(height: 4),
                    Text('$totalCount건', style: theme.textTheme.muted),
                  ],
                ),
              ],
            ),
            const SizedBox(height: 16),
            if (_controller.isLoading)
              const Padding(
                padding: EdgeInsets.symmetric(vertical: 40),
                child: Center(child: CircularProgressIndicator()),
              )
            else if (histories.isEmpty)
              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,
                  ),
                ),
              )
            else
              SuperportTable.fromCells(
                header: header,
                rows: rows,
                rowHeight: 74,
                maxHeight: 520,
                columnSpanExtent: (index) {
                  switch (index) {
                    case 0:
                      return const FixedTableSpanExtent(150);
                    case 1:
                      return const FixedTableSpanExtent(80);
                    case 2:
                      return const FixedTableSpanExtent(220);
                    case 3:
                    case 4:
                      return const FixedTableSpanExtent(150);
                    case 5:
                      return const FixedTableSpanExtent(160);
                    default:
                      return const FixedTableSpanExtent(200);
                  }
                },
                onRowTap: _controller.isLoading
                    ? null
                    : (index) => _openHistoryDetail(histories[index]),
                sortableColumns: _sortableColumns,
                sortState: _sortColumnIndex == null
                    ? null
                    : SuperportTableSortState(
                        columnIndex: _sortColumnIndex!,
                        ascending: _sortAscending,
                      ),
                onSortChanged: _handleSortChange,
                pagination: pagination,
                onPageChange: (page) => _controller.fetch(page: page),
                onPageSizeChange: (size) {
                  _controller.updatePageSize(size);
                  _controller.fetch(page: 1);
                },
                isLoading: _controller.isLoading,
              ),
          ],
        ),
      ),
    );
  }

  Widget _buildStepBadge(ShadThemeData theme, ApprovalHistoryRecord record) {
    if (record.stepOrder == null) {
      return Text('-', style: theme.textTheme.muted);
    }
    return ShadBadge(child: Text('${record.stepOrder}단계'));
  }

  String _statusLabel(ApprovalHistoryRecord record) {
    final from = record.fromStatus?.name;
    if (from == null || from.isEmpty) {
      return record.toStatus.name;
    }
    return '$from → ${record.toStatus.name}';
  }

  Future<void> _openHistoryDetail(ApprovalHistoryRecord record) async {
    await showApprovalHistoryDetailDialog(
      context: context,
      controller: _controller,
      record: record,
      dateFormat: _dateTimeFormat,
      currentUser: _currentUser,
    );
    if (!mounted) {
      return;
    }
    _controller.clearSelection();
  }

  ShadTableCell _buildTableCell(
    ShadThemeData theme,
    Widget child, {
    Alignment alignment = Alignment.centerLeft,
  }) {
    return ShadTableCell(
      alignment: alignment,
      child: DefaultTextStyle(style: theme.textTheme.small, child: child),
    );
  }
}

/// 결재 이력 데이터를 표 형태로 렌더링하는 위젯.
