import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import '../../core/i18n/app_localizations.dart';
import '../../core/theme/app_colors_extension.dart';
import '../../shared/widgets/app_skeletons.dart';
import 'package:skeletonizer/skeletonizer.dart';
import '../expense/expense_api.dart';
import '../expense_apply/report_model.dart';

/// 费用报销明细报表 - 页面23

class ExpenseDetailReportPage extends ConsumerStatefulWidget {
  const ExpenseDetailReportPage({super.key});
  @override
  ConsumerState<ExpenseDetailReportPage> createState() =>
      _ExpenseDetailReportPageState();
}

class _ExpenseDetailReportPageState
    extends ConsumerState<ExpenseDetailReportPage> {
  final _startCtrl = TextEditingController();
  final _endCtrl = TextEditingController();
  bool _loading = true;
  bool _isInitialLoad = true;
  String? _error;
  ReportData? _data;
  List<ReportDetailItem> _details = [];
  int _detailPage = 1;
  int _detailTotal = 0;
  bool _detailLoading = false;

  @override
  void initState() {
    super.initState();
    final now = DateTime.now();
    _startCtrl.text = '${now.year}-01-01';
    _endCtrl.text = '${now.year}-12-31';
    WidgetsBinding.instance.addPostFrameCallback((_) => _loadData());
  }

  @override
  void dispose() {
    _startCtrl.dispose();
    _endCtrl.dispose();
    super.dispose();
  }

  Future<void> _loadData() async {
    setState(() {
      _loading = true;
      _error = null;
    });
    try {
      final api = ref.read(expenseApiProvider);
      final data = await api.getExpenseReport(
        startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : null,
        endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : null,
      );
      if (mounted) {
        setState(() {
          _data = data;
          _loading = false;
        });
        _loadDetails();
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _error = e.toString();
          _loading = false;
        });
      }
    }
  }

  Future<void> _loadDetails() async {
    if (_detailLoading) return;
    setState(() => _detailLoading = true);
    try {
      final api = ref.read(expenseApiProvider);
      final result = await api.getExpenseReportDetail(
        startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : null,
        endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : null,
        page: _detailPage,
      );
      if (!mounted) return;
      final list =
          (result['list'] as List<dynamic>?)
              ?.map((e) => ReportDetailItem.fromJson(e as Map<String, dynamic>))
              .toList() ??
          [];
      setState(() {
        _details = list;
        _detailTotal = result['total'] as int? ?? 0;
        _detailLoading = false;
      });
    } catch (_) {
      if (mounted) setState(() => _detailLoading = false);
    }
  }

  // ── 日期选择 ──
  void _pickDate(TextEditingController ctrl) {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final now = DateTime.now();
    TDPicker.showDatePicker(
      context,
      title: l10n.get('selectDate'),
      backgroundColor: colors.bgCard,
      useYear: true,
      useMonth: true,
      useDay: true,
      useHour: false,
      useMinute: false,
      useSecond: false,
      useWeekDay: false,
      dateStart: const [2020, 1, 1],
      dateEnd: [now.year + 1, 12, 31],
      initialDate: [now.year, now.month, now.day],
      onConfirm: (selected) {
        ctrl.text =
            '${selected['year']}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}';
        setState(() {});
        Navigator.of(context).pop();
      },
    );
  }

  // ── 日期 chip ──
  Widget _dateChip(
    TextEditingController ctrl,
    String hint,
    TDThemeData tdTheme,
    AppColorsExtension colors,
  ) {
    final text = ctrl.text;
    return Container(
      height: 40,
      padding: const EdgeInsets.symmetric(horizontal: 8),
      decoration: BoxDecoration(
        color: colors.bgSecondaryContainer,
        borderRadius: BorderRadius.circular(20),
        border: Border.all(color: tdTheme.componentStrokeColor),
      ),
      child: Row(
        children: [
          Icon(Icons.calendar_today, size: 14, color: colors.textSecondary),
          const SizedBox(width: 4),
          Expanded(
            child: Text(
              text.isNotEmpty ? text : hint,
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                fontSize: 12,
                color: text.isNotEmpty
                    ? colors.textPrimary
                    : colors.textSecondary,
              ),
            ),
          ),
          if (text.isNotEmpty)
            GestureDetector(
              onTap: () {
                ctrl.clear();
                setState(() {});
              },
              child: Icon(Icons.close, size: 16, color: colors.textSecondary),
            ),
        ],
      ),
    );
  }

  // ── 日期过滤区 ──
  Widget _buildDateFilter() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    final tdTheme = TDTheme.of(context);
    return Container(
      decoration: BoxDecoration(
        color: colors.bgCard,
        border: Border(bottom: BorderSide(color: tdTheme.componentStrokeColor)),
      ),
      child: Padding(
        padding: const EdgeInsets.fromLTRB(12, 8, 12, 8),
        child: Row(
          children: [
            Expanded(
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () => _pickDate(_startCtrl),
                child: _dateChip(
                  _startCtrl,
                  l10n.get('filterStartDate'),
                  tdTheme,
                  colors,
                ),
              ),
            ),
            const SizedBox(width: 8),
            Text(
              '—',
              style: TextStyle(fontSize: 14, color: colors.textSecondary),
            ),
            const SizedBox(width: 8),
            Expanded(
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () => _pickDate(_endCtrl),
                child: _dateChip(
                  _endCtrl,
                  l10n.get('filterEndDate'),
                  tdTheme,
                  colors,
                ),
              ),
            ),
            const SizedBox(width: 8),
            GestureDetector(
              onTap: () {
                _details = [];
                _detailPage = 1;
                _detailTotal = 0;
                _isInitialLoad = false;
                _loadData();
                _loadDetails();
              },
              child: Container(
                width: 40,
                height: 40,
                decoration: BoxDecoration(
                  color: colors.primary,
                  borderRadius: BorderRadius.circular(20),
                ),
                child: const Icon(Icons.search, color: Colors.white, size: 22),
              ),
            ),
          ],
        ),
      ),
    );
  }

  // ── 4 张统计卡片 ──
  Widget _buildStatCards() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    final summary = _data?.summary ?? const ReportSummary();
    final pendingCount = summary.totalCount - summary.approvedCount;
    return Padding(
      padding: const EdgeInsets.fromLTRB(12, 12, 12, 0),
      child: Column(
        children: [
          Row(
            children: [
              Expanded(
                child: _statCard(
                  l10n.get('statTotalApproved'),
                  '¥${summary.totalAmount.toStringAsFixed(2)}',
                  colors.amountPrimary,
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: _statCard(
                  l10n.get('statMonthCount'),
                  '${summary.totalCount} 笔',
                  colors.textPrimary,
                ),
              ),
            ],
          ),
          const SizedBox(height: 8),
          Row(
            children: [
              Expanded(
                child: _statCard(
                  l10n.get('statPendingApprove'),
                  '$pendingCount 笔',
                  colors.textPrimary,
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: _statCard(
                  l10n.get('statPendingPayment'),
                  '0 笔',
                  colors.textPrimary,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _statCard(String label, String value, Color valueColor) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return Container(
      padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 8),
      decoration: BoxDecoration(
        color: colors.bgCard,
        borderRadius: BorderRadius.circular(8),
        boxShadow: const [
          BoxShadow(
            color: Color(0x08000000),
            blurRadius: 4,
            offset: Offset(0, 1),
          ),
        ],
      ),
      child: Column(
        children: [
          Text(
            value,
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.w700,
              color: valueColor,
            ),
          ),
          const SizedBox(height: 4),
          Text(
            label,
            style: TextStyle(fontSize: 12, color: colors.textSecondary),
          ),
        ],
      ),
    );
  }

  // ── 图表 ──
  Widget _buildChartSection() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    return Padding(
      padding: const EdgeInsets.all(12),
      child: Container(
        width: double.infinity,
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: colors.bgCard,
          borderRadius: BorderRadius.circular(8),
          boxShadow: const [
            BoxShadow(
              color: Color(0x08000000),
              blurRadius: 4,
              offset: Offset(0, 1),
            ),
          ],
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              l10n.get('chartTitle1'),
              style: TextStyle(
                fontSize: 14,
                fontWeight: FontWeight.w600,
                color: colors.textPrimary,
              ),
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                _legendDot(colors.primary, l10n.get('expenseAmount')),
                const SizedBox(width: 16),
                _legendDot(colors.success, l10n.get('approvedAmount')),
              ],
            ),
            const SizedBox(height: 12),
            SizedBox(height: 200, child: _buildDualLineChart()),
          ],
        ),
      ),
    );
  }

  Widget _legendDot(Color color, String label) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          width: 8,
          height: 8,
          decoration: BoxDecoration(color: color, shape: BoxShape.circle),
        ),
        const SizedBox(width: 4),
        Text(
          label,
          style: TextStyle(fontSize: 11, color: colors.textSecondary),
        ),
      ],
    );
  }

  Widget _buildDualLineChart() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final monthly = _data?.monthly ?? [];
    final months = [
      '1月',
      '2月',
      '3月',
      '4月',
      '5月',
      '6月',
      '7月',
      '8月',
      '9月',
      '10月',
      '11月',
      '12月',
    ];

    // 构建 12 个月的点，API 未返回的月份填 0
    final amountSpots = List.generate(12, (i) {
      final idx = monthly.indexWhere((m) => m.month == i + 1);
      return FlSpot(i.toDouble(), idx >= 0 ? monthly[idx].amount : 0);
    });
    final approvedSpots = List.generate(12, (i) {
      final idx = monthly.indexWhere((m) => m.month == i + 1);
      return FlSpot(i.toDouble(), idx >= 0 ? monthly[idx].approvedAmount : 0);
    });

    // 计算合理的 Y 轴最大值
    final allValues = <double>[];
    for (final m in monthly) {
      allValues.add(m.amount);
      allValues.add(m.approvedAmount);
    }
    final maxVal = allValues.isEmpty
        ? 100.0
        : allValues.reduce((a, b) => a > b ? a : b);
    final maxY = maxVal * 1.2;

    return LineChart(
      LineChartData(
        gridData: FlGridData(
          show: true,
          drawVerticalLine: false,
          horizontalInterval: maxY > 0 ? maxY / 5 : 20,
          getDrawingHorizontalLine: (v) =>
              FlLine(color: colors.border, strokeWidth: 0.5),
        ),
        titlesData: FlTitlesData(
          leftTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              reservedSize: 50,
              getTitlesWidget: (v, meta) {
                final val = v.toInt();
                return Text(
                  '¥$val',
                  style: TextStyle(fontSize: 10, color: colors.textPlaceholder),
                );
              },
            ),
          ),
          bottomTitles: AxisTitles(
            sideTitles: SideTitles(
              showTitles: true,
              interval: 1,
              reservedSize: 26,
              getTitlesWidget: (v, meta) {
                final i = v.toInt();
                if (i < 0 || i >= months.length) return const SizedBox();
                return Padding(
                  padding: const EdgeInsets.only(top: 4),
                  child: Text(
                    months[i],
                    style: TextStyle(
                      fontSize: 9,
                      color: colors.textPlaceholder,
                    ),
                  ),
                );
              },
            ),
          ),
          topTitles: const AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
          rightTitles: const AxisTitles(
            sideTitles: SideTitles(showTitles: false),
          ),
        ),
        borderData: FlBorderData(show: false),
        minY: 0,
        maxY: maxY > 0 ? maxY : 100,
        lineTouchData: LineTouchData(
          enabled: true,
          touchTooltipData: LineTouchTooltipData(
            getTooltipItems: (spots) => spots.map((s) {
              final mi = s.spotIndex;
              return LineTooltipItem(
                '${months[mi]}\n¥${s.y.toStringAsFixed(0)}',
                const TextStyle(
                  color: Colors.white,
                  fontSize: 12,
                  fontWeight: FontWeight.w500,
                ),
              );
            }).toList(),
          ),
        ),
        lineBarsData: [
          LineChartBarData(
            spots: amountSpots,
            isCurved: true,
            color: colors.primary,
            barWidth: 2.5,
            dotData: FlDotData(
              show: true,
              getDotPainter: (spot, percent, barData, index) =>
                  FlDotCirclePainter(
                    radius: 3,
                    color: colors.primary,
                    strokeWidth: 0,
                  ),
            ),
            belowBarData: BarAreaData(
              show: true,
              color: colors.primary.withValues(alpha: 0.08),
            ),
          ),
          LineChartBarData(
            spots: approvedSpots,
            isCurved: true,
            color: colors.success,
            barWidth: 2.5,
            dotData: FlDotData(
              show: true,
              getDotPainter: (spot, percent, barData, index) =>
                  FlDotCirclePainter(
                    radius: 3,
                    color: colors.success,
                    strokeWidth: 0,
                  ),
            ),
            belowBarData: BarAreaData(
              show: true,
              color: colors.success.withValues(alpha: 0.08),
            ),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    if (_loading && _isInitialLoad) {
      return const SkeletonReportPage();
    }
    if (_loading) {
      return SingleChildScrollView(
        child: Column(
          children: [
            _buildDateFilter(),
            const SizedBox(height: 16),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 12),
              child: Bone(height: 80, borderRadius: BorderRadius.circular(12)),
            ),
            const SizedBox(height: 16),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 12),
              child: Bone(height: 200, borderRadius: BorderRadius.circular(12)),
            ),
            const SizedBox(height: 16),
            Center(
              child: TDLoading(
                size: TDLoadingSize.medium,
                icon: TDLoadingIcon.activity,
              ),
            ),
          ],
        ),
      );
    }
    if (_error != null) {
      return Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(Icons.error_outline, size: 48, color: colors.textPlaceholder),
            const SizedBox(height: 12),
            Text(
              _error!,
              style: TextStyle(color: colors.textSecondary),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 16),
            GestureDetector(
              onTap: _loadData,
              child: Container(
                padding: const EdgeInsets.symmetric(
                  horizontal: 16,
                  vertical: 8,
                ),
                decoration: BoxDecoration(
                  color: colors.primary,
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Text(
                  l10n.get('retry'),
                  style: TextStyle(color: Colors.white, fontSize: 14),
                ),
              ),
            ),
          ],
        ),
      );
    }
    return SingleChildScrollView(
      child: Column(
        children: [
          _buildDateFilter(),
          _buildStatCards(),
          _buildChartSection(),
          _buildDetailList(),
          const SizedBox(height: 80),
        ],
      ),
    );
  }

  Widget _buildDetailList() {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    if (_detailLoading && _details.isEmpty) {
      return const Padding(
        padding: EdgeInsets.only(top: 32),
        child: Center(
          child: TDLoading(
            size: TDLoadingSize.medium,
            icon: TDLoadingIcon.activity,
          ),
        ),
      );
    }
    if (_details.isEmpty) {
      return Padding(
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
        child: Container(
          width: double.infinity,
          decoration: BoxDecoration(
            color: colors.bgCard,
            borderRadius: BorderRadius.circular(8),
          ),
          child: Padding(
            padding: const EdgeInsets.symmetric(vertical: 48),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.inbox_outlined, size: 48, color: colors.textPlaceholder),
                const SizedBox(height: 12),
                Text(
                  l10n.get('noDetailData'),
                  style: TextStyle(fontSize: 14, color: colors.textSecondary),
                ),
              ],
            ),
          ),
        ),
      );
    }
    final headerStyle = TextStyle(
      fontSize: 12,
      fontWeight: FontWeight.w600,
      color: colors.textSecondary,
    );
    final rowStyle = TextStyle(fontSize: 13, color: colors.textPrimary);
    final amountStyle = TextStyle(
      fontSize: 13,
      color: colors.amountPrimary,
      fontWeight: FontWeight.w600,
    );
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
      child: Container(
        width: double.infinity,
        decoration: BoxDecoration(
          color: colors.bgCard,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
              child: Row(
                children: [
                  Text(
                    l10n.get('detailList'),
                    style: TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.w600,
                      color: colors.textPrimary,
                    ),
                  ),
                ],
              ),
            ),
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
              color: colors.bgDisabled,
              child: Row(
                children: [
                  Expanded(
                    flex: 3,
                    child: Text(l10n.get('expenseNo'), style: headerStyle),
                  ),
                  const SizedBox(width: 8),
                  SizedBox(
                    width: 80,
                    child: Text(l10n.get('date'), style: headerStyle),
                  ),
                  const SizedBox(width: 8),
                  SizedBox(
                    width: 80,
                    child: Text(
                      l10n.get('expenseAmount'),
                      textAlign: TextAlign.right,
                      style: headerStyle,
                    ),
                  ),
                  const SizedBox(width: 8),
                  SizedBox(
                    width: 60,
                    child: Text(
                      l10n.get('filterStatus'),
                      textAlign: TextAlign.center,
                      style: headerStyle,
                    ),
                  ),
                ],
              ),
            ),
            ..._details.map((d) {
              final approved = d.isApproved;
              final chipColor = approved ? colors.success : colors.warning;
              return Padding(
                padding: const EdgeInsets.symmetric(
                  horizontal: 16,
                  vertical: 8,
                ),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Expanded(
                      flex: 3,
                      child: Text(
                        d.billNo,
                        style: rowStyle,
                        maxLines: 2,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                    const SizedBox(width: 8),
                    SizedBox(
                      width: 80,
                      child: Text(
                        d.billDate != null && d.billDate!.length >= 10
                            ? d.billDate!.substring(0, 10)
                            : '-',
                        style: rowStyle,
                        maxLines: 2,
                      ),
                    ),
                    const SizedBox(width: 8),
                    SizedBox(
                      width: 80,
                      child: Text(
                        '¥${d.amount.toStringAsFixed(2)}',
                        textAlign: TextAlign.right,
                        style: amountStyle,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                    const SizedBox(width: 8),
                    SizedBox(
                      width: 60,
                      child: Container(
                        padding: const EdgeInsets.symmetric(
                          horizontal: 6,
                          vertical: 2,
                        ),
                        decoration: BoxDecoration(
                          color: chipColor.withValues(alpha: 0.1),
                          borderRadius: BorderRadius.circular(10),
                          border: Border.all(color: chipColor, width: 0.5),
                        ),
                        child: Text(
                          approved ? l10n.get('approved') : l10n.get('pending'),
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 11,
                            color: chipColor,
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              );
            }),
            // 分页栏
            if (_detailTotal > 0)
              Container(
                padding: const EdgeInsets.symmetric(
                  horizontal: 16,
                  vertical: 10,
                ),
                decoration: BoxDecoration(
                  border: Border(
                    top: BorderSide(color: colors.border, width: 0.5),
                  ),
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    GestureDetector(
                      onTap: _detailPage > 1
                          ? () {
                              _detailPage--;
                              _loadDetails();
                            }
                          : null,
                      child: Icon(
                        Icons.chevron_left,
                        size: 20,
                        color: _detailPage > 1
                            ? colors.textPrimary
                            : colors.textPlaceholder,
                      ),
                    ),
                    const SizedBox(width: 16),
                    Text(
                      '$_detailPage',
                      style: TextStyle(fontSize: 13, color: colors.textPrimary),
                    ),
                    const SizedBox(width: 4),
                    Text(
                      '/ ${(_detailTotal / 20).ceil()}',
                      style: TextStyle(
                        fontSize: 13,
                        color: colors.textSecondary,
                      ),
                    ),
                    const SizedBox(width: 16),
                    GestureDetector(
                      onTap: _detailPage * 20 < _detailTotal
                          ? () {
                              _detailPage++;
                              _loadDetails();
                            }
                          : null,
                      child: Icon(
                        Icons.chevron_right,
                        size: 20,
                        color: _detailPage * 20 < _detailTotal
                            ? colors.textPrimary
                            : colors.textPlaceholder,
                      ),
                    ),
                    const SizedBox(width: 16),
                    Text(
                      '${l10n.get('total')} $_detailTotal ${l10n.get('items')}',
                      style: TextStyle(
                        fontSize: 12,
                        color: colors.textSecondary,
                      ),
                    ),
                  ],
                ),
              ),
            const SizedBox(height: 8),
          ],
        ),
      ),
    );
  }
}
