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 'package:superport_v2/core/network/failure.dart';
import 'package:superport_v2/features/approvals/domain/entities/approval.dart';
import 'package:superport_v2/features/approvals/domain/repositories/approval_repository.dart';
import 'package:superport_v2/widgets/app_layout.dart';
import 'package:superport_v2/widgets/components/empty_state.dart';
import 'package:superport_v2/widgets/components/feedback.dart';
import 'package:superport_v2/widgets/components/superport_dialog.dart';

import '../../domain/entities/dashboard_kpi.dart';
import '../../domain/entities/dashboard_pending_approval.dart';
import '../../domain/entities/dashboard_transaction_summary.dart';
import '../../domain/repositories/dashboard_repository.dart';
import '../controllers/dashboard_controller.dart';

/// Superport 메인 대시보드 화면.
class DashboardPage extends StatefulWidget {
  const DashboardPage({super.key});

  @override
  State<DashboardPage> createState() => _DashboardPageState();
}

class _DashboardPageState extends State<DashboardPage> {
  late final DashboardController _controller;
  Timer? _autoRefreshTimer;
  final intl.DateFormat _timestampFormat = intl.DateFormat('yyyy-MM-dd HH:mm');

  static const _kpiPresets = [
    _KpiPreset(
      key: 'inbound',
      label: '오늘 입고',
      icon: lucide.LucideIcons.packagePlus,
    ),
    _KpiPreset(
      key: 'outbound',
      label: '오늘 출고',
      icon: lucide.LucideIcons.packageMinus,
    ),
    _KpiPreset(
      key: 'rental',
      label: '오늘 대여',
      icon: lucide.LucideIcons.handshake,
    ),
    _KpiPreset(
      key: 'pending_approvals',
      label: '결재 대기',
      icon: lucide.LucideIcons.messageSquareWarning,
    ),
  ];

  @override
  void initState() {
    super.initState();
    _controller = DashboardController(
      repository: GetIt.I<DashboardRepository>(),
    );
    _controller.ensureLoaded();
    _autoRefreshTimer = Timer.periodic(
      const Duration(minutes: 5),
      (_) => _controller.refresh(),
    );
  }

  @override
  void dispose() {
    _autoRefreshTimer?.cancel();
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, _) {
        return AppLayout(
          title: '대시보드',
          subtitle: '입·출·대여 현황과 결재 대기를 한 눈에 확인합니다.',
          breadcrumbs: const [AppBreadcrumbItem(label: '대시보드')],
          actions: [
            ShadButton.ghost(
              onPressed: _controller.isLoading ? null : _controller.refresh,
              leading: _controller.isRefreshing
                  ? const SizedBox(
                      width: 16,
                      height: 16,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : const Icon(lucide.LucideIcons.refreshCw, size: 16),
              child: const Text('새로고침'),
            ),
          ],
          child: _buildBody(context),
        );
      },
    );
  }

  Widget _buildBody(BuildContext context) {
    final summary = _controller.summary;
    final theme = ShadTheme.of(context);

    if (_controller.isLoading && summary == null) {
      return const Center(child: CircularProgressIndicator());
    }

    if (summary == null) {
      return Center(
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 480),
          child: ShadCard(
            title: Text('대시보드 데이터를 불러오지 못했습니다.', style: theme.textTheme.h3),
            description: Text(
              _controller.errorMessage ?? '네트워크 연결을 확인한 뒤 다시 시도해 주세요.',
              style: theme.textTheme.muted,
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const SuperportEmptyState(
                  title: '데이터가 없습니다',
                  description: '권한 또는 네트워크 상태를 확인한 뒤 다시 시도해 주세요.',
                ),
                const SizedBox(height: 16),
                Align(
                  alignment: Alignment.centerRight,
                  child: ShadButton(
                    onPressed: _controller.isLoading
                        ? null
                        : _controller.refresh,
                    child: const Text('다시 시도'),
                  ),
                ),
              ],
            ),
          ),
        ),
      );
    }

    final kpiMap = summary.kpis.fold<Map<String, DashboardKpi>>({}, (map, kpi) {
      map[kpi.key] = kpi;
      return map;
    });

    return SingleChildScrollView(
      padding: const EdgeInsets.only(bottom: 48),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          if (_controller.errorMessage != null)
            Padding(
              padding: const EdgeInsets.only(bottom: 16),
              child: DecoratedBox(
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(12),
                  color: theme.colorScheme.destructive.withValues(alpha: 0.12),
                ),
                child: ListTile(
                  leading: Icon(
                    lucide.LucideIcons.info,
                    color: theme.colorScheme.destructive,
                  ),
                  title: Text(
                    '대시보드 데이터를 최신 상태로 동기화하지 못했습니다.',
                    style: theme.textTheme.small,
                  ),
                  subtitle: Text(
                    _controller.errorMessage!,
                    style: theme.textTheme.small,
                  ),
                  trailing: TextButton(
                    onPressed: _controller.refresh,
                    child: const Text('다시 시도'),
                  ),
                ),
              ),
            ),
          Wrap(
            spacing: 16,
            runSpacing: 16,
            children: [
              for (final preset in _kpiPresets)
                _KpiCard(
                  icon: preset.icon,
                  label: preset.label,
                  kpi: kpiMap[preset.key],
                ),
            ],
          ),
          const SizedBox(height: 12),
          if (summary.generatedAt != null)
            Text(
              '최근 갱신: ${_timestampFormat.format(summary.generatedAt!.toLocal())}',
              style: theme.textTheme.small,
            ),
          const SizedBox(height: 24),
          LayoutBuilder(
            builder: (context, constraints) {
              final showSidePanel = constraints.maxWidth > 920;
              return Flex(
                direction: showSidePanel ? Axis.horizontal : Axis.vertical,
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: showSidePanel
                    ? MainAxisSize.max
                    : MainAxisSize.min,
                children: [
                  Flexible(
                    flex: 3,
                    fit: showSidePanel ? FlexFit.tight : FlexFit.loose,
                    child: _RecentTransactionsCard(
                      transactions: summary.recentTransactions,
                    ),
                  ),
                  if (showSidePanel)
                    const SizedBox(width: 16)
                  else
                    const SizedBox(height: 16),
                  Flexible(
                    flex: 2,
                    fit: showSidePanel ? FlexFit.tight : FlexFit.loose,
                    child: _PendingApprovalCard(
                      approvals: summary.pendingApprovals,
                    ),
                  ),
                ],
              );
            },
          ),
          const SizedBox(height: 24),
          // TODO(superport-team): 백엔드 알림 API 연동 후 _ReminderPanel을 복원한다.
          // const _ReminderPanel(),
        ],
      ),
    );
  }
}

class _KpiCard extends StatelessWidget {
  const _KpiCard({required this.icon, required this.label, this.kpi});

  final IconData icon;
  final String label;
  final DashboardKpi? kpi;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return ConstrainedBox(
      constraints: const BoxConstraints(minWidth: 220, maxWidth: 260),
      child: ShadCard(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Icon(icon, size: 20, color: theme.colorScheme.primary),
            const SizedBox(height: 12),
            Text(label, style: theme.textTheme.small),
            const SizedBox(height: 6),
            Text(kpi?.displayValue ?? '--', style: theme.textTheme.h3),
            const SizedBox(height: 8),
            _DeltaTrendRow(kpi: kpi),
          ],
        ),
      ),
    );
  }
}

class _DeltaTrendRow extends StatelessWidget {
  const _DeltaTrendRow({this.kpi});

  final DashboardKpi? kpi;

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

    if (delta == null) {
      return Text(kpi?.trendLabel ?? '데이터 동기화 중', style: theme.textTheme.muted);
    }

    final absDelta = delta.abs();
    final percent = (absDelta * 100).toStringAsFixed(1);
    final trimmedPercent = percent.endsWith('.0')
        ? percent.substring(0, percent.length - 2)
        : percent;
    final percentText = delta > 0
        ? '+$trimmedPercent%'
        : delta < 0
        ? '-$trimmedPercent%'
        : '0%';

    final icon = delta > 0
        ? lucide.LucideIcons.arrowUpRight
        : delta < 0
        ? lucide.LucideIcons.arrowDownRight
        : lucide.LucideIcons.minus;

    final Color color;
    if (delta > 0) {
      color = theme.colorScheme.primary;
    } else if (delta < 0) {
      color = theme.colorScheme.destructive;
    } else {
      color = theme.textTheme.muted.color ?? theme.colorScheme.mutedForeground;
    }

    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Icon(icon, size: 16, color: color),
        const SizedBox(width: 4),
        Text(percentText, style: theme.textTheme.small.copyWith(color: color)),
        const SizedBox(width: 8),
        Flexible(
          child: Text(
            kpi?.trendLabel ?? '전일 대비',
            overflow: TextOverflow.ellipsis,
            style: theme.textTheme.muted,
          ),
        ),
      ],
    );
  }
}

class _RecentTransactionsCard extends StatelessWidget {
  const _RecentTransactionsCard({required this.transactions});

  final List<DashboardTransactionSummary> transactions;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return ShadCard(
      title: Text('최근 트랜잭션', style: theme.textTheme.h3),
      description: Text(
        '최근 7일간의 입·출고 및 대여/결재 흐름입니다.',
        style: theme.textTheme.muted,
      ),
      child: SizedBox(
        height: 320,
        child: transactions.isEmpty
            ? const Center(
                child: SuperportEmptyState(
                  title: '최근 트랜잭션이 없습니다',
                  description: '최근 7일간 생성된 입·출·대여 트랜잭션이 없습니다.',
                ),
              )
            : ShadTable.list(
                header: const [
                  ShadTableCell.header(child: Text('번호')),
                  ShadTableCell.header(child: Text('일자')),
                  ShadTableCell.header(child: Text('유형')),
                  ShadTableCell.header(child: Text('상태')),
                  ShadTableCell.header(child: Text('작성자')),
                ],
                children: [
                  for (final row in transactions)
                    [
                      ShadTableCell(child: Text(row.transactionNo)),
                      ShadTableCell(child: Text(row.transactionDate)),
                      ShadTableCell(child: Text(row.transactionType)),
                      ShadTableCell(child: Text(row.statusName)),
                      ShadTableCell(child: Text(row.createdBy)),
                    ],
                ],
                columnSpanExtent: (index) => const FixedTableSpanExtent(140),
                rowSpanExtent: (index) => const FixedTableSpanExtent(52),
              ),
      ),
    );
  }
}

class _PendingApprovalCard extends StatelessWidget {
  const _PendingApprovalCard({required this.approvals});

  final List<DashboardPendingApproval> approvals;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    if (approvals.isEmpty) {
      return ShadCard(
        title: Text('내 결재 대기', style: theme.textTheme.h3),
        description: Text(
          '최종 승인 대기 전표는 기본 목록에 노출되지 않습니다.',
          style: theme.textTheme.muted,
        ),
        child: const SuperportEmptyState(
          title: '대기 중인 결재가 없습니다',
          description: '최종 승인 대기 전표가 생성되면 이곳에 표시됩니다.',
        ),
      );
    }

    final now = DateTime.now();
    final dateFormat = intl.DateFormat('yyyy-MM-dd HH:mm');

    return ShadCard(
      title: Text('내 결재 대기', style: theme.textTheme.h3),
      description: Text(
        '최종 승인 대기 전표를 한곳에서 확인하고 처리할 수 있습니다.',
        style: theme.textTheme.muted,
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          for (var index = 0; index < approvals.length; index++) ...[
            _PendingApprovalListTile(
              approval: approvals[index],
              now: now,
              dateFormat: dateFormat,
              onViewDetail: () => _handleViewDetail(context, approvals[index]),
            ),
            if (index < approvals.length - 1) const Divider(),
          ],
        ],
      ),
    );
  }

  void _handleViewDetail(
    BuildContext context,
    DashboardPendingApproval approval,
  ) async {
    final approvalId = approval.approvalId;
    debugPrint(
      '[DashboardPage] 상세 버튼 클릭: approvalId=$approvalId, approvalNo=${approval.approvalNo}',
    ); // 클릭 시 결재 식별자를 로그로 남겨 추적한다.
    if (approvalId == null) {
      debugPrint(
        '[DashboardPage] 결재 상세 조회 불가 - pending_approvals 응답에 approval_id가 없습니다.',
      );
      SuperportToast.error(context, '결재 상세를 조회할 수 없습니다. (식별자 없음)');
      return;
    }
    final repository = GetIt.I<ApprovalRepository>();
    final detailFuture = repository
        .fetchDetail(approvalId, includeSteps: true, includeHistories: true)
        .catchError((error) {
          final failure = Failure.from(error);
          debugPrint(
            '[DashboardPage] 대시보드 결재 상세 조회 실패: ${failure.describe()}',
          ); // 콘솔에 에러를 표시해 즉시 추적한다.
          if (context.mounted) {
            SuperportToast.error(context, failure.describe());
          }
          throw error;
        })
        .then((detail) {
          debugPrint(
            '[DashboardPage] 결재 상세 조회 성공: id=${detail.id}, approvalNo=${detail.approvalNo}',
          );
          return detail;
        });
    if (!context.mounted) {
      return;
    }
    await SuperportDialog.show<void>(
      context: context,
      dialog: SuperportDialog(
        title: '결재 상세',
        description: '결재번호 ${approval.approvalNo}',
        constraints: const BoxConstraints(maxWidth: 760),
        actions: [
          ShadButton(
            onPressed: () =>
                Navigator.of(context, rootNavigator: true).maybePop(),
            child: const Text('닫기'),
          ),
        ],
        child: SizedBox(
          width: double.infinity,
          height: 480,
          child: FutureBuilder<Approval>(
            future: detailFuture,
            builder: (dialogContext, snapshot) {
              if (snapshot.connectionState != ConnectionState.done) {
                return const Center(child: CircularProgressIndicator());
              }
              if (snapshot.hasError) {
                final failure = Failure.from(snapshot.error!);
                return Center(
                  child: Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 16),
                    child: Text(
                      failure.describe(),
                      style: ShadTheme.of(dialogContext).textTheme.muted,
                      textAlign: TextAlign.center,
                    ),
                  ),
                );
              }
              final detail = snapshot.data!;
              return _DashboardApprovalDetailContent(approval: detail);
            },
          ),
        ),
      ),
    );
  }
}

class _PendingApprovalListTile extends StatelessWidget {
  const _PendingApprovalListTile({
    required this.approval,
    required this.now,
    required this.dateFormat,
    required this.onViewDetail,
  });

  final DashboardPendingApproval approval;
  final DateTime now;
  final intl.DateFormat dateFormat;
  final VoidCallback onViewDetail;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    final summary = _PendingApprovalSummary.parse(approval.stepSummary);
    final requestedAt = approval.requestedAt;
    final timestampLabel = requestedAt == null
        ? '상신일시 확인 불가'
        : dateFormat.format(requestedAt.toLocal());
    final elapsed = requestedAt == null
        ? null
        : _formatElapsedKorean(now.difference(requestedAt));
    final chips = <Widget>[ShadBadge(child: Text(approval.approvalNo))];
    if (summary.stage != null && summary.stage!.isNotEmpty) {
      chips.add(ShadBadge.outline(child: Text(summary.stage!)));
    }
    if (summary.actor != null && summary.actor!.isNotEmpty) {
      chips.add(ShadBadge.outline(child: Text('승인자 ${summary.actor!}')));
    }
    if (summary.status != null && summary.status!.isNotEmpty) {
      chips.add(ShadBadge.outline(child: Text('상태 ${summary.status!}')));
    }
    final description = summary.description;

    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 12),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.only(top: 4),
            child: Icon(
              lucide.LucideIcons.fileCheck,
              size: 18,
              color: theme.colorScheme.mutedForeground,
            ),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  approval.title,
                  style: theme.textTheme.p.copyWith(
                    fontWeight: FontWeight.w600,
                    color: theme.colorScheme.foreground,
                  ),
                ),
                if (chips.isNotEmpty) ...[
                  const SizedBox(height: 8),
                  Wrap(spacing: 8, runSpacing: 6, children: chips),
                ],
                if (description != null) ...[
                  const SizedBox(height: 8),
                  Text(description, style: theme.textTheme.small),
                ],
                const SizedBox(height: 8),
                Text(
                  elapsed == null
                      ? '상신: $timestampLabel'
                      : '상신: $timestampLabel · 경과 $elapsed',
                  style: theme.textTheme.small.copyWith(
                    color: theme.colorScheme.mutedForeground,
                  ),
                ),
              ],
            ),
          ),
          const SizedBox(width: 12),
          ShadButton.ghost(
            size: ShadButtonSize.sm,
            onPressed: onViewDetail,
            child: const Text('상세'),
          ),
        ],
      ),
    );
  }
}

class _PendingApprovalSummary {
  const _PendingApprovalSummary({this.stage, this.actor, this.status});

  final String? stage;
  final String? actor;
  final String? status;

  static _PendingApprovalSummary parse(String? raw) {
    if (raw == null) {
      return const _PendingApprovalSummary();
    }
    var text = raw.trim();
    if (text.isEmpty) {
      return const _PendingApprovalSummary();
    }
    String? status;
    final statusMatch = RegExp(r'\(([^)]+)\)$').firstMatch(text);
    if (statusMatch != null) {
      status = statusMatch.group(1)?.trim();
      text = text.substring(0, statusMatch.start).trim();
    }
    final parts = text.split(RegExp(r'\s*[·/→>]+\s*'));
    String? stage;
    String? actor;
    if (parts.isNotEmpty) {
      final value = parts.first.trim();
      if (value.isNotEmpty) {
        stage = value;
      }
    }
    if (parts.length >= 2) {
      final joined = parts.sublist(1).join(' · ').trim();
      if (joined.isNotEmpty) {
        actor = joined;
      }
    }
    return _PendingApprovalSummary(stage: stage, actor: actor, status: status);
  }

  String? get description {
    final segments = <String>[];
    if (stage != null && stage!.isNotEmpty) {
      segments.add('현재 단계 $stage');
    }
    if (actor != null && actor!.isNotEmpty) {
      segments.add('승인자 $actor');
    }
    if (status != null && status!.isNotEmpty) {
      segments.add('상태 $status');
    }
    if (segments.isEmpty) {
      return null;
    }
    return segments.join(' · ');
  }
}

String _formatElapsedKorean(Duration duration) {
  var value = duration;
  if (value.isNegative) {
    value = Duration(seconds: -value.inSeconds);
  }
  if (value.inMinutes < 1) {
    return '1분 미만';
  }
  if (value.inHours < 1) {
    return '${value.inMinutes}분';
  }
  if (value.inHours < 24) {
    final hours = value.inHours;
    final minutes = value.inMinutes % 60;
    if (minutes == 0) {
      return '$hours시간';
    }
    return '$hours시간 $minutes분';
  }
  if (value.inDays < 7) {
    final days = value.inDays;
    final hours = value.inHours % 24;
    if (hours == 0) {
      return '$days일';
    }
    return '$days일 $hours시간';
  }
  final weeks = value.inDays ~/ 7;
  final days = value.inDays % 7;
  if (days == 0) {
    return '$weeks주';
  }
  return '$weeks주 $days일';
}

class _DashboardApprovalDetailContent extends StatelessWidget {
  const _DashboardApprovalDetailContent({required this.approval});

  final Approval approval;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    final dateFormat = intl.DateFormat('yyyy-MM-dd HH:mm');
    final overviewRows = [
      ('결재번호', approval.approvalNo),
      ('트랜잭션번호', approval.transactionNo),
      ('현재 상태', approval.status.name),
      (
        '현재 단계',
        approval.currentStep == null
            ? '-'
            : 'Step ${approval.currentStep!.stepOrder} · '
                  '${approval.currentStep!.approver.name}',
      ),
      ('상신자', approval.requester.name),
      ('상신일시', dateFormat.format(approval.requestedAt.toLocal())),
      (
        '최종결정일시',
        approval.decidedAt == null
            ? '-'
            : dateFormat.format(approval.decidedAt!.toLocal()),
      ),
    ];
    final note = approval.note?.trim();

    return SingleChildScrollView(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('개요', style: theme.textTheme.h4),
          const SizedBox(height: 12),
          Wrap(
            spacing: 16,
            runSpacing: 12,
            children: [
              for (final row in overviewRows)
                _DetailField(label: row.$1, value: row.$2),
            ],
          ),
          if (note != null && note.isNotEmpty) ...[
            const SizedBox(height: 16),
            _DetailField(label: '비고', value: note, fullWidth: true),
          ],
          const SizedBox(height: 24),
          Text('단계', style: theme.textTheme.h4),
          const SizedBox(height: 12),
          _ApprovalStepList(steps: approval.steps, dateFormat: dateFormat),
          const SizedBox(height: 24),
          Text('이력', style: theme.textTheme.h4),
          const SizedBox(height: 12),
          _ApprovalHistoryList(
            histories: approval.histories,
            dateFormat: dateFormat,
          ),
        ],
      ),
    );
  }
}

class _DetailField extends StatelessWidget {
  const _DetailField({
    required this.label,
    required this.value,
    this.fullWidth = false,
  });

  final String label;
  final String value;
  final bool fullWidth;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    return SizedBox(
      width: fullWidth ? double.infinity : 240,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(label, style: theme.textTheme.muted),
          const SizedBox(height: 4),
          Text(value, style: theme.textTheme.p),
        ],
      ),
    );
  }
}

class _ApprovalStepList extends StatelessWidget {
  const _ApprovalStepList({required this.steps, required this.dateFormat});

  final List<ApprovalStep> steps;
  final intl.DateFormat dateFormat;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    if (steps.isEmpty) {
      return Text('등록된 결재 단계가 없습니다.', style: theme.textTheme.muted);
    }
    return ShadCard(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          for (var index = 0; index < steps.length; index++) ...[
            _ApprovalStepTile(step: steps[index], dateFormat: dateFormat),
            if (index < steps.length - 1) const Divider(),
          ],
        ],
      ),
    );
  }
}

class _ApprovalStepTile extends StatelessWidget {
  const _ApprovalStepTile({required this.step, required this.dateFormat});

  final ApprovalStep step;
  final intl.DateFormat dateFormat;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    final decidedAt = step.decidedAt;
    final note = step.note?.trim();
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 6),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Step ${step.stepOrder} · ${step.approver.name}',
            style: theme.textTheme.small,
          ),
          const SizedBox(height: 4),
          Text('상태: ${step.status.name}', style: theme.textTheme.p),
          const SizedBox(height: 2),
          Text(
            '배정: ${dateFormat.format(step.assignedAt.toLocal())}',
            style: theme.textTheme.small,
          ),
          Text(
            '결정: ${decidedAt == null ? '-' : dateFormat.format(decidedAt.toLocal())}',
            style: theme.textTheme.small,
          ),
          if (note != null && note.isNotEmpty) ...[
            const SizedBox(height: 4),
            Text('비고: $note', style: theme.textTheme.small),
          ],
        ],
      ),
    );
  }
}

class _ApprovalHistoryList extends StatelessWidget {
  const _ApprovalHistoryList({
    required this.histories,
    required this.dateFormat,
  });

  final List<ApprovalHistory> histories;
  final intl.DateFormat dateFormat;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    if (histories.isEmpty) {
      return Text('등록된 결재 이력이 없습니다.', style: theme.textTheme.muted);
    }
    return ShadCard(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          for (var index = 0; index < histories.length; index++) ...[
            _ApprovalHistoryTile(
              history: histories[index],
              dateFormat: dateFormat,
            ),
            if (index < histories.length - 1) const Divider(),
          ],
        ],
      ),
    );
  }
}

class _ApprovalHistoryTile extends StatelessWidget {
  const _ApprovalHistoryTile({required this.history, required this.dateFormat});

  final ApprovalHistory history;
  final intl.DateFormat dateFormat;

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    final note = history.note?.trim();
    final fromStatus = history.fromStatus?.name ?? '-';
    final toStatus = history.toStatus.name;
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 6),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            '${history.approver.name} · ${history.action.name}',
            style: theme.textTheme.small,
          ),
          const SizedBox(height: 4),
          Text('상태: $fromStatus → $toStatus', style: theme.textTheme.p),
          const SizedBox(height: 2),
          Text(
            '처리일시: ${dateFormat.format(history.actionAt.toLocal())}',
            style: theme.textTheme.small,
          ),
          if (note != null && note.isNotEmpty) ...[
            const SizedBox(height: 4),
            Text('비고: $note', style: theme.textTheme.small),
          ],
        ],
      ),
    );
  }
}

class _KpiPreset {
  const _KpiPreset({
    required this.key,
    required this.label,
    required this.icon,
  });

  final String key;
  final String label;
  final IconData icon;
}

// TODO(superport-team): 백엔드 알림 API가 준비되면 아래 mock 패널을 실제 데이터 기반으로 재구현한다.
// class _ReminderPanel extends StatelessWidget {
//   const _ReminderPanel();
//
//   @override
//   Widget build(BuildContext context) {
//     final theme = ShadTheme.of(context);
//     return ShadCard(
//       title: Text('주의/알림', style: theme.textTheme.h3),
//       description: Text(
//         '지연된 결재나 시스템 점검 일정을 확인하세요.',
//         style: theme.textTheme.muted,
//       ),
//       child: Column(
//         crossAxisAlignment: CrossAxisAlignment.stretch,
//         children: const [
//           _ReminderItem(
//             icon: lucide.LucideIcons.clock,
//             label: '결재 지연',
//             message: '영업부 장비 구매 결재가 2일째 대기 중입니다.',
//           ),
//           SizedBox(height: 12),
//           _ReminderItem(
//             icon: lucide.LucideIcons.triangleAlert,
//             label: '시스템 점검',
//             message: '2024-03-15 22:00 ~ 23:00 서버 점검이 예정되어 있습니다.',
//           ),
//           SizedBox(height: 12),
//           _ReminderItem(
//             icon: lucide.LucideIcons.mail,
//             label: '고객 문의',
//             message: '3건의 신규 고객 문의가 접수되었습니다.',
//           ),
//         ],
//       ),
//     );
//   }
// }

// class _ReminderItem extends StatelessWidget {
//   const _ReminderItem({
//     required this.icon,
//     required this.label,
//     required this.message,
//   });
//
//   final IconData icon;
//   final String label;
//   final String message;
//
//   @override
//   Widget build(BuildContext context) {
//     final theme = ShadTheme.of(context);
//     return Row(
//       crossAxisAlignment: CrossAxisAlignment.start,
//       children: [
//         Icon(icon, size: 18, color: theme.colorScheme.primary),
//         const SizedBox(width: 12),
//         Expanded(
//           child: Column(
//             crossAxisAlignment: CrossAxisAlignment.start,
//             children: [
//               Text(label, style: theme.textTheme.small),
//               const SizedBox(height: 4),
//               Text(message, style: theme.textTheme.p),
//             ],
//           ),
//         ),
//       ],
//     );
//   }
// }
