// ignore_for_file: unused_element

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 'package:marquee/marquee.dart';
import '../../core/i18n/app_localizations.dart';
import '../../core/theme/app_colors_extension.dart';
import '../../shared/widgets/app_skeletons.dart';
import '../../shared/widgets/date_range_picker.dart';
import '../../shared/widgets/list_footer.dart';
import '../../core/utils/amount_utils.dart';
import '../vehicle/vehicle_apply_api.dart';
import '../vehicle/vehicle_report_model.dart';

/// 用车明细报表 - 页面25

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

class _VehicleDetailReportPageState
    extends ConsumerState<VehicleDetailReportPage> {
  static const _monthI18nKeys = [
    '',
    'tdJanuary',
    'tdFebruary',
    'tdMarch',
    'tdApril',
    'tdMay',
    'tdJune',
    'tdJuly',
    'tdAugust',
    'tdSeptember',
    'tdOctober',
    'tdNovember',
    'tdDecember',
  ];
  final _startCtrl = TextEditingController();
  final _endCtrl = TextEditingController();
  bool _isInitialLoad = true;
  String? _error;

  // 汇总
  VehicleReportSummary? _summaryData;
  bool _summaryLoading = false;

  // 月度折线图
  List<VehicleMonthlyItem> _monthlyData = [];
  bool _monthlyLoading = false;

  // 明细
  List<VehicleReportDetailItem> _details = [];
  int _detailPage = 1;
  int _detailTotal = 0;
  bool _detailLoading = false;
  bool _detailLoadingMore = false;
  final _scrollCtrl = ScrollController();

  // 下属柱形图
  List<VehicleSubordinateItem> _subordinateData = [];
  bool _subordinateLoading = false;

  String _activeStartDate = '';
  String _activeEndDate = '';

  @override
  void initState() {
    super.initState();
    final now = DateTime.now();
    final elevenMonthsAgo = DateTime(now.year, now.month - 11, 1);
    _startCtrl.text =
        '${elevenMonthsAgo.year}-${elevenMonthsAgo.month.toString().padLeft(2, '0')}-01';
    final lastDay = DateTime(now.year, now.month + 1, 0).day;
    _endCtrl.text =
        '${now.year}-${now.month.toString().padLeft(2, '0')}-${lastDay.toString().padLeft(2, '0')}';
    _scrollCtrl.addListener(_onScroll);
    WidgetsBinding.instance.addPostFrameCallback((_) => _loadData());
  }

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

  Future<void> _loadData() async {
    _activeStartDate = _startCtrl.text;
    _activeEndDate = _endCtrl.text;
    setState(() {
      _summaryLoading = true;
      _monthlyLoading = true;
      _subordinateLoading = true;
      _detailLoading = true;
      _error = null;
    });
    try {
      final api = ref.read(vehicleApplyApiProvider);
      final results = await Future.wait([
        api.getVehicleReportSummary(
          startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : '',
          endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : '',
        ),
        api.getVehicleReportMonthly(
          startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : '',
          endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : '',
        ),
        api.getVehicleSubordinateReport(
          startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : '',
          endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : '',
        ),
        api.getVehicleReportDetail(
          startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : '',
          endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : '',
          page: 1,
        ),
      ]);
      if (!mounted) return;
      setState(() {
        _summaryData = results[0] as VehicleReportSummary;
        _monthlyData = results[1] as List<VehicleMonthlyItem>;
        _subordinateData = results[2] as List<VehicleSubordinateItem>;
        final detailResult = results[3] as Map<String, dynamic>;
        _details =
            (detailResult['list'] as List<dynamic>?)
                ?.map(
                  (e) => VehicleReportDetailItem.fromJson(
                    e as Map<String, dynamic>,
                  ),
                )
                .toList() ??
            [];
        _detailTotal = detailResult['total'] as int? ?? 0;
        _detailPage = 1;
        _isInitialLoad = false;
        _summaryLoading = false;
        _monthlyLoading = false;
        _subordinateLoading = false;
        _detailLoading = false;
      });
    } catch (e) {
      if (mounted) {
        setState(() {
          _error = e.toString();
          _isInitialLoad = false;
          _summaryLoading = false;
          _monthlyLoading = false;
          _subordinateLoading = false;
          _detailLoading = false;
        });
      }
    }
  }

  Future<void> _loadSummary() async {
    setState(() => _summaryLoading = true);
    try {
      final api = ref.read(vehicleApplyApiProvider);
      final data = await api.getVehicleReportSummary(
        startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : '',
        endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : '',
      );
      if (mounted) {
        setState(() {
          _summaryData = data;
          _summaryLoading = false;
        });
      }
    } catch (_) {
      if (mounted) setState(() => _summaryLoading = false);
    }
  }

  Future<void> _loadMonthly() async {
    setState(() => _monthlyLoading = true);
    try {
      final api = ref.read(vehicleApplyApiProvider);
      final data = await api.getVehicleReportMonthly(
        startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : '',
        endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : '',
      );
      if (mounted) {
        setState(() {
          _monthlyData = data;
          _monthlyLoading = false;
        });
      }
    } catch (_) {
      if (mounted) setState(() => _monthlyLoading = false);
    }
  }

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

  Future<void> _loadMoreDetails() async {
    if (_detailLoadingMore) return;
    if (_details.length >= _detailTotal) return;
    setState(() => _detailLoadingMore = true);
    try {
      final api = ref.read(vehicleApplyApiProvider);
      final result = await api.getVehicleReportDetail(
        startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : '',
        endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : '',
        page: _detailPage + 1,
      );
      if (!mounted) return;
      final list =
          (result['list'] as List<dynamic>?)
              ?.map(
                (e) =>
                    VehicleReportDetailItem.fromJson(e as Map<String, dynamic>),
              )
              .toList() ??
          [];
      setState(() {
        _details = [..._details, ...list];
        _detailPage++;
        _detailLoadingMore = false;
      });
    } catch (_) {
      if (mounted) setState(() => _detailLoadingMore = false);
    }
  }

  void _onScroll() {
    if (_scrollCtrl.position.pixels <
        _scrollCtrl.position.maxScrollExtent - 200) {
      return;
    }
    if (_detailTotal > 0 &&
        _details.length < _detailTotal &&
        !_detailLoadingMore) {
      _loadMoreDetails();
    }
  }

  Future<void> _loadSubordinateData() async {
    if (_subordinateLoading) return;
    setState(() => _subordinateLoading = true);
    try {
      final api = ref.read(vehicleApplyApiProvider);
      final data = await api.getVehicleSubordinateReport(
        startDate: _startCtrl.text.isNotEmpty ? _startCtrl.text : '',
        endDate: _endCtrl.text.isNotEmpty ? _endCtrl.text : '',
      );
      if (mounted) {
        setState(() {
          _subordinateData = data;
          _subordinateLoading = false;
        });
      }
    } catch (_) {
      if (mounted) setState(() => _subordinateLoading = false);
    }
  }

  // ── 日期过滤区 ──
  Widget _buildDateFilter() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    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, 12),
        child: DateRangePicker(
          startCtrl: _startCtrl,
          endCtrl: _endCtrl,
          onChanged: () {
            setState(() {});
            _detailPage = 1;
            _detailTotal = 0;
            _isInitialLoad = false;
            _loadData();
          },
        ),
      ),
    );
  }

  // ── 3 张统计卡片（2+1）──
  Widget _buildStatCards() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    final summary = _summaryData ?? const VehicleReportSummary();
    final cards = Padding(
      padding: const EdgeInsets.fromLTRB(12, 12, 12, 0),
      child: Column(
        children: [
          Row(
            children: [
              Expanded(
                child: _statCard(
                  l10n.get('statTotalTrips'),
                  '${summary.totalTrips}',
                  colors.textPrimary,
                ),
              ),
              const SizedBox(width: 8),
              Expanded(
                child: _statCard(
                  l10n.get('statTotalCost'),
                  formatAmount(summary.totalCost),
                  colors.amountPrimary,
                ),
              ),
            ],
          ),
          const SizedBox(height: 8),
          _statCard(
            l10n.get('statTotalMileage'),
            summary.totalMileage.toStringAsFixed(1),
            colors.success,
          ),
        ],
      ),
    );
    return Stack(
      children: [
        cards,
        if (_summaryLoading && _summaryData != null)
          Positioned.fill(
            child: Container(
              color: Colors.white.withValues(alpha: 0.6),
              child: const Center(
                child: TDLoading(
                  size: TDLoadingSize.small,
                  icon: TDLoadingIcon.activity,
                ),
              ),
            ),
          ),
      ],
    );
  }

  Widget _statCard(String label, String value, Color valueColor) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    return Container(
      width: double.infinity,
      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: [
          _buildValue(value, valueColor),
          const SizedBox(height: 4),
          Text(
            label,
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(fontSize: 12, color: colors.textSecondary),
          ),
        ],
      ),
    );
  }

  Widget _buildValue(String value, Color valueColor) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final style = TextStyle(
          fontSize: 18,
          fontWeight: FontWeight.w700,
          color: valueColor,
        );
        final tp = TextPainter(
          text: TextSpan(text: value, style: style),
          textDirection: TextDirection.ltr,
          textScaler: MediaQuery.textScalerOf(context),
          maxLines: 1,
        )..layout();
        if (tp.width > constraints.maxWidth) {
          return SizedBox(
            height: tp.height,
            child: Marquee(
              text: value,
              style: style,
              scrollAxis: Axis.horizontal,
              blankSpace: 40,
              velocity: 30,
              pauseAfterRound: const Duration(seconds: 1),
              startPadding: 0,
            ),
          );
        }
        return Text(value, softWrap: false, style: style);
      },
    );
  }

  // ── 折线图（出车次数）──
  Widget _buildChartSection() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    final chart = 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('chartTitle3'),
              style: TextStyle(
                fontSize: 14,
                fontWeight: FontWeight.w600,
                color: colors.textPrimary,
              ),
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                _legendDot(colors.primary, l10n.get('statMonthTrips')),
              ],
            ),
            const SizedBox(height: 16),
            SizedBox(height: 200, child: _buildSingleLineChart()),
          ],
        ),
      ),
    );
    return Stack(
      children: [
        chart,
        if (_monthlyLoading && _monthlyData.isNotEmpty)
          Positioned.fill(
            child: Container(
              color: Colors.white.withValues(alpha: 0.6),
              child: const Center(
                child: TDLoading(
                  size: TDLoadingSize.small,
                  icon: TDLoadingIcon.activity,
                ),
              ),
            ),
          ),
      ],
    );
  }

  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 _buildSingleLineChart() {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);

    if (_monthlyData.isEmpty) {
      return Center(
        child: Text(
          l10n.get('noChartData'),
          style: TextStyle(fontSize: 14, color: colors.textPlaceholder),
        ),
      );
    }

    // 根据日期区间生成月份列表
    final start = DateTime.tryParse(_activeStartDate);
    final end = DateTime.tryParse(_activeEndDate);
    final monthLabels = <String>[];
    final monthKeys = <int>[];
    if (start != null && end != null) {
      var cur = DateTime(start.year, start.month, 1);
      final endMonth = DateTime(end.year, end.month, 1);
      while (!cur.isAfter(endMonth)) {
        monthLabels.add(l10n.get(_monthI18nKeys[cur.month]));
        monthKeys.add(cur.month);
        cur = DateTime(cur.year, cur.month + 1, 1);
      }
    }

    // 建立 API 数据索引
    final monthlyMap = <int, VehicleMonthlyItem>{};
    for (final item in _monthlyData) {
      monthlyMap[item.month] = item;
    }

    final tripsData = monthKeys.map((m) {
      final item = monthlyMap[m];
      return item?.trips.toDouble() ?? 0.0;
    }).toList();

    final maxTrips = tripsData.reduce((a, b) => a > b ? a : b);
    final leftMaxY = (maxTrips > 0 ? maxTrips * 1.2 : 10).toDouble();

    return Padding(
      padding: const EdgeInsets.only(top: 8),
      child: LineChart(
        LineChartData(
          gridData: FlGridData(
            show: true,
            drawVerticalLine: false,
            horizontalInterval: leftMaxY / 4,
            getDrawingHorizontalLine: (v) =>
                FlLine(color: colors.border, strokeWidth: 0.5),
          ),
          titlesData: FlTitlesData(
            leftTitles: AxisTitles(
              sideTitles: SideTitles(
                showTitles: true,
                reservedSize: 32,
                interval: leftMaxY / 4,
                getTitlesWidget: (v, meta) => Text(
                  '${v.toInt()}',
                  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 >= monthLabels.length) {
                    return const SizedBox();
                  }
                  return Padding(
                    padding: const EdgeInsets.only(top: 4),
                    child: Text(
                      monthLabels[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: leftMaxY,
          lineTouchData: LineTouchData(
            enabled: true,
            touchTooltipData: LineTouchTooltipData(
              fitInsideHorizontally: true,
              fitInsideVertically: true,
              getTooltipColor: (_) =>
                  colors.textPrimary.withValues(alpha: 0.85),
              getTooltipItems: (spots) => spots.map((s) {
                return LineTooltipItem(
                  '${monthLabels[s.spotIndex]} ${s.y.toInt()} ${l10n.get('unitCount')}',
                  const TextStyle(
                    color: Colors.white,
                    fontSize: 12,
                    fontWeight: FontWeight.w500,
                  ),
                );
              }).toList(),
            ),
          ),
          lineBarsData: [
            // 出车次数 - 左轴
            LineChartBarData(
              spots: List.generate(
                tripsData.length,
                (i) => FlSpot(i.toDouble(), tripsData[i]),
              ),
              isCurved: true,
              preventCurveOverShooting: 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),
              ),
            ),
          ],
        ),
      ),
    );
  }

  // ── 柱形图（下属出车次数对比） ──
  Widget _buildBarChartSection() {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;

    if (_subordinateLoading && _subordinateData.isEmpty) {
      return Padding(
        padding: const EdgeInsets.symmetric(horizontal: 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('chartTitle7'),
                style: TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.w600,
                  color: colors.textPrimary,
                ),
              ),
              const SizedBox(height: 16),
              const SizedBox(
                height: 180,
                child: Center(
                  child: TDLoading(
                    size: TDLoadingSize.small,
                    icon: TDLoadingIcon.activity,
                  ),
                ),
              ),
            ],
          ),
        ),
      );
    }

    if (_subordinateData.isEmpty) {
      return Padding(
        padding: const EdgeInsets.symmetric(horizontal: 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('chartTitle7'),
                style: TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.w600,
                  color: colors.textPrimary,
                ),
              ),
              const SizedBox(height: 16),
              SizedBox(
                height: 180,
                child: Center(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Icon(
                        Icons.inbox_outlined,
                        size: 48,
                        color: colors.textPlaceholder,
                      ),
                      const SizedBox(height: 12),
                      Text(
                        l10n.get('noChartData'),
                        style: TextStyle(
                          fontSize: 14,
                          color: colors.textSecondary,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      );
    }

    return Stack(
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 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('chartTitle7'),
                  style: TextStyle(
                    fontSize: 14,
                    fontWeight: FontWeight.w600,
                    color: colors.textPrimary,
                  ),
                ),
                const SizedBox(height: 16),
                SizedBox(
                  height: 220,
                  child: SingleChildScrollView(
                    scrollDirection: Axis.horizontal,
                    child: SizedBox(
                      width: (_subordinateData.length * 60.0).clamp(
                        MediaQuery.of(context).size.width - 56,
                        double.infinity,
                      ),
                      child: Padding(
                        padding: const EdgeInsets.only(top: 8),
                        child: BarChart(
                          BarChartData(
                            alignment: _subordinateData.length == 1
                                ? BarChartAlignment.center
                                : BarChartAlignment.spaceAround,
                            maxY:
                                (_subordinateData
                                            .map((e) => e.trips.toDouble())
                                            .reduce((a, b) => a > b ? a : b) *
                                        1.2)
                                    .clamp(1, double.infinity),
                            barTouchData: BarTouchData(
                              enabled: true,
                              touchTooltipData: BarTouchTooltipData(
                                fitInsideHorizontally: true,
                                fitInsideVertically: true,
                                getTooltipColor: (_) =>
                                    colors.textPrimary.withValues(alpha: 0.85),
                                getTooltipItem: (group, groupIndex, rod, rodIndex) {
                                  final item = _subordinateData[group.x];
                                  return BarTooltipItem(
                                    '${item.usrName}\n${rod.toY.toInt()}${l10n.get('unitCount')}',
                                    const TextStyle(
                                      color: Colors.white,
                                      fontSize: 12,
                                      fontWeight: FontWeight.w500,
                                    ),
                                  );
                                },
                              ),
                            ),
                            barGroups: _subordinateData.asMap().entries.map((
                              e,
                            ) {
                              final barColors = [
                                colors.chart1,
                                colors.chart2,
                                colors.chart3,
                                colors.chart4,
                                colors.chart5,
                                colors.primary,
                                colors.success,
                                colors.warning,
                                colors.infoText,
                                colors.danger,
                              ];
                              return BarChartGroupData(
                                x: e.key,
                                barRods: [
                                  BarChartRodData(
                                    toY: e.value.trips.toDouble(),
                                    color: barColors[e.key % barColors.length],
                                    width: _subordinateData.length == 1
                                        ? 40
                                        : 20,
                                    borderRadius: const BorderRadius.vertical(
                                      top: Radius.circular(4),
                                    ),
                                  ),
                                ],
                              );
                            }).toList(),
                            titlesData: FlTitlesData(
                              leftTitles: AxisTitles(
                                sideTitles: SideTitles(
                                  showTitles: true,
                                  reservedSize: 36,
                                  interval:
                                      (_subordinateData
                                                  .map(
                                                    (e) => e.trips.toDouble(),
                                                  )
                                                  .reduce(
                                                    (a, b) => a > b ? a : b,
                                                  ) *
                                              1.2)
                                          .clamp(1, double.infinity) /
                                      4,
                                  getTitlesWidget: (v, _) => Text(
                                    '${v.toInt()}',
                                    style: TextStyle(
                                      fontSize: 10,
                                      color: colors.textPlaceholder,
                                    ),
                                  ),
                                ),
                              ),
                              bottomTitles: AxisTitles(
                                sideTitles: SideTitles(
                                  showTitles: true,
                                  reservedSize: 40,
                                  getTitlesWidget: (v, _) {
                                    final i = v.toInt();
                                    if (i < 0 || i >= _subordinateData.length) {
                                      return const SizedBox();
                                    }
                                    return Padding(
                                      padding: const EdgeInsets.only(top: 4),
                                      child: Text(
                                        _subordinateData[i].usrName.length > 4
                                            ? '${_subordinateData[i].usrName.substring(0, 4)}...'
                                            : _subordinateData[i].usrName,
                                        style: TextStyle(
                                          fontSize: 9,
                                          color: colors.textPlaceholder,
                                        ),
                                        maxLines: 2,
                                        overflow: TextOverflow.ellipsis,
                                      ),
                                    );
                                  },
                                ),
                              ),
                              topTitles: const AxisTitles(
                                sideTitles: SideTitles(showTitles: false),
                              ),
                              rightTitles: const AxisTitles(
                                sideTitles: SideTitles(showTitles: false),
                              ),
                            ),
                            borderData: FlBorderData(show: false),
                            gridData: FlGridData(
                              show: true,
                              drawVerticalLine: false,
                              horizontalInterval:
                                  (_subordinateData
                                              .map((e) => e.trips.toDouble())
                                              .reduce((a, b) => a > b ? a : b) *
                                          1.2)
                                      .clamp(1, double.infinity) /
                                  5,
                              getDrawingHorizontalLine: (v) => FlLine(
                                color: colors.border,
                                strokeWidth: 0.5,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
        if (_subordinateLoading && _subordinateData.isNotEmpty)
          Positioned.fill(
            child: Container(
              color: Colors.white.withValues(alpha: 0.6),
              child: const Center(
                child: TDLoading(
                  size: TDLoadingSize.small,
                  icon: TDLoadingIcon.activity,
                ),
              ),
            ),
          ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final l10n = AppLocalizations.of(context);
    if (_summaryLoading && _isInitialLoad) {
      return const SkeletonVehicleDetailReportPage();
    }
    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 Column(
      children: [
        _buildDateFilter(),
        Expanded(
          child: SingleChildScrollView(
            controller: _scrollCtrl,
            child: Column(
              children: [
                _buildStatCards(),
                _buildChartSection(),
                _buildBarChartSection(),
                const SizedBox(height: 12),
                _buildDetailList(),
                const SizedBox(height: 80),
              ],
            ),
          ),
        ),
      ],
    );
  }

  // ── 明细列表 ──
  Widget _buildDetailList() {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    if (_detailLoading && _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: 64),
            child: const Center(
              child: TDLoading(
                size: TDLoadingSize.small,
                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),
                ),
              ],
            ),
          ),
        ),
      );
    }

    return Stack(
      children: [
        _buildDetailListContent(),
        if (_detailLoading && _details.isNotEmpty)
          Positioned.fill(
            child: Container(
              color: Colors.white.withValues(alpha: 0.6),
              child: const Center(
                child: TDLoading(
                  size: TDLoadingSize.small,
                  icon: TDLoadingIcon.activity,
                ),
              ),
            ),
          ),
      ],
    );
  }

  Widget _buildDetailListContent() {
    final l10n = AppLocalizations.of(context);
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final hasMore = _details.length < _detailTotal;

    return Padding(
      padding: const EdgeInsets.fromLTRB(12, 0, 12, 8),
      child: Container(
        width: double.infinity,
        decoration: BoxDecoration(
          color: colors.bgCard,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          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,
                    ),
                  ),
                  const Spacer(),
                  Text(
                    '${l10n.get('total')} $_detailTotal ${l10n.get('unitItem')}',
                    style: TextStyle(fontSize: 12, color: colors.textSecondary),
                  ),
                ],
              ),
            ),
            Divider(height: 1, color: colors.border),
            ListView.builder(
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              padding: EdgeInsets.zero,
              itemCount: _details.length + 1,
              itemBuilder: (_, i) {
                if (i == _details.length) {
                  if (_detailLoadingMore) {
                    return const Padding(
                      padding: EdgeInsets.symmetric(vertical: 16),
                      child: Center(
                        child: TDLoading(
                          size: TDLoadingSize.small,
                          icon: TDLoadingIcon.activity,
                        ),
                      ),
                    );
                  }
                  return ListFooter(
                    itemCount: _details.length,
                    hasMore: hasMore,
                  );
                }
                return _buildDetailItem(_details[i]);
              },
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildDetailItem(VehicleReportDetailItem d) {
    final colors = Theme.of(context).extension<AppColorsExtension>()!;
    final billDate = d.billDate != null && d.billDate!.length >= 10
        ? d.billDate!.substring(0, 10)
        : '-';
    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Flexible(
                    child: Text(
                      d.billNo,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: TextStyle(
                        fontSize: 14,
                        fontWeight: FontWeight.w600,
                        color: colors.textPrimary,
                      ),
                    ),
                  ),
                  const SizedBox(width: 12),
                  Text(
                    '${d.mileage.toStringAsFixed(1)} km',
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    style: TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.w600,
                      color: colors.success,
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 6),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    billDate,
                    style: TextStyle(fontSize: 12, color: colors.textSecondary),
                  ),
                  Text(
                    d.applicantName,
                    style: TextStyle(fontSize: 12, color: colors.textSecondary),
                  ),
                ],
              ),
              if (d.originAdr.isNotEmpty && d.destAdr.isNotEmpty) ...[
                const SizedBox(height: 4),
                Row(
                  children: [
                    Flexible(
                      child: Text(
                        '${d.originAdr} → ${d.destAdr}',
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: TextStyle(fontSize: 12, color: colors.textSecondary),
                      ),
                    ),
                  ],
                ),
              ],
              if (d.reason.isNotEmpty) ...[
                const SizedBox(height: 4),
                Text(
                  d.reason,
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                  style: TextStyle(fontSize: 12, color: colors.textSecondary),
                ),
              ],
              if (d.licensePlate.isNotEmpty) ...[
                const SizedBox(height: 6),
                Container(
                  padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1),
                  decoration: BoxDecoration(
                    color: colors.platePrimary.withValues(alpha: 0.1),
                    borderRadius: BorderRadius.circular(4),
                  ),
                  child: Text(
                    d.licensePlate,
                    style: TextStyle(
                      fontSize: 11,
                      fontWeight: FontWeight.w500,
                      color: colors.platePrimary,
                    ),
                  ),
                ),
              ],
            ],
          ),
        ),
        Divider(height: 1, color: colors.border),
      ],
    );
  }
}
