// home_shell.dart — 主框架(4 Tab:连接 / 节点 / 统计 / 账户)
//
// 自适应断点:同一份页面代码,宽度 ≥900 时从底部 Tab 切换为左侧栏分栏
// (LayoutBuilder 开关,不 fork 页面)。窄屏支持左右滑动切换 Tab。
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../pangolin_theme.dart';
import '../screens/account_page.dart';
import '../screens/connect_page.dart';
import '../screens/nodes_page.dart';
import '../screens/stats_page.dart';
import '../state/app_providers.dart';
import '../state/connection_provider.dart';
import '../state/nodes_provider.dart';
import 'pangolin_icons.dart';
import 'pangolin_logo.dart';
import 'tab_swipe.dart';

/// 宽屏断点(逻辑像素)。≥该值切侧栏分栏。
const double kWideBreakpoint = 900;

class HomeShell extends ConsumerStatefulWidget {
  const HomeShell({super.key});
// home_shell.dart — 主框架(底部 4 Tab:连接 / 节点 / 统计 / 账户)
//
// M6 改动：_toggle/_pick 替换为真实 ConnectApi.fetchConfig → VpnBridge.start。
// API URL / token 由 --dart-define 注入（见 README M6 联调说明），默认指向本地 mock server。
// tsk_nuoKSM4Vt-zK
import 'dart:async';
import 'package:flutter/material.dart';
import '../pangolin_theme.dart';
import '../services/connect_api.dart';
import '../services/vpn_bridge.dart';
import 'pangolin_icons.dart';
import 'connect_button.dart';
import 'server_tile.dart';
import 'country_code.dart';
import 'account_screens.dart';
import 'pangolin_logo.dart';

// ── 联调配置（由 --dart-define 注入；不入库）──
// 运行示例：flutter run --dart-define=PANGOLIN_API_URL=http://localhost:8081 \
//                       --dart-define=PANGOLIN_API_TOKEN=dev-mock-token \
//                       --dart-define=PANGOLIN_DEVICE_ID=demo-device-001
const _kApiUrl = String.fromEnvironment(
  'PANGOLIN_API_URL',
  defaultValue: 'http://localhost:8081',
);
const _kApiToken = String.fromEnvironment(
  'PANGOLIN_API_TOKEN',
  defaultValue: 'dev-mock-token',
);
const _kDeviceId = String.fromEnvironment(
  'PANGOLIN_DEVICE_ID',
  defaultValue: 'demo-device-001',
);

class HomeShell extends StatefulWidget {
  const HomeShell({super.key, this.zh = true});
  final bool zh;
  @override
  ConsumerState<HomeShell> createState() => _HomeShellState();
}

class _HomeShellState extends ConsumerState<HomeShell> {
  int _tab = 0;
  int _dir = 0;
  Timer? _dirReset;

  void _goTab(int i) {
    if (i == _tab) return;
    setState(() {
      _dir = i > _tab ? 1 : -1;
      _tab = i;
    });
    _dirReset?.cancel();
    _dirReset = Timer(const Duration(milliseconds: 260), () {
      if (mounted) setState(() => _dir = 0);
    });
  }

  void _swipe(int delta) => _goTab((_tab + delta).clamp(0, 3));

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

  List<Widget> _pages(bool isWide) => [
        ConnectPage(isWide: isWide, onOpenNodes: () => _goTab(1)),
        NodesPage(isWide: isWide, onPicked: () => _goTab(0)),
        StatsPage(isWide: isWide),
        AccountPage(isWide: isWide),
      ];
  VpnStatus _status = VpnStatus.off;
  ServerInfo _server = const ServerInfo(
    code: 'HK',
    name: '香港 · 流媒体',
    sub: 'Hong Kong',
    ping: 18,
    nodeId: 'hk-1',
  );
  Timer? _timer;
  int _elapsed = 0;

  // ── 控制面 + 数据面 ──
  late final ConnectApi _api = ConnectApi(baseUrl: _kApiUrl, authToken: _kApiToken);
  final VpnBridge _bridge = VpnBridge();

  String _t(String zh, String en) => widget.zh ? zh : en;

  // ── 连接/断开（异步，含错误路径）──
  void _toggle() {
    if (_status == VpnStatus.connecting) return; // 防重入
    if (_status == VpnStatus.off) {
      _connect(_server);
    } else {
      _disconnect();
    }
  }

  Future<void> _connect(ServerInfo server) async {
    setState(() => _status = VpnStatus.connecting);
    final messenger = ScaffoldMessenger.of(context);
    try {
      // 1. 从控制面拉取完整 sing-box config JSON
      final configJson = await _api.fetchConfig(
        nodeId: server.effectiveNodeId,
        deviceId: _kDeviceId,
      );
      // 2. 原样透传给 VpnBridge.start（禁止在 Dart 层修改 configJson）
      await _bridge.start(configJson);
      if (!mounted) return;
      setState(() {
        _status = VpnStatus.on;
        _elapsed = 0;
      });
      _timer = Timer.periodic(
        const Duration(seconds: 1),
        (_) => setState(() => _elapsed++),
      );
    } on ConnectApiException catch (e) {
      if (!mounted) return;
      setState(() => _status = VpnStatus.off);
      messenger.showSnackBar(SnackBar(
        content: Text(widget.zh ? e.messageZh : e.messageEn),
        backgroundColor: Theme.of(context).colorScheme.error,
        behavior: SnackBarBehavior.floating,
      ));
    } catch (e) {
      if (!mounted) return;
      setState(() => _status = VpnStatus.off);
      messenger.showSnackBar(SnackBar(
        content: Text(_t('连接失败，请稍后重试', 'Connection failed, please try again')),
        behavior: SnackBarBehavior.floating,
      ));
    }
  }

  Future<void> _disconnect() async {
    _timer?.cancel();
    setState(() => _status = VpnStatus.off);
    await _bridge.stop();
  }

  void _pick(ServerInfo s) {
    setState(() {
      _server = s;
      _tab = 0;
    });
    if (_status == VpnStatus.on) {
      _timer?.cancel();
      _connect(s);
    }
  }

  @override
  void dispose() {
    _timer?.cancel();
    _api.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final c = context.pangolin;
    return Scaffold(
      backgroundColor: c.bg,
      body: LayoutBuilder(builder: (context, constraints) {
        final isWide = constraints.maxWidth >= kWideBreakpoint;
        final page = DirectionalTabSwitcher(index: _tab, direction: _dir, child: _pages(isWide)[_tab]);
        if (isWide) {
          return SafeArea(child: _WideLayout(tab: _tab, onTab: _goTab, child: page));
        }
        return SafeArea(
          bottom: false,
          child: Column(children: [
            Expanded(
              child: HorizontalSwipeArea(
                onSwipeLeft: () => _swipe(1),
                onSwipeRight: () => _swipe(-1),
                child: page,
              ),
            ),
            _BottomTab(index: _tab, onTap: _goTab),
          ]),
        );
      }),
    final pages = [
      _ConnectPage(
        zh: widget.zh,
        status: _status,
        server: _server,
        elapsedSec: _elapsed,
        onToggle: _toggle,
        onOpenServers: () => setState(() => _tab = 1),
      ),
      _ServersPage(zh: widget.zh, current: _server.code, onPick: _pick),
      _StatsPage(zh: widget.zh),
      _AccountPage(zh: widget.zh),
    ];
    return Scaffold(
      backgroundColor: c.bg,
      body: SafeArea(bottom: false, child: pages[_tab]),
      bottomNavigationBar: _BottomTab(
        zh: widget.zh,
        index: _tab,
        onTap: (i) => setState(() => _tab = i),
      ),
    );
  }
}

/// ── 宽屏分栏:左侧栏导航 + 内容区 ──
class _WideLayout extends ConsumerWidget {
  const _WideLayout({required this.tab, required this.onTab, required this.child});
  final int tab;
  final ValueChanged<int> onTab;
  final Widget child;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final c = context.pangolin;
    final t = ref.watch(appTextProvider);
    final conn = ref.watch(connectionProvider);
    final node = ref.watch(effectiveNodeProvider);
    final titles = [t.tabConnect, t.tabServers, t.tabStats, t.tabMe];
    return Row(children: [
      _SideRail(tab: tab, onTab: onTab),
      Expanded(
        child: Column(children: [
          // 内容区顶栏:标题 + 在线状态
          SizedBox(
            height: 56,
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 28),
              child: Row(children: [
                Text(titles[tab], style: PangolinText.h3.copyWith(color: c.fg1, fontWeight: FontWeight.w700)),
                const Spacer(),
                Text(
                  conn.phase == VpnPhase.on ? '● ${node.code}' : '○',
                  style: PangolinText.mono.copyWith(
                      fontSize: 12.5,
                      fontWeight: FontWeight.w600,
                      color: conn.phase == VpnPhase.on ? c.success : c.fg3),
                ),
              ]),
            ),
          ),
          Expanded(child: child),
        ]),
      ),
    ]);
  }
}

class _SideRail extends ConsumerWidget {
  const _SideRail({required this.tab, required this.onTab});
  final int tab;
  final ValueChanged<int> onTab;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final c = context.pangolin;
    final t = ref.watch(appTextProvider);
    final isFree = ref.watch(isFreePlanProvider);
    final items = [
      (PangolinIcons.power, t.tabConnect),
      (PangolinIcons.globe, t.tabServers),
      (PangolinIcons.barChart, t.tabStats),
      (PangolinIcons.user, t.tabMe),
    ];
    return Container(
      width: 232,
      decoration: BoxDecoration(color: c.bgSubtle, border: Border(right: BorderSide(color: c.border))),
      padding: const EdgeInsets.fromLTRB(14, 18, 14, 16),
      child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
        // 品牌锁版
        Padding(
          padding: const EdgeInsets.fromLTRB(8, 0, 8, 20),
          child: Row(children: [
            const PangolinMark(size: 30),
            const SizedBox(width: 10),
            Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [
              Text(t.brand, style: PangolinText.h3.copyWith(color: c.fg1, fontWeight: FontWeight.w700, fontSize: 17, height: 1)),
              const SizedBox(height: 3),
              Text('PANGOLIN', style: PangolinText.overline.copyWith(color: c.accent, fontSize: 9, letterSpacing: 1.8)),
            ]),
          ]),
        ),
        for (var i = 0; i < items.length; i++)
          Padding(
            padding: const EdgeInsets.only(bottom: 4),
            child: _RailItem(icon: items[i].$1, label: items[i].$2, active: i == tab, onTap: () => onTab(i)),
          ),
        const Spacer(),
        // 套餐迷你卡
        Container(
          padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 12),
          decoration: BoxDecoration(
            color: isFree ? c.surface : null,
            gradient: isFree
                ? null
                : const LinearGradient(
                    begin: Alignment.topLeft, end: Alignment.bottomRight,
                    colors: [PangolinColors.clay600, PangolinColors.clay800]),
            border: isFree ? Border.all(color: c.border) : null,
            borderRadius: BorderRadius.circular(PangolinRadius.lg),
          ),
          child: Row(children: [
            Container(
              width: 32, height: 32,
              decoration: BoxDecoration(color: isFree ? c.bgSubtle : PangolinColors.white.withOpacity(0.18), shape: BoxShape.circle),
              child: Icon(isFree ? PangolinIcons.user : PangolinIcons.crown, size: 16, color: isFree ? c.fg2 : PangolinColors.white),
            ),
            const SizedBox(width: 9),
            Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [
              Text(isFree ? t.freePlanName : t.proMember,
                  overflow: TextOverflow.ellipsis,
                  style: PangolinText.caption.copyWith(color: isFree ? c.fg1 : PangolinColors.white, fontWeight: FontWeight.w700, fontSize: 12.5)),
              Text(kDemoEmail,
                  overflow: TextOverflow.ellipsis,
                  style: PangolinText.caption.copyWith(color: isFree ? c.fg3 : PangolinColors.white.withOpacity(0.7), fontSize: 10.5)),
            ])),
          ]),
        ),
      ]),
    );
  }
}

class _RailItem extends StatelessWidget {
  const _RailItem({required this.icon, required this.label, required this.active, required this.onTap});
  final IconData icon;
  final String label;
  final bool active;
  final VoidCallback onTap;
/// ── Bottom tab bar ──
class _BottomTab extends StatelessWidget {
  const _BottomTab({required this.zh, required this.index, required this.onTap});
  final bool zh;
  final int index;
  final ValueChanged<int> onTap;

  @override
  Widget build(BuildContext context) {
    final c = context.pangolin;
    return Material(
      color: active ? c.accentSubtle : Colors.transparent,
      borderRadius: BorderRadius.circular(PangolinRadius.md),
      clipBehavior: Clip.antiAlias,
      child: InkWell(
        onTap: onTap,
        child: ConstrainedBox(
          constraints: const BoxConstraints(minHeight: 48), // 触控尺寸 ≥48
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 13),
            child: Row(children: [
              Icon(icon, size: 20, color: active ? c.accent : c.fg3),
              const SizedBox(width: 12),
              Text(label, style: PangolinText.body.copyWith(color: active ? c.accent : c.fg2, fontWeight: active ? FontWeight.w700 : FontWeight.w500)),
            ]),
          ),
        ),
      ),
    );
  }
}

/// ── 底部 Tab 栏(窄屏)──
class _BottomTab extends ConsumerWidget {
  const _BottomTab({required this.index, required this.onTap});
  final int index;
  final ValueChanged<int> onTap;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final c = context.pangolin;
    final t = ref.watch(appTextProvider);
    final items = [
      (PangolinIcons.power, t.tabConnect),
      (PangolinIcons.globe, t.tabServers),
      (PangolinIcons.barChart, t.tabStats),
      (PangolinIcons.user, t.tabMe),
    ];
    return Container(
      decoration: BoxDecoration(
        color: c.surface,
        border: Border(top: BorderSide(color: c.border)),
      ),
      padding: const EdgeInsets.only(top: 8, bottom: 22),
      child: Row(
        children: [
          for (var i = 0; i < items.length; i++)
            Expanded(
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () => onTap(i),
                child: Column(mainAxisSize: MainAxisSize.min, children: [
                  Icon(items[i].$1, size: 22, color: i == index ? c.accent : c.fg3),
                  const SizedBox(height: 4),
                  Text(
                    items[i].$2,
                    style: PangolinText.caption.copyWith(
                      color: i == index ? c.accent : c.fg3,
                      fontWeight: i == index ? FontWeight.w700 : FontWeight.w500,
                    ),
                  ),
                ]),
              ),
            ),
        ],
      ),
    );
  }
}

/// ── Connect page ──
class _ConnectPage extends StatelessWidget {
  const _ConnectPage({
    required this.zh,
    required this.status,
    required this.server,
    required this.elapsedSec,
    required this.onToggle,
    required this.onOpenServers,
  });

  final bool zh;
  final VpnStatus status;
  final ServerInfo server;
  final int elapsedSec;
  final VoidCallback onToggle, onOpenServers;

  @override
  Widget build(BuildContext context) {
    final c = context.pangolin;
    final cap = switch (status) {
      VpnStatus.off => zh ? '未连接 · 轻点连接' : 'Tap to connect',
      VpnStatus.connecting => zh ? '连接中…' : 'Connecting…',
      VpnStatus.on => zh ? '已连接 · 网络已加密' : 'Connected · Encrypted',
      VpnStatus.error => zh ? '连接错误' : 'Connection error',
    };
    return Column(children: [
      _TopBar(
        zh: zh,
        trailing: Text(
          status == VpnStatus.on
              ? (zh ? '● 在线' : '● Online')
              : (zh ? '○ 离线' : '○ Offline'),
          style: PangolinText.mono.copyWith(
            fontSize: 12,
            color: status == VpnStatus.on ? c.success : c.fg3,
            fontWeight: FontWeight.w600,
          ),
        ),
      ),
      Expanded(
        child: Center(
          child: Column(mainAxisSize: MainAxisSize.min, children: [
            ConnectButton(
              status: status,
              elapsed: Duration(seconds: elapsedSec),
              onTap: onToggle,
            ),
            const SizedBox(height: 24),
            Text(
              cap,
              style: PangolinText.body.copyWith(color: c.fg2, fontWeight: FontWeight.w600),
            ),
          ]),
        ),
      ),
      Padding(
        padding: const EdgeInsets.fromLTRB(20, 0, 20, 18),
        child: GestureDetector(
          onTap: onOpenServers,
          child: Container(
            padding: const EdgeInsets.all(12),
            decoration: BoxDecoration(
              color: c.surface,
              borderRadius: BorderRadius.circular(PangolinRadius.lg),
              border: Border.all(color: c.border),
              boxShadow: PangolinShadow.sm,
            ),
            child: Row(children: [
              CountryCode(code: server.code, active: true),
              const SizedBox(width: 12),
              Expanded(
                child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                  Text(
                    server.name,
                    style: PangolinText.body.copyWith(color: c.fg1, fontWeight: FontWeight.w600),
                  ),
                  Text(
                    '${server.sub} · ${server.ping}ms',
                    style: PangolinText.caption.copyWith(color: c.fg3, fontWeight: FontWeight.w400),
                  ),
                ]),
              ),
              Icon(PangolinIcons.chevronRight, size: 20, color: c.fg3),
            ]),
          ),
        ),
      ),
    ]);
  }
}

/// ── Servers page ──
class _ServersPage extends StatelessWidget {
  const _ServersPage({required this.zh, required this.current, required this.onPick});

  final bool zh;
  final String current;
  final ValueChanged<ServerInfo> onPick;

  static const _servers = [
    ServerInfo(code: 'HK', name: '香港 · 流媒体', sub: 'Hong Kong', ping: 18, nodeId: 'hk-1'),
    ServerInfo(code: 'JP', name: '日本 东京', sub: 'Tokyo', ping: 32, nodeId: 'jp-1'),
    ServerInfo(code: 'TW', name: '台湾 台北', sub: 'Taipei', ping: 28, nodeId: 'tw-1'),
    ServerInfo(code: 'SG', name: '新加坡', sub: 'Singapore · P2P', ping: 54, nodeId: 'sg-1'),
    ServerInfo(code: 'KR', name: '韩国 首尔', sub: 'Seoul', ping: 41, nodeId: 'kr-1'),
    ServerInfo(code: 'US', name: '美国 洛杉矶', sub: 'Los Angeles', ping: 146, nodeId: 'us-1'),
  ];

  @override
  Widget build(BuildContext context) {
    final c = context.pangolin;
    return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
      _TopBar(zh: zh),
      Padding(
        padding: const EdgeInsets.fromLTRB(20, 0, 20, 12),
        child: Text(
          zh ? '选择节点' : 'Choose server',
          style: PangolinText.h2.copyWith(color: c.fg1),
        ),
      ),
      Expanded(
        child: ListView.builder(
          padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),
          itemCount: _servers.length,
          itemBuilder: (_, i) => Padding(
            padding: const EdgeInsets.only(bottom: 10),
            child: ServerTile(
              server: _servers[i],
              active: _servers[i].code == current,
              onTap: () => onPick(_servers[i]),
            ),
          ),
        ),
      ),
    ]);
  }
}

/// ── Stats page ──
class _StatsPage extends StatelessWidget {
  const _StatsPage({required this.zh});
  final bool zh;

  @override
  Widget build(BuildContext context) {
    final c = context.pangolin;
    final vals = [2.1, 3.4, 1.8, 4.6, 5.2, 6.1, 3.0];
    final labels = zh ? ['一', '二', '三', '四', '五', '六', '日'] : ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
    const maxV = 6.1;
    return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
      _TopBar(zh: zh),
      Padding(
        padding: const EdgeInsets.fromLTRB(20, 0, 20, 16),
        child: Text(zh ? '使用统计' : 'Statistics', style: PangolinText.h2.copyWith(color: c.fg1)),
      ),
      Padding(
        padding: const EdgeInsets.symmetric(horizontal: 20),
        child: Row(children: [
          for (final m in [(zh ? '本月流量' : 'Traffic', '42.6', 'GB'), (zh ? '平均延迟' : 'Ping', '29', 'ms'), (zh ? '本月时长' : 'Time', '86.4', 'h')])
            Expanded(child: Container(
              margin: const EdgeInsets.only(right: 12),
              padding: const EdgeInsets.all(14),
              decoration: BoxDecoration(color: c.surface, borderRadius: BorderRadius.circular(PangolinRadius.lg), border: Border.all(color: c.border), boxShadow: PangolinShadow.sm),
              child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                Text(m.$1, style: PangolinText.caption.copyWith(color: c.fg3, fontWeight: FontWeight.w600)),
                const SizedBox(height: 6),
                Text.rich(TextSpan(text: m.$2, style: PangolinText.mono.copyWith(fontSize: 20, color: c.fg1, fontWeight: FontWeight.w500),
                    children: [TextSpan(text: ' ${m.$3}', style: PangolinText.caption.copyWith(color: c.fg3))])),
          Expanded(
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () => onTap(i),
              child: Column(mainAxisSize: MainAxisSize.min, children: [
                Icon(items[i].$1, size: 22, color: i == index ? c.accent : c.fg3),
                const SizedBox(height: 4),
                Text(items[i].$2,
                    style: PangolinText.caption.copyWith(
                        color: i == index ? c.accent : c.fg3, fontWeight: i == index ? FontWeight.w700 : FontWeight.w500)),
              ]),
            ),
          ),
          for (final m in [
            (zh ? '本月流量' : 'Traffic', '42.6', 'GB'),
            (zh ? '平均延迟' : 'Ping', '29', 'ms'),
            (zh ? '本月时长' : 'Time', '86.4', 'h'),
          ])
            Expanded(
              child: Container(
                margin: const EdgeInsets.only(right: 12),
                padding: const EdgeInsets.all(14),
                decoration: BoxDecoration(
                  color: c.surface,
                  borderRadius: BorderRadius.circular(PangolinRadius.lg),
                  border: Border.all(color: c.border),
                  boxShadow: PangolinShadow.sm,
                ),
                child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                  Text(
                    m.$1,
                    style: PangolinText.caption.copyWith(color: c.fg3, fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 6),
                  Text.rich(TextSpan(
                    text: m.$2,
                    style: PangolinText.mono
                        .copyWith(fontSize: 20, color: c.fg1, fontWeight: FontWeight.w500),
                    children: [
                      TextSpan(
                        text: ' ${m.$3}',
                        style: PangolinText.caption.copyWith(color: c.fg3),
                      )
                    ],
                  )),
                ]),
              ),
            ),
        ]),
      ),
      const SizedBox(height: 16),
      Expanded(
        child: Padding(
          padding: const EdgeInsets.fromLTRB(20, 0, 20, 20),
          child: Container(
            width: double.infinity,
            padding: const EdgeInsets.all(18),
            decoration: BoxDecoration(
              color: c.surface,
              borderRadius: BorderRadius.circular(PangolinRadius.lg),
              border: Border.all(color: c.border),
              boxShadow: PangolinShadow.sm,
            ),
            child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
              Text(
                zh ? '本周流量 (GB)' : 'This week (GB)',
                style: PangolinText.sm.copyWith(color: c.fg1, fontWeight: FontWeight.w600),
              ),
              const SizedBox(height: 18),
              Expanded(
                child: Row(crossAxisAlignment: CrossAxisAlignment.end, children: [
                  for (var i = 0; i < vals.length; i++)
                    Expanded(
                      child: Column(mainAxisAlignment: MainAxisAlignment.end, children: [
                        Text(
                          '${vals[i]}',
                          style: PangolinText.mono.copyWith(fontSize: 12, color: c.fg3),
                        ),
                        const SizedBox(height: 6),
                        Container(
                          height: 90 * (vals[i] / maxV),
                          margin: const EdgeInsets.symmetric(horizontal: 6),
                          decoration: BoxDecoration(
                            color: c.accent.withOpacity(.85),
                            borderRadius: const BorderRadius.vertical(top: Radius.circular(6)),
                          ),
                        ),
                        const SizedBox(height: 6),
                        Text(labels[i], style: PangolinText.caption.copyWith(color: c.fg3)),
                      ]),
                    ),
                ]),
              ),
            ]),
          ),
        ),
      ),
    ]);
  }
}

/// ── Account page ──
class _AccountPage extends StatelessWidget {
  const _AccountPage({required this.zh});
  final bool zh;

  @override
  Widget build(BuildContext context) {
    final c = context.pangolin;
    return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
      _TopBar(zh: zh),
      Padding(
        padding: const EdgeInsets.fromLTRB(20, 0, 20, 14),
        child: Text(zh ? '我的' : 'Account', style: PangolinText.h2.copyWith(color: c.fg1)),
      ),
      Expanded(
        child: ListView(padding: const EdgeInsets.fromLTRB(20, 0, 20, 20), children: [
          Container(
            padding: const EdgeInsets.all(18),
            decoration: BoxDecoration(
              gradient: const LinearGradient(
                begin: Alignment.topLeft,
                end: Alignment.bottomRight,
                colors: [PangolinColors.clay600, PangolinColors.clay800],
              ),
              borderRadius: BorderRadius.circular(PangolinRadius.xl),
              boxShadow: PangolinShadow.md,
            ),
            child: Row(children: [
              Container(
                width: 44,
                height: 44,
                decoration: BoxDecoration(
                  color: PangolinColors.white.withOpacity(.18),
                  shape: BoxShape.circle,
                ),
                child: const Icon(PangolinIcons.crown, size: 22, color: PangolinColors.white),
              ),
              const SizedBox(width: 11),
              Expanded(
                child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
                  const Text(
                    'me@pangolin.vpn',
                    style: TextStyle(
                      color: PangolinColors.white,
                      fontWeight: FontWeight.w700,
                      fontSize: 16,
                    ),
                  ),
                  const SizedBox(height: 4),
                  Text(
                    zh ? 'PRO 会员 · 至 2026-12-31' : 'PRO · until 2026-12-31',
                    style: TextStyle(color: PangolinColors.white.withOpacity(.85), fontSize: 12),
                  ),
                ]),
              ),
              FilledButton(
                onPressed: () => Navigator.of(context).push(MaterialPageRoute(
                  builder: (_) => PlansScreen(
                    zh: zh,
                    onChoose: (_) => Navigator.of(context).push(
                      MaterialPageRoute(builder: (_) => RedeemScreen(zh: zh)),
                    ),
                  ),
                )),
                style: FilledButton.styleFrom(
                  backgroundColor: PangolinColors.white,
                  foregroundColor: PangolinColors.clay700,
                  shape: const StadiumBorder(),
                  padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
                ),
                child: Text(
                  zh ? '续费 / 升级' : 'Renew',
                  style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 13),
                ),
              ),
            ]),
          ),
          const SizedBox(height: 18),
          _accountRow(c, PangolinIcons.mail, zh ? '邮箱' : 'Email', 'me@pangolin.vpn'),
          _accountRow(c, PangolinIcons.lock, zh ? '密码' : 'Password', '••••••••••'),
          _accountRow(
            c,
            PangolinIcons.monitorSmartphone,
            zh ? '我的设备' : 'My devices',
            '',
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(builder: (_) => DevicesScreen(zh: zh)),
            ),
          ),
          _accountRow(
            c,
            PangolinIcons.shoppingBag,
            zh ? '兑换 & 购买' : 'Redeem & buy',
            '',
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(builder: (_) => RedeemScreen(zh: zh)),
            ),
          ),
          _accountRow(
            c,
            PangolinIcons.messageCircle,
            zh ? '联系我们' : 'Contact us',
            '',
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(builder: (_) => ContactScreen(zh: zh)),
            ),
          ),
          _accountRow(
            c,
            PangolinIcons.logOut,
            zh ? '退出登录' : 'Sign out',
            '',
            danger: true,
          ),
        ]),
      ),
    ]);
  }

  Widget _accountRow(
    PangolinScheme c,
    IconData icon,
    String title,
    String value, {
    bool danger = false,
    VoidCallback? onTap,
  }) {
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: onTap,
      child: Container(
        margin: const EdgeInsets.only(bottom: 10),
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
        decoration: BoxDecoration(
          color: c.surface,
          borderRadius: BorderRadius.circular(PangolinRadius.lg),
          border: Border.all(color: c.border),
          boxShadow: PangolinShadow.sm,
        ),
        child: Row(children: [
          Icon(icon, size: 20, color: danger ? c.danger : c.accent),
          const SizedBox(width: 13),
          Expanded(
            child: Text(
              title,
              style: PangolinText.body
                  .copyWith(color: danger ? c.danger : c.fg1, fontWeight: FontWeight.w500),
            ),
          ),
          if (value.isNotEmpty)
            Text(value, style: PangolinText.sm.copyWith(color: c.fg3))
          else
            Icon(PangolinIcons.chevronRight, size: 18, color: c.fg3),
        ]),
      ),
    );
  }
}

/// ── Shared top bar ──
class _TopBar extends StatelessWidget {
  const _TopBar({required this.zh, this.trailing});
  final bool zh;
  final Widget? trailing;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(20, 6, 20, 14),
      child: Row(children: [
        PangolinBrandLockup(zh: zh, markSize: 24),
        const Spacer(),
        if (trailing != null) trailing!,
      ]),
    );
  }
}
