import 'dart:io';
import 'dart:async';
import 'dart:developer' as dev;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import 'package:device_info_plus/device_info_plus.dart';

import '../models/device_matching.dart';
import '../utils/charge_utils.dart';
import '../widgets/charge_detail_page.dart';

// --- 潘通色定义 ---
const Color kHealthGreen = Color(0xFF00B140);
const Color kHealthYellow = Color(0xFFEFDF00);
const Color kHealthOrange = Color(0xFFD75A16);

class BatteryHealthPage extends StatefulWidget {
  const BatteryHealthPage({super.key});

  @override
  State<BatteryHealthPage> createState() => _BatteryHealthPageState();
}

class _BatteryHealthPageState extends State<BatteryHealthPage>
    with SingleTickerProviderStateMixin {
  // ---------- 数据 ----------
  double _currentCap = 0;
  int _cycleCount = 0;
  double _batteryTemp = 0;
  double _batteryVolt = 0;
  int _designCap = 5050;
  String _deviceModel = "魅族21 Pro (默认)";
  double _maxTemp = 0;
  double _minTemp = 0;
  double _maxVolt = 0;
  double _minVolt = 0;
  bool _hasData = false;
  final String _filePath = '/storage/emulated/0/mbattery_charger/';

  // ---------- 趋势图数据 ----------
  List<Map<String, dynamic>> _trendData = [];

  // ---------- 充电状态 ----------
  bool _isCharging = false;
  String _chargeType = ''; // "EPP", "PPS", "SDP", "无线", "MZ_EPP" 等
  double _chargePower = 0.0;
  double _chargeVolt = 0.0;
  double _chargeCurr = 0.0;
  int? _wiredLevel;
  bool _isWireless = false;

  // 🟢 1.3.0-dev.3: 充电开始时间（UTC），用于时间窗口判断
  DateTime? _chargingStartTime;

  // 动画控制
  late AnimationController _chargeAnimationController;
  late Animation<double> _bottomSlide;
  late Animation<double> _entryFadeIn;

  // 平台通道
  static const _methodChannel = MethodChannel('com.lxh.battery_health/charge');
  static const _eventChannel = EventChannel(
    'com.lxh.battery_health/charge_events',
  );
  StreamSubscription? _chargeEventSubscription;

  // 轮询定时器（15秒）
  Timer? _pollTimer;

  // ---------- 数据库 ----------
  Database? _db;

  Future<Database> get database async {
    if (_db != null) return _db!;
    _db = await _initDatabase();
    return _db!;
  }

  Future<Database> _initDatabase() async {
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String dbPath = path.join(appDocDir.path, 'battery_health.db');
    return await openDatabase(
      dbPath,
      version: 2,
      onCreate: (db, version) async {
        await db.execute(
          'CREATE TABLE battery_history ('
          'date TEXT PRIMARY KEY, '
          'capacity INTEGER, '
          'volt_max REAL, '
          'volt_min REAL'
          ')',
        );
      },
      onUpgrade: (db, oldVersion, newVersion) async {
        if (oldVersion < 2) {
          try {
            await db.execute(
              'ALTER TABLE battery_history ADD COLUMN volt_max REAL',
            );
            await db.execute(
              'ALTER TABLE battery_history ADD COLUMN volt_min REAL',
            );
          } catch (_) {}
        }
      },
    );
  }

  Future<void> _insertOrUpdate(
    String date,
    int capacity,
    double voltMax,
    double voltMin,
  ) async {
    Database db = await database;
    await db.insert('battery_history', {
      'date': date,
      'capacity': capacity,
      'volt_max': voltMax,
      'volt_min': voltMin,
    }, conflictAlgorithm: ConflictAlgorithm.replace);
  }

  Future<List<Map<String, dynamic>>> _queryRecentData(int days) async {
    Database db = await database;
    return await db.query('battery_history', orderBy: 'date DESC', limit: days);
  }

  // ---------- 设备信息 ----------
  Future<void> _getDeviceInfo() async {
    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
    try {
      AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
      String model = androidInfo.model;
      setState(() {
        _deviceModel = DeviceMatching.getModelName(model);
        _designCap = DeviceMatching.getDesignCapacity(model);
      });
    } catch (e) {
      setState(() {
        _deviceModel = '魅族21 Pro (默认)';
        _designCap = 5050;
      });
    }
  }

  // ---------- 扫描目录 ----------
  Future<void> _scanAndUpdateDB() async {
    Directory dir = Directory(_filePath);
    if (!await dir.exists()) return;

    List<FileSystemEntity> files = await dir.list().toList();
    RegExp filePattern = RegExp(r'mbattery_charger_log_(\d{4}_\d{2}_\d{2})$');

    for (FileSystemEntity entity in files) {
      if (entity is File) {
        String fileName = path.basename(entity.path);
        Match? match = filePattern.firstMatch(fileName);
        if (match != null) {
          String dateStr = match.group(1)!.replaceAll('_', '-');
          try {
            List<String> lines = await entity.readAsLines();
            if (lines.isEmpty) continue;

            List<String> validLines = lines
                .where((line) => line.contains('tbat='))
                .toList();
            if (validLines.isEmpty) continue;

            String lastLine = validLines.last;
            RegExp capReg = RegExp(r'learned_cap=(\d+)');
            String? capStr = capReg.firstMatch(lastLine)?.group(1);
            if (capStr == null) continue;
            int cap = int.parse(capStr) ~/ 1000;

            RegExp voltReg = RegExp(r'vbat=(\d+)');
            double? maxVolt, minVolt;
            for (String line in validLines) {
              Match? match = voltReg.firstMatch(line);
              if (match != null) {
                double v = int.parse(match.group(1)!) / 1000000;
                if (maxVolt == null || v > maxVolt) maxVolt = v;
                if (minVolt == null || v < minVolt) minVolt = v;
              }
            }
            if (maxVolt == null || minVolt == null) continue;

            await _insertOrUpdate(dateStr, cap, maxVolt, minVolt);
          } catch (_) {}
        }
      }
    }
  }

  // ---------- 1.3.0-dev.1: 使用 UTC 生成文件名 ----------
  String getTodayFileName() {
    DateTime nowUtc = DateTime.now().toUtc();
    String year = nowUtc.year.toString();
    String month = nowUtc.month.toString().padLeft(2, '0');
    String day = nowUtc.day.toString().padLeft(2, '0');
    return 'mbattery_charger_log_${year}_${month}_$day';
  }

  // ---------- 时间戳工具方法 ----------
  /// 解析日志行中的时间戳，强制解析为 UTC
  DateTime? _parseLogTimestamp(String line) {
    RegExp reg = RegExp(r'\[(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})\]');
    Match? match = reg.firstMatch(line);
    if (match == null) return null;
    try {
      String dateStr = match.group(1)!;
      String timeStr = match.group(2)!;
      List<String> dateParts = dateStr.split('-');
      List<String> timeParts = timeStr.split(':');
      return DateTime.utc(
        int.parse(dateParts[0]),
        int.parse(dateParts[1]),
        int.parse(dateParts[2]),
        int.parse(timeParts[0]),
        int.parse(timeParts[1]),
        int.parse(timeParts[2]),
      );
    } catch (_) {
      return null;
    }
  }

  /// 🟢 1.3.0-dev.3: 时间窗口以插入时刻为基准，只向前看
  bool _isLogTimestampValid(DateTime? logTime) {
    if (logTime == null) return false;
    if (_chargingStartTime == null) {
      // 边缘情况：回退到当前时间 ±3 分钟
      DateTime nowUtc = DateTime.now().toUtc();
      Duration diff = nowUtc.difference(logTime);
      return diff.abs().inMinutes <= 3;
    }
    // 日志时间必须在 [充电开始时间, 充电开始时间 + 3 分钟] 范围内
    DateTime endTime = _chargingStartTime!.add(const Duration(minutes: 3));
    return logTime.isAfter(_chargingStartTime!) && logTime.isBefore(endTime);
  }

  // ---------- 核心：系统API定调 ----------
  void _applySystemChargeState(bool isCharging, String systemChargeType) {
    dev.log(
      '[_applySystemChargeState] isCharging: $isCharging, systemChargeType: $systemChargeType',
      name: 'BatteryHealth',
    );

    setState(() {
      _isCharging = isCharging;

      if (!isCharging) {
        dev.log('[_applySystemChargeState] 充电断开，重置状态', name: 'BatteryHealth');
        _chargeType = '';
        _isWireless = false;
        _chargePower = 0.0;
        _chargeVolt = 0.0;
        _chargeCurr = 0.0;
        _wiredLevel = null;
        _chargingStartTime = null; // 🟢 清空开始时间
        _updateChargeState();
        return;
      }

      // 🟢 1.3.0-dev.3: 记录充电开始时刻（仅当从断开状态变为充电状态时）
      if (_chargingStartTime == null) {
        _chargingStartTime = DateTime.now().toUtc();
        dev.log(
          '[_applySystemChargeState] 充电开始时间: $_chargingStartTime',
          name: 'BatteryHealth',
        );
      }

      if (systemChargeType == "WIRELESS") {
        dev.log('[_applySystemChargeState] 无线充电模式', name: 'BatteryHealth');
        _isWireless = true;
        _chargeType = "无线";
        _wiredLevel = null;
      } else if (systemChargeType == "AC") {
        dev.log(
          '[_applySystemChargeState] 有线快充模式 (AC/PPS)',
          name: 'BatteryHealth',
        );
        _isWireless = false;
        _chargeType = "PPS";
      } else if (systemChargeType == "USB") {
        dev.log(
          '[_applySystemChargeState] 有线慢充模式 (USB/SDP)',
          name: 'BatteryHealth',
        );
        _isWireless = false;
        _chargeType = "SDP";
      } else {
        // UNKNOWN 时清空旧类型，等待日志修正
        dev.log(
          '[_applySystemChargeState] ⚠️ 未知类型: $systemChargeType，清空类型等待日志',
          name: 'BatteryHealth',
        );
        _isWireless = false;
        _chargeType = '';
      }

      _chargePower = 0.0;
      _chargeVolt = 0.0;
      _chargeCurr = 0.0;
      _updateChargeState();
    });

    if (_isCharging) {
      _fetchChargeDataFromLog();
    }
  }

  // ---------- 日志解析 ----------
  void _parseChargeDataFromLog(List<String> lines) {
    dev.log(
      '[_parseChargeDataFromLog] 开始解析，共 ${lines.length} 行',
      name: 'BatteryHealth',
    );

    // ---------- 1. 收集所有在有效时间窗口内的数据行 ----------
    List<Map<String, dynamic>> validLines = [];
    for (String line in lines) {
      DateTime? timestamp = _parseLogTimestamp(line);
      if (!_isLogTimestampValid(timestamp)) continue;

      bool isUsb =
          line.contains('chg_usb') &&
          (line.contains('ibus=') || line.contains('real_type='));
      bool isWls = line.contains('chg_wls') && line.contains('wls_online=1');

      if (isUsb || isWls) {
        validLines.add({
          'line': line,
          'timestamp': timestamp,
          'type': isWls ? 'wls' : 'usb',
        });
      }
    }

    if (validLines.isEmpty) {
      dev.log('[_parseChargeDataFromLog] 无有效时间窗口内的数据行', name: 'BatteryHealth');
      return;
    }

    // 按时间戳排序（从新到旧）
    validLines.sort((a, b) => b['timestamp'].compareTo(a['timestamp']));

    // 取最新的一条
    Map<String, dynamic> latest = validLines.first;
    String latestLine = latest['line'];
    String latestType = latest['type'];
    DateTime latestTime = latest['timestamp'];

    dev.log(
      '[_parseChargeDataFromLog] 最新有效数据: $latestType, 时间: $latestTime',
      name: 'BatteryHealth',
    );

    // ---------- 2. 无线处理 ----------
    if (latestType == 'wls') {
      dev.log('[_parseChargeDataFromLog] 处理无线数据', name: 'BatteryHealth');

      RegExp typeReg = RegExp(r'wls_type=(\w+)');
      RegExp voltReg = RegExp(r'wls_volt=(\d+)');
      RegExp currReg = RegExp(r'wls_curr=(\d+)');

      String? wlsType = typeReg.firstMatch(latestLine)?.group(1);
      int volt = int.parse(voltReg.firstMatch(latestLine)?.group(1) ?? '0');
      int curr = int.parse(currReg.firstMatch(latestLine)?.group(1) ?? '0');

      setState(() {
        _isWireless = true;
        _chargeType = (wlsType != null && wlsType.isNotEmpty) ? wlsType : "无线";
        _chargePower = (volt * curr) / 1000000.0;
        _chargeVolt = volt / 1000.0;
        _chargeCurr = curr / 1000.0;
        _wiredLevel = null;
        dev.log(
          '[_parseChargeDataFromLog] 无线覆盖成功: $_chargeType, ${_chargePower.toStringAsFixed(2)}W',
          name: 'BatteryHealth',
        );
      });
      return;
    }

    // ---------- 3. 有线处理 ----------
    if (latestType == 'usb') {
      dev.log('[_parseChargeDataFromLog] 处理有线数据', name: 'BatteryHealth');

      RegExp ibusReg = RegExp(r'ibus=(\d+)');
      RegExp vbusReg = RegExp(r'vbus=(\d+)');
      RegExp levelReg = RegExp(r'wired_level=(\d+)');
      RegExp typeReg = RegExp(r'real_type=(\w+)');

      int ibus = int.parse(ibusReg.firstMatch(latestLine)?.group(1) ?? '0');
      int vbus = int.parse(vbusReg.firstMatch(latestLine)?.group(1) ?? '0');
      String? realType = typeReg.firstMatch(latestLine)?.group(1);
      int level = int.parse(levelReg.firstMatch(latestLine)?.group(1) ?? '0');

      setState(() {
        _chargePower = (vbus * ibus) / 1000000000.0;
        _chargeVolt = vbus / 1000000.0;
        _chargeCurr = ibus / 1000000.0;

        _isWireless = false;

        // 🟢 1.3.0-dev.2: real_type 优先级最高
        if (realType != null && realType == "PPS") {
          _chargeType = "PPS";
        } else if (realType != null &&
            (realType == "SDP" || realType == "FLOAT")) {
          _chargeType = "SDP";
        } else if (level >= 3 && _chargeType != "PPS") {
          _chargeType = "PPS";
        } else if (_chargeType.isEmpty) {
          _chargeType = "SDP";
        }

        if (_chargeType == "PPS") {
          _wiredLevel = level;
        } else {
          _wiredLevel = null;
        }

        dev.log(
          '[_parseChargeDataFromLog] 有线更新: $_chargeType, ${_chargePower.toStringAsFixed(2)}W, level: $level',
          name: 'BatteryHealth',
        );
      });
      return;
    }
  }

  // 🟢 1.3.0-dev.3: 增加超时保护
  Future<void> _fetchChargeDataFromLog() async {
    if (!_isCharging) {
      dev.log('[_fetchChargeDataFromLog] 未充电，跳过读取', name: 'BatteryHealth');
      return;
    }

    // 超时检查：如果插入超过 5 分钟还没读到数据，不再频繁报错
    if (_chargingStartTime != null) {
      Duration elapsed = DateTime.now().toUtc().difference(_chargingStartTime!);
      if (elapsed.inMinutes > 5) {
        dev.log(
          '[_fetchChargeDataFromLog] 充电开始已超过 5 分钟，跳过本次轮询',
          name: 'BatteryHealth',
        );
        return;
      }
    }

    String fullPath = _filePath + getTodayFileName();
    dev.log('[_fetchChargeDataFromLog] 尝试读取: $fullPath', name: 'BatteryHealth');

    File file = File(fullPath);
    if (!await file.exists()) {
      dev.log(
        '[_fetchChargeDataFromLog] ⚠️ 文件不存在: $fullPath',
        name: 'BatteryHealth',
      );
      return;
    }
    try {
      List<String> lines = await file.readAsLines();
      dev.log(
        '[_fetchChargeDataFromLog] ✅ 读取成功，共 ${lines.length} 行',
        name: 'BatteryHealth',
      );
      if (lines.isEmpty) return;
      _parseChargeDataFromLog(lines);
    } catch (e) {
      dev.log('[_fetchChargeDataFromLog] ❌ 读取异常: $e', name: 'BatteryHealth');
    }
  }

  // ---------- 显示辅助 ----------
  String _getDisplayPower() {
    if (!_isCharging) return '';
    if (_isWireless) {
      return ChargeUtils.getDisplayPowerWireless(_chargePower);
    } else {
      return ChargeUtils.getDisplayPowerWired(
        _chargePower,
        _wiredLevel,
        _chargeType,
      );
    }
  }

  String _getChargeTypeLabel() {
    return ChargeUtils.getChargeTypeLabel(_isWireless, _chargeType);
  }

  // ---------- 动画控制 ----------
  void _startChargeAnimation() {
    if (_chargeAnimationController.isAnimating) return;
    _chargeAnimationController.forward();
  }

  void _stopChargeAnimation() {
    if (_chargeAnimationController.isAnimating) return;
    _chargeAnimationController.reverse();
  }

  void _updateChargeState() {
    if (!mounted) return;
    if (_isCharging) {
      _startChargeAnimation();
    } else {
      _stopChargeAnimation();
    }
  }

  // ---------- 平台通道 ----------
  Future<void> _getInitialChargeState() async {
    try {
      final Map<dynamic, dynamic> result = await _methodChannel.invokeMethod(
        'getChargeState',
      );
      bool isCharging = result['isCharging'] ?? false;
      String systemType = result['chargeType'] ?? 'NONE';
      _applySystemChargeState(isCharging, systemType);
    } catch (e) {
      // 静默降级
    }
  }

  // ---------- 读取当前数据 ----------
  Future<void> readBatteryCapacity() async {
    var status = await Permission.manageExternalStorage.request();
    if (!status.isGranted) {
      setState(() => _hasData = false);
      return;
    }

    await _getDeviceInfo();
    await _scanAndUpdateDB();

    String fullPath = _filePath + getTodayFileName();
    File file = File(fullPath);

    if (!await file.exists()) {
      List<Map<String, dynamic>> recent = await _queryRecentData(1);
      if (recent.isNotEmpty) {
        setState(() {
          _currentCap = recent.first['capacity'].toDouble();
          _maxVolt = recent.first['volt_max'] ?? 0;
          _minVolt = recent.first['volt_min'] ?? 0;
          _hasData = true;
        });
        await _updateTrendChart();
      } else {
        setState(() => _hasData = false);
      }
      if (_isCharging) _fetchChargeDataFromLog();
      _chargeAnimationController.reset();
      _updateChargeState();
      return;
    }

    try {
      List<String> lines = await file.readAsLines();
      if (lines.isEmpty) {
        setState(() => _hasData = false);
        if (_isCharging) _fetchChargeDataFromLog();
        _chargeAnimationController.reset();
        _updateChargeState();
        return;
      }

      if (_isCharging) _parseChargeDataFromLog(lines);

      List<String> validLines = lines
          .where((line) => line.contains('tbat='))
          .toList();
      if (validLines.isEmpty) {
        setState(() => _hasData = false);
        _chargeAnimationController.reset();
        _updateChargeState();
        return;
      }

      String lastLine = validLines.last;
      RegExp capReg = RegExp(r'learned_cap=(\d+)');
      RegExp cycleReg = RegExp(r'cycle=(\d+)');
      RegExp tempReg = RegExp(r'tbat=(\d+)');
      RegExp voltageReg = RegExp(r'vbat=(\d+)');

      String? capStr = capReg.firstMatch(lastLine)?.group(1);
      String? cycleStr = cycleReg.firstMatch(lastLine)?.group(1);
      String? tempStr = tempReg.firstMatch(lastLine)?.group(1);
      String? voltStr = voltageReg.firstMatch(lastLine)?.group(1);

      if (capStr == null) {
        setState(() => _hasData = false);
        _chargeAnimationController.reset();
        _updateChargeState();
        return;
      }

      double capMah = int.parse(capStr) / 1000;
      int cycle = int.parse(cycleStr ?? '0');
      double temp = double.parse(tempStr ?? '0');
      double volt = double.parse(voltStr ?? '0') / 1000000;

      List<double> temps = [];
      for (String line in validLines) {
        RegExpMatch? match = tempReg.firstMatch(line);
        if (match != null) temps.add(double.parse(match.group(1)!));
      }
      double maxTemp = temps.isNotEmpty
          ? temps.reduce((a, b) => a > b ? a : b)
          : temp;
      double minTemp = temps.isNotEmpty
          ? temps.reduce((a, b) => a < b ? a : b)
          : temp;

      double? maxVolt, minVolt;
      for (String line in validLines) {
        Match? match = voltageReg.firstMatch(line);
        if (match != null) {
          double v = int.parse(match.group(1)!) / 1000000;
          if (maxVolt == null || v > maxVolt) maxVolt = v;
          if (minVolt == null || v < minVolt) minVolt = v;
        }
      }

      setState(() {
        _currentCap = capMah;
        _cycleCount = cycle;
        _batteryTemp = temp;
        _batteryVolt = volt;
        _maxTemp = maxTemp;
        _minTemp = minTemp;
        _maxVolt = maxVolt ?? volt;
        _minVolt = minVolt ?? volt;
        _hasData = true;
      });

      await _updateTrendChart();
      _chargeAnimationController.reset();
      _updateChargeState();
    } catch (e) {
      setState(() => _hasData = false);
      _chargeAnimationController.reset();
      _updateChargeState();
    }
  }

  Future<void> _updateTrendChart() async {
    List<Map<String, dynamic>> data = await _queryRecentData(15);
    setState(() {
      _trendData = data.reversed.toList();
    });
  }

  // ---------- 生命周期 ----------
  @override
  void initState() {
    super.initState();

    _chargeAnimationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
    );
    _bottomSlide = Tween<double>(begin: 0, end: 24).animate(
      CurvedAnimation(
        parent: _chargeAnimationController,
        curve: Curves.easeInOutCubic,
      ),
    );
    _entryFadeIn = Tween<double>(begin: 0, end: 1).animate(
      CurvedAnimation(
        parent: _chargeAnimationController,
        curve: const Interval(0.0, 0.5, curve: Curves.easeIn),
      ),
    );

    _getInitialChargeState();

    _chargeEventSubscription = _eventChannel.receiveBroadcastStream().listen((
      event,
    ) {
      final bool isCharging = event['isCharging'] ?? false;
      final String systemType = event['chargeType'] ?? 'NONE';
      _applySystemChargeState(isCharging, systemType);
    });

    _pollTimer = Timer.periodic(const Duration(seconds: 15), (timer) {
      if (_isCharging) {
        _fetchChargeDataFromLog();
      }
    });

    WidgetsBinding.instance.addPostFrameCallback((_) {
      readBatteryCapacity();
    });
  }

  @override
  void dispose() {
    _chargeEventSubscription?.cancel();
    _pollTimer?.cancel();
    _chargeAnimationController.dispose();
    _db?.close();
    super.dispose();
  }

  // ---------- Build ----------
  @override
  Widget build(BuildContext context) {
    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: SystemUiOverlayStyle.dark,
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: const Color.fromARGB(0, 255, 255, 255),
          elevation: 0,
          title: const Text(
            '电池健康度',
            style: TextStyle(
              fontSize: 24,
              fontWeight: FontWeight.w600,
              color: Colors.black,
            ),
          ),
          actions: [
            IconButton(
              icon: const Icon(Icons.refresh),
              onPressed: readBatteryCapacity,
              tooltip: '刷新数据',
              color: Colors.black,
            ),
          ],
        ),
        body: _hasData ? _buildDataLayout() : _buildEmptyState(),
      ),
    );
  }

  Widget _buildEmptyState() {
    return const Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.battery_unknown, size: 64, color: Colors.grey),
          SizedBox(height: 16),
          Text('暂无数据', style: TextStyle(fontSize: 18, color: Colors.grey)),
          Text('点击右上角刷新尝试', style: TextStyle(fontSize: 14, color: Colors.grey)),
        ],
      ),
    );
  }

  Widget _buildDataLayout() {
    double healthPercent = (_designCap > 0)
        ? (_currentCap / _designCap) * 100
        : 0;

    String chargeSummary = '';
    if (_isCharging) {
      String typeLabel = _getChargeTypeLabel();
      String powerLabel = _getDisplayPower();
      chargeSummary = '充电中 · $typeLabel · $powerLabel';
    }

    return Padding(
      padding: const EdgeInsets.all(20.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            _deviceModel,
            style: const TextStyle(
              fontSize: 14,
              color: Colors.grey,
              fontWeight: FontWeight.w400,
            ),
          ),
          const SizedBox(height: 4),

          Row(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              Row(
                crossAxisAlignment: CrossAxisAlignment.baseline,
                textBaseline: TextBaseline.alphabetic,
                children: [
                  Text(
                    healthPercent.toStringAsFixed(1),
                    style: const TextStyle(
                      fontSize: 40,
                      fontWeight: FontWeight.w500,
                      height: 1.0,
                    ),
                  ),
                  const SizedBox(width: 2),
                  Text(
                    '%',
                    style: TextStyle(
                      fontSize: 20,
                      fontWeight: FontWeight.w300,
                      height: 1.0,
                      color: Colors.grey.shade600,
                    ),
                  ),
                ],
              ),
              const Spacer(),
              Column(
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Text(
                    '$_cycleCount cycles',
                    style: const TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.w500,
                      height: 1.2,
                    ),
                  ),
                  const SizedBox(height: 4),
                  Text.rich(
                    TextSpan(
                      children: [
                        TextSpan(
                          text: _currentCap.toStringAsFixed(0),
                          style: const TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.w300,
                          ),
                        ),
                        TextSpan(
                          text: ' / ',
                          style: TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.w300,
                            color: Colors.grey.shade500,
                          ),
                        ),
                        TextSpan(
                          text: '${_designCap}mAh',
                          style: const TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.w300,
                          ),
                        ),
                      ],
                    ),
                    style: const TextStyle(
                      fontSize: 20,
                      fontWeight: FontWeight.w300,
                      height: 1.0,
                    ),
                  ),
                ],
              ),
            ],
          ),
          const SizedBox(height: 24),

          _buildTrendChart(),
          const SizedBox(height: 8),

          AnimatedBuilder(
            animation: _chargeAnimationController,
            builder: (context, child) {
              double entryHeight = 28 * _entryFadeIn.value;

              Widget chargeEntry = Opacity(
                opacity: _entryFadeIn.value,
                child: _buildChargeEntry(chargeSummary),
              );

              return Column(
                children: [
                  SizedBox(height: entryHeight, child: chargeEntry),
                  Transform.translate(
                    offset: Offset(0, _bottomSlide.value),
                    child: _buildBottomInfo(),
                  ),
                ],
              );
            },
          ),
          const Spacer(),
        ],
      ),
    );
  }

  Widget _buildChargeEntry(String summary) {
    return GestureDetector(
      onTap: () {
        if (_isCharging) {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => ChargeDetailPage(
                chargeType: _chargeType,
                isWireless: _isWireless,
                power: _chargePower,
                volt: _chargeVolt,
                curr: _chargeCurr,
                wiredLevel: _wiredLevel,
              ),
            ),
          );
        }
      },
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(
            summary,
            style: const TextStyle(
              fontSize: 16,
              fontWeight: FontWeight.w500,
              color: Colors.black87,
            ),
          ),
          Row(
            children: [
              Text(
                '充电信息',
                style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.w500,
                  color: Colors.grey.shade700,
                ),
              ),
              const SizedBox(width: 4),
              Text(
                '>',
                style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.w500,
                  color: Colors.grey.shade700,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildTrendChart() {
    List<Map<String, dynamic>> displayData = _trendData.isNotEmpty
        ? _trendData
        : _getMockData();

    List<String> dates = displayData.map((e) {
      String date = e['date'] as String;
      var parts = date.split('-');
      return '${parts[1]}/${parts[2]}';
    }).toList();

    List<double> percents = displayData.map((e) {
      int cap = e['capacity'] as int;
      return (cap / _designCap) * 100;
    }).toList();

    while (percents.length < 15) {
      percents.insert(0, 0);
      dates.insert(0, '');
    }
    if (percents.length > 15) {
      percents = percents.sublist(percents.length - 15);
      dates = dates.sublist(dates.length - 15);
    }

    int todayIndex = percents.length - 1;
    int sevenDaysAgoIndex = todayIndex - 7;
    bool showSevenDaysAgo = sevenDaysAgoIndex >= 0;

    String sevenDaysAgoDate = showSevenDaysAgo ? dates[sevenDaysAgoIndex] : '';
    String todayDate = dates[todayIndex];

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text(
          '容量百分比变动趋势（近15天）',
          style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
        ),
        const SizedBox(height: 8),
        Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            SizedBox(
              height: 180,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: const [
                  Text(
                    '100',
                    style: TextStyle(
                      fontSize: 10,
                      color: Colors.grey,
                      height: 1.0,
                    ),
                  ),
                  Text(
                    '70',
                    style: TextStyle(
                      fontSize: 10,
                      color: Colors.grey,
                      height: 1.0,
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(width: 4),
            Expanded(
              child: LayoutBuilder(
                builder: (context, constraints) {
                  double totalWidth = constraints.maxWidth;
                  double step = totalWidth / 15;

                  return SizedBox(
                    height: 180,
                    child: Stack(
                      children: [
                        Padding(
                          padding: const EdgeInsets.only(bottom: 20),
                          child: Row(
                            crossAxisAlignment: CrossAxisAlignment.end,
                            children: List.generate(percents.length, (index) {
                              double value = percents[index];
                              Color barColor;
                              if (value > 0) {
                                if (value >= 80)
                                  barColor = kHealthGreen;
                                else if (value >= 60)
                                  barColor = kHealthYellow;
                                else
                                  barColor = kHealthOrange;
                              } else {
                                barColor = Colors.grey.shade300;
                              }
                              double clampedValue = value.clamp(70.0, 100.0);
                              double heightFactor =
                                  (clampedValue - 70.0) / 30.0;

                              return Expanded(
                                child: Align(
                                  alignment: Alignment.bottomCenter,
                                  child: Container(
                                    margin: const EdgeInsets.symmetric(
                                      horizontal: 2,
                                    ),
                                    height: 20 + (100 * heightFactor),
                                    width: 18,
                                    decoration: BoxDecoration(
                                      color: barColor,
                                      borderRadius: BorderRadius.circular(4),
                                    ),
                                  ),
                                ),
                              );
                            }),
                          ),
                        ),
                        if (showSevenDaysAgo && sevenDaysAgoDate.isNotEmpty)
                          Positioned(
                            left: sevenDaysAgoIndex * step + (step / 2) - 14,
                            bottom: 2,
                            child: Text(
                              sevenDaysAgoDate,
                              style: const TextStyle(
                                fontSize: 9,
                                color: Colors.grey,
                                height: 1.0,
                              ),
                            ),
                          ),
                        if (todayDate.isNotEmpty)
                          Positioned(
                            left: todayIndex * step + (step / 2) - 14,
                            bottom: 2,
                            child: Text(
                              todayDate,
                              style: const TextStyle(
                                fontSize: 9,
                                color: Colors.black,
                                height: 1.0,
                                fontWeight: FontWeight.w600,
                              ),
                            ),
                          ),
                      ],
                    ),
                  );
                },
              ),
            ),
          ],
        ),
        if (percents.every((v) => v == 0))
          const Padding(
            padding: EdgeInsets.only(top: 8.0),
            child: Text(
              '暂无历史数据，请点击刷新按钮更新',
              style: TextStyle(fontSize: 12, color: Colors.grey),
            ),
          ),
      ],
    );
  }

  List<Map<String, dynamic>> _getMockData() {
    List<String> mockDates = [
      '2026-06-14',
      '2026-06-15',
      '2026-06-16',
      '2026-06-17',
      '2026-06-18',
      '2026-06-19',
      '2026-06-20',
      '2026-06-21',
      '2026-06-22',
      '2026-06-23',
      '2026-06-24',
      '2026-06-25',
      '2026-06-26',
      '2026-06-27',
      '2026-06-28',
    ];
    List<int> mockCap = [
      4635,
      4632,
      4628,
      4625,
      4620,
      4618,
      4615,
      4610,
      4608,
      4605,
      4600,
      4598,
      4595,
      4590,
      4585,
    ];
    return List.generate(
      15,
      (i) => {'date': mockDates[i], 'capacity': mockCap[i]},
    );
  }

  Widget _buildBottomInfo() {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildInfoItem(
                _buildIcon('voltage'),
                '电压',
                '${_batteryVolt.toStringAsFixed(3)}V',
              ),
              const SizedBox(height: 8),
              Row(
                children: [
                  Text(
                    '↑ ${_maxVolt.toStringAsFixed(3)}V',
                    style: const TextStyle(
                      color: Colors.red,
                      fontSize: 14,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                  const SizedBox(width: 12),
                  Text(
                    '↓ ${_minVolt.toStringAsFixed(3)}V',
                    style: const TextStyle(
                      color: Colors.blue,
                      fontSize: 14,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildInfoItem(
                _buildIcon('temperature'),
                '温度',
                '${_batteryTemp.toStringAsFixed(0)}°C',
              ),
              const SizedBox(height: 8),
              Row(
                children: [
                  Text(
                    '↑ ${_maxTemp.toStringAsFixed(0)}°C',
                    style: const TextStyle(
                      color: Colors.red,
                      fontSize: 14,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                  const SizedBox(width: 12),
                  Text(
                    '↓ ${_minTemp.toStringAsFixed(0)}°C',
                    style: const TextStyle(
                      color: Colors.blue,
                      fontSize: 14,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ],
    );
  }

  Widget _buildIcon(String type) {
    switch (type) {
      case 'voltage':
        return SvgPicture.asset(
          'assets/icons/si--lightning-fill.svg',
          width: 18,
          height: 18,
          colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.srcIn),
        );
      case 'temperature':
        return SvgPicture.asset(
          'assets/icons/mdi--temperature.svg',
          width: 18,
          height: 18,
          colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.srcIn),
        );
      default:
        return const Icon(Icons.help_outline, size: 18, color: Colors.grey);
    }
  }

  Widget _buildInfoItem(Widget icon, String label, String value) {
    return Row(
      children: [
        icon,
        const SizedBox(width: 6),
        Text(label, style: const TextStyle(fontSize: 14, color: Colors.grey)),
        const SizedBox(width: 6),
        Text(
          value,
          style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
        ),
      ],
    );
  }
}
