import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:dio/dio.dart';

import '../../model/user_model.dart';
import '../../providers/user_provider.dart';
import '../../service/sega_service.dart';
import '../../tool/cacheImage.dart';
import '../../widgets/glowBlobConfig.dart';
import 'login_page.dart';

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

  @override
  State<UserPage> createState() => _UserPageState();
}

class _UserPageState extends State<UserPage> {
  final _nameController = TextEditingController();
  final _emailController = TextEditingController();
  final _sexController = TextEditingController();
  final _bioController = TextEditingController();
  final _dfUserController = TextEditingController();
  final _dfPwdController = TextEditingController();
  final _lxKeyController = TextEditingController();
  static const _pinkColor = Color(0xFFFFC0D6);

  bool _isDisagreeRecommend = false;
  bool _isDisagreeFriend = false;
  Map<String, dynamic>? _radarData;

  Future<void> _loadRadarData() async {
    final provider = Provider.of<UserProvider>(context, listen: false);
    try {
      await provider.waitInit(); // 你需要在 UserProvider 里加这个方法（我下面会给你代码）
      final data = await provider.fetchRadarData(provider.user?.id ?? 'default_id');
      setState(() {
        _radarData = data;
      });
      if(mounted){
        // ScaffoldMessenger.of(context).showSnackBar(
        //   const SnackBar(content: Text("雷达图数据加载成功 ✅")),
        // );
      }
    } catch (e) {
      if(mounted){
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text("加载失败：$e")),
        );
      }
    }
  }

  @override
  void initState() {
    super.initState();
    _loadRadarData();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final provider = Provider.of<UserProvider>(context, listen: false);
      provider.fetchSexTags();
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    final user = Provider.of<UserProvider>(context).user;
    _nameController.text = user?.name ?? '';
    _emailController.text = user?.email ?? '';
    _sexController.text = user?.sex ?? '';
    _bioController.text = user?.bio ?? '';
    _dfUserController.text = user?.dfUsername ?? '';
    _dfPwdController.text = user?.dfPassword ?? '';
    _lxKeyController.text = user?.lxKey ?? '';

    _isDisagreeRecommend = user?.isDisagreeRecommend ?? false;
    _isDisagreeFriend = user?.isDisagreeFriend ?? false;
  }

  @override
  void dispose() {
    _nameController.dispose();
    _emailController.dispose();
    _sexController.dispose();
    _bioController.dispose();
    _dfUserController.dispose();
    _dfPwdController.dispose();
    _lxKeyController.dispose();
    super.dispose();
  }

  Future<void> _launchURL(String urlString) async {
    final Uri url = Uri.parse(urlString);
    if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('无法打开链接: $urlString')),
        );
      }
    }
  }

  Future<void> _verifyShuiyu() async {
    final username = _dfUserController.text.trim();
    final password = _dfPwdController.text.trim();

    if (username.isEmpty || password.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("请输入水鱼用户名和密码")),
      );
      return;
    }

    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text("正在验证水鱼账号..."),
          duration: Duration(seconds: 1),
        ),
      );
    }

    try {
      final dio = Dio();
      final response = await dio.post(
        'https://maimai.diving-fish.com/api/maimaidxprober/login',
        data: {
          "username": username,
          "password": password,
        },
        options: Options(
          sendTimeout: const Duration(seconds: 10),
          receiveTimeout: const Duration(seconds: 10),
        ),
      );

      final Map<String, dynamic> result = response.data;

      if (mounted) {
        if (result['message'] == "登录成功") {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text("水鱼账号验证成功！"),
              backgroundColor: Colors.green,
              duration: Duration(seconds: 1),
            ),
          );
        } else {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(result['message'] ?? "验证失败"),
              duration: Duration(seconds: 1),
              backgroundColor: Colors.red,
            ),
          );
        }
      }
    } on DioException catch (e) {
      if (mounted) {
        String errorMsg = "网络请求失败";
        if (e.type == DioExceptionType.connectionTimeout) {
          errorMsg = "连接超时，请检查网络";
        } else if (e.type == DioExceptionType.receiveTimeout) {
          errorMsg = "服务器响应超时";
        } else if (e.type == DioExceptionType.connectionError) {
          errorMsg = "网络连接异常，请检查网络";
        }

        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(errorMsg),
            backgroundColor: Colors.red,
          ),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text("未知错误，请重试"),
            backgroundColor: Colors.red,
            duration: Duration(seconds: 1),
          ),
        );
      }
    }
  }

  Future<void> _verifyLuoxue() async {
    final key = _lxKeyController.text.trim();

    if (key.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("请输入落雪 lxKey")),
      );
      return;
    }

    try {
      final dio = Dio();
      final response = await dio.get(
        'https://maimai.lxns.net/api/v0/user/maimai/player',
        options: Options(
          headers: {
            'X-User-Token': key,
          },
        ),
      );

      final result = LuoxueResponse.fromJson(response.data);

      if (result.success && mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text("✅ 验证成功！玩家：${result.data.name}\nDX Rating：${result.data.rating}"),
          ),
        );
      }
    } on DioException catch (e) {
      String msg = "验证失败";
      if (e.response?.statusCode == 401) {
        msg = "❌ lxKey 无效或已过期";
      } else if (e.type == DioExceptionType.connectionError) {
        msg = "📶 网络连接失败";
      }

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text(msg)),
        );
      }
    }
  }

  void _showSexSelectDialog() {
    final provider = Provider.of<UserProvider>(context, listen: false);
    final tags = provider.sexTags;

    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      shape: const RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
      ),
      builder: (context) {
        return Container(
          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Text(
                "选择性别标签",
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
              ),
              const SizedBox(height: 16),
              if (tags.isEmpty)
                const Padding(
                  padding: EdgeInsets.all(20),
                  child: Text("暂无性别标签"),
                ),
              Wrap(
                spacing: 8,
                runSpacing: 8,
                children: tags.map((tag) {
                  return ActionChip(
                    label: Text(tag),
                    onPressed: () {
                      _sexController.text = tag;
                      Navigator.pop(context);
                    },
                  );
                }).toList(),
              ),
              const SizedBox(height: 30),
            ],
          ),
        );
      },
    );
  }

  void _showSyncProgressDialog(BuildContext context, ValueNotifier<String> status) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (ctx) => AlertDialog(
        content: ValueListenableBuilder<String>(
          valueListenable: status,
          builder: (_, text, __) {
            return Row(
              children: [
                const CircularProgressIndicator(),
                const SizedBox(width: 20),
                Expanded(child: Text(text)),
              ],
            );
          },
        ),
      ),
    );
  }

  Future<void> _verifyBoundSega(SegaCard card) async {
    final segaId = card.segaId;
    final pwd = card.password;
    final type = card.type;

    if (segaId == null || pwd == null || type == null) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("账号信息不完整")));
      return;
    }

    try {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("正在验证 SegaID…")));

      final region = type == "jp" ? Region.jp : Region.intl;
      final data = await SegaService.verifyOnlyLogin(
        region: region,
        segaId: segaId,
        password: pwd,
      );

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text("✅ 验证成功：${data['user']['name']}"), backgroundColor: Colors.green),
        );
      }
    } on NetImportError catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text("❌ ${e.message}"), backgroundColor: Colors.red),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("验证失败")));
      }
    }
  }

  Future<void> _refreshBoundSegaScore(SegaCard card) async {
    final segaId = card.segaId;
    final pwd = card.password;
    final type = card.type;

    if (segaId == null || pwd == null || type == null) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("账号信息不完整")));
      return;
    }

    final statusNotifier = ValueNotifier<String>("准备同步成绩...");
    if (mounted) _showSyncProgressDialog(context, statusNotifier);

    try {
      final region = type == "jp" ? Region.jp : Region.intl;
      final data = await SegaService.fetchAndSync(
        region: region,
        segaId: segaId,
        password: pwd,
        onProgress: (status, percent) {
          statusNotifier.value = status;
        },
      );

      // 同步到后端
      final provider = Provider.of<UserProvider>(context, listen: false);
      await provider.syncSegaScore(data);

      // 关闭弹窗
      if (mounted) Navigator.pop(context);

      // ✅【正确提示：上传成功】
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text("✅ 成绩同步成功（已上传至服务器）"),
            backgroundColor: Colors.green,
          ),
        );
      }

    } on NetImportError catch (e) {
      if (mounted) Navigator.pop(context);
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text("❌ ${e.message}"), backgroundColor: Colors.red),
        );
      }
    } catch (e) {
      if (mounted) Navigator.pop(context);
      if (mounted) {
        // ❌【上传失败提示】
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text("❌ 成绩同步失败（服务器上传失败）"),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  void _showAddSegaSheet() {
    final idController = TextEditingController();
    final pwdController = TextEditingController();
    Region selectedRegion = Region.intl;

    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(16))),
      builder: (ctx) => Padding(
        padding: EdgeInsets.fromLTRB(20, 20, 20, MediaQuery.of(ctx).viewInsets.bottom + 20),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text("添加 Sega 账号", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
            const SizedBox(height: 16),
            TextField(
              controller: idController,
              decoration: const InputDecoration(labelText: "SegaID", isDense: true, border: OutlineInputBorder()),
            ),
            const SizedBox(height: 12),
            TextField(
              controller: pwdController,
              obscureText: true,
              decoration: const InputDecoration(labelText: "密码", isDense: true, border: OutlineInputBorder()),
            ),
            const SizedBox(height: 12),
            DropdownButtonFormField<Region>(
              value: selectedRegion,
              decoration: const InputDecoration(border: OutlineInputBorder(), isDense: true),
              items: const [
                DropdownMenuItem(value: Region.intl, child: Text("国际服")),
                DropdownMenuItem(value: Region.jp, child: Text("日服")),
              ],
              onChanged: (v) {
                if (v != null) selectedRegion = v;
              },
            ),
            const SizedBox(height: 20),
            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                onPressed: () async {
                  final id = idController.text.trim();
                  final pwd = pwdController.text.trim();
                  if (id.isEmpty || pwd.isEmpty) {
                    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("请输入完整信息")));
                    return;
                  }

                  final newCard = SegaCard(
                    segaId: id,
                    password: pwd,
                    type: selectedRegion.name,
                  );

                  final provider = Provider.of<UserProvider>(context, listen: false);
                  final user = provider.user;
                  if (user != null) {
                    final list = user.segaCards ?? [];
                    final newList = List<SegaCard>.from(list)..add(newCard);

                    final updatedUser = UserModel(
                      id: user.id,
                      name: user.name,
                      userId: user.userId,
                      teamId: user.teamId,
                      email: user.email,
                      password: user.password,
                      twoFactorKey: user.twoFactorKey,
                      apiKey: user.apiKey,
                      apiBindKey: user.apiBindKey,
                      protectRole: user.protectRole,
                      risks: user.risks,
                      mcName: user.mcName,
                      userName2userId: user.userName2userId,
                      lxKey: user.lxKey,
                      dfUsername: user.dfUsername,
                      dfPassword: user.dfPassword,
                      nuoId: user.nuoId,
                      botId: user.botId,
                      spasolBotId: user.spasolBotId,
                      githubId: user.githubId,
                      rating: user.rating,
                      ratingMax: user.ratingMax,
                      iconId: user.iconId,
                      plateId: user.plateId,
                      plateIds: user.plateIds,
                      frameId: user.frameId,
                      charaSlots: user.charaSlots,
                      qiandaoDay: user.qiandaoDay,
                      inviter: user.inviter,
                      successLogoutTime: user.successLogoutTime,
                      lastLoginTime: user.lastLoginTime,
                      friendIds: user.friendIds,
                      bio: user.bio,
                      friendBio: user.friendBio,
                      sex: user.sex,
                      isDisagreeRecommend: user.isDisagreeRecommend,
                      isDisagreeFriend: user.isDisagreeFriend,
                      points: user.points,
                      planPoints: user.planPoints,
                      cardIds: user.cardIds,
                      userCards: user.userCards,
                      tags: user.tags,
                      useBeta: user.useBeta,
                      useNuo: user.useNuo,
                      useServer: user.useServer,
                      useB50Type: user.useB50Type,
                      userHot: user.userHot,
                      chatInGroupNumbers: user.chatInGroupNumbers,
                      sc: user.sc,
                      id2pcNuo: user.id2pcNuo,
                      mai2links: user.mai2links,
                      key2KeychipEn: user.key2KeychipEn,
                      key2key2KeychipEn: user.key2key2KeychipEn,
                      mai2link: user.mai2link,
                      userRegion: user.userRegion,
                      rinUsernameOrEmail: user.rinUsernameOrEmail,
                      rinPassword: user.rinPassword,
                      rinChusanUser: user.rinChusanUser,
                      segaCards: newList,
                      placeList: user.placeList,
                      lastKeyChip: user.lastKeyChip,
                      token: user.token,
                      timesRegionData: user.timesRegionData,
                      yearTotal: user.yearTotal,
                      yearTotalComment: user.yearTotalComment,
                      userCollCardMap: user.userCollCardMap,
                      collName2musicIds: user.collName2musicIds,
                      ai: user.ai,
                      pkScore: user.pkScore,
                      pkScoreStr: user.pkScoreStr,
                      pkScoreReality: user.pkScoreReality,
                      pkUserId: user.pkUserId,
                      limitPkTimestamp: user.limitPkTimestamp,
                      hasAcceptPk: user.hasAcceptPk,
                      pkPlayNum: user.pkPlayNum,
                      pkWin: user.pkWin,
                      userData: user.userData,
                      banState: user.banState,
                    );

                    provider.updateUser(updatedUser);
                    await provider.saveUserInfo();
                  }

                  if (mounted) {
                    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("✅ 添加成功")));
                    Navigator.pop(ctx);
                  }
                },
                child: const Text("保存"),
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final userProvider = Provider.of<UserProvider>(context);
    final UserModel? user = userProvider.user;

    if (user == null) {
      return Scaffold(
        appBar: AppBar(title: const Text("用户中心")),
        body: Center(
            child: Transform.translate(
              offset: const Offset(0, -40),
              child: _buildLoginCard(
                onTap: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (_) => const LoginPage()),
                  );
                },
              ),
            )
        ),
        floatingActionButton: _buildFloatingBackButton(),
      );
    }

    return Scaffold(
        floatingActionButton: _buildFloatingBackButton(),
        body: Stack(
        children: [
// 在 Stack 的底层调用
          LiquidGlowBackground(
            blurSigma: 60, // 模糊程度
            duration: const Duration(seconds: 10), // 动画周期
            blobs: [
              GlowBlobConfig(
                color: Colors.deepPurpleAccent.withOpacity(0.5),
                size: 250,
                begin: const Alignment(-0.8, -0.4), // 从左下
                end: const Alignment(-0.2, 0.2),   // 移动到中央偏左
              ),
              GlowBlobConfig(
                color: Colors.pinkAccent.withOpacity(0.4),
                size: 100,
                begin: const Alignment(-0.8, 0.9),
                end: const Alignment(0.3, 0.5),
              ),
              GlowBlobConfig(
                color: Colors.white.withOpacity(0.3),
                size: 200,
                begin: const Alignment(2.0, -0.4),  // 从正下方溢出处
                end: const Alignment(0.0, -0.5),    // 向上浮动
              ),
            ],
          ),
          // 2. 主内容层
          SafeArea(
            bottom:false ,
            child:SingleChildScrollView(
              padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 20),
              child: Center(
                child: Container(
                  constraints: const BoxConstraints(maxWidth: 900),
                  child: Column(
                    children: [
                      _buildProfileHeader(context, userProvider, user),
                      const SizedBox(height: 24),

                      if (user.userCards != null && user.userCards!.isNotEmpty)
                        _buildUserCardSlider(userProvider, user),
                      const SizedBox(height: 24),

                      _buildSectionCard([
                        _buildItem("用户ID", user.id.toString()),
                        _buildEditableItem("用户名", _nameController),
                        _buildEditableItem("邮箱", _emailController),
                        _buildEditableSexItem(),
                        _buildEditableItem("个性签名", _bioController),
                        _buildItem("积分", user.points.toString()),
                        _buildItem("B50方案", user.useB50Type.toString()),
                        _buildCopyableItem(context, "API Key", user.apiKey),
                        _buildCopyableItem(context, "绑定 API Key", user.apiBindKey),
                        _buildItem("UserID", "****${user.userId.toString().substring(4)}"),
                        _buildItem("上次登录", _formatLastLoginTime(user.lastLoginTime)),
                      ]),
                      const SizedBox(height: 20),

                      _buildScoreCheckerCard(user),
                      const SizedBox(height: 20),

                      _buildSectionCard([
                        _buildSwitchItem("禁止被推荐", _isDisagreeRecommend, (v) {
                          setState(() => _isDisagreeRecommend = v);
                        }),
                        _buildSwitchItem("禁止加好友", _isDisagreeFriend, (v) {
                          setState(() => _isDisagreeFriend = v);
                        }),
                      ]),
                      const SizedBox(height: 20),

                      _buildSegaCard(user),
                      const SizedBox(height: 20),
                      _buildRadarChartSection(),
                      const SizedBox(height: 20),

                      _buildSaveButton(userProvider),
                      const SizedBox(height: 12),
                      _buildLogoutButton(context, userProvider),
                      const SizedBox(height: 100),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  // 移除 Sega 账号
  Future<void> _removeSegaCard(SegaCard card, UserModel user) async {
    final confirm = await showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text("确认移除"),
        content: Text("确定要删除 ${card.segaId} 吗？"),
        actions: [
          TextButton(onPressed: () => Navigator.pop(ctx), child: const Text("取消")),
          TextButton(
            onPressed: () => Navigator.pop(ctx, true),
            style: TextButton.styleFrom(foregroundColor: Colors.red),
            child: const Text("删除"),
          ),
        ],
      ),
    );

    if (confirm != true) return;

    final provider = Provider.of<UserProvider>(context, listen: false);

    // 直接删除，不使用 copyWith
    List<SegaCard> newList = List.from(user.segaCards ?? [])..remove(card);

    // 完全沿用你原来的 UserModel 构造方式
    UserModel updatedUser = UserModel(
      id: user.id,
      name: user.name,
      userId: user.userId,
      teamId: user.teamId,
      email: user.email,
      password: user.password,
      twoFactorKey: user.twoFactorKey,
      apiKey: user.apiKey,
      apiBindKey: user.apiBindKey,
      protectRole: user.protectRole,
      risks: user.risks,
      mcName: user.mcName,
      userName2userId: user.userName2userId,
      lxKey: user.lxKey,
      dfUsername: user.dfUsername,
      dfPassword: user.dfPassword,
      nuoId: user.nuoId,
      botId: user.botId,
      spasolBotId: user.spasolBotId,
      githubId: user.githubId,
      rating: user.rating,
      ratingMax: user.ratingMax,
      iconId: user.iconId,
      plateId: user.plateId,
      plateIds: user.plateIds,
      frameId: user.frameId,
      charaSlots: user.charaSlots,
      qiandaoDay: user.qiandaoDay,
      inviter: user.inviter,
      successLogoutTime: user.successLogoutTime,
      lastLoginTime: user.lastLoginTime,
      friendIds: user.friendIds,
      bio: user.bio,
      friendBio: user.friendBio,
      sex: user.sex,
      isDisagreeRecommend: user.isDisagreeRecommend,
      isDisagreeFriend: user.isDisagreeFriend,
      points: user.points,
      planPoints: user.planPoints,
      cardIds: user.cardIds,
      userCards: user.userCards,
      tags: user.tags,
      useBeta: user.useBeta,
      useNuo: user.useNuo,
      useServer: user.useServer,
      useB50Type: user.useB50Type,
      userHot: user.userHot,
      chatInGroupNumbers: user.chatInGroupNumbers,
      sc: user.sc,
      id2pcNuo: user.id2pcNuo,
      mai2links: user.mai2links,
      key2KeychipEn: user.key2KeychipEn,
      key2key2KeychipEn: user.key2key2KeychipEn,
      mai2link: user.mai2link,
      userRegion: user.userRegion,
      rinUsernameOrEmail: user.rinUsernameOrEmail,
      rinPassword: user.rinPassword,
      rinChusanUser: user.rinChusanUser,
      segaCards: newList, // 这里更新
      placeList: user.placeList,
      lastKeyChip: user.lastKeyChip,
      token: user.token,
      timesRegionData: user.timesRegionData,
      yearTotal: user.yearTotal,
      yearTotalComment: user.yearTotalComment,
      userCollCardMap: user.userCollCardMap,
      collName2musicIds: user.collName2musicIds,
      ai: user.ai,
      pkScore: user.pkScore,
      pkScoreStr: user.pkScoreStr,
      pkScoreReality: user.pkScoreReality,
      pkUserId: user.pkUserId,
      limitPkTimestamp: user.limitPkTimestamp,
      hasAcceptPk: user.hasAcceptPk,
      pkPlayNum: user.pkPlayNum,
      pkWin: user.pkWin,
      userData: user.userData,
      banState: user.banState,
    );

    provider.updateUser(updatedUser);
    await provider.saveUserInfo();

    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("✅ 已移除：${card.segaId}")),
      );
    }
  }

  Widget _buildScoreCheckerCard(UserModel user) {
    return _webCard(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text(
            "第三方查分器绑定",
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
          const SizedBox(height: 16),

          const Text("水鱼查分器", style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500)),
          const SizedBox(height: 8),
          TextField(
            controller: _dfUserController,
            decoration: const InputDecoration(
              labelText: "用户名",
              isDense: true,
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 8),
          TextField(
            controller: _dfPwdController,
            obscureText: true,
            decoration: const InputDecoration(
              labelText: "密码",
              isDense: true,
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 8),
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              TextButton.icon(
                icon: const Icon(Icons.check_circle_outline, size: 18),
                label: const Text("验证水鱼账号"),
                onPressed: _verifyShuiyu,
              ),
              const SizedBox(width: 8),
              TextButton.icon(
                icon: const Icon(Icons.open_in_new, size: 18),
                label: const Text("跳转水鱼官网"),
                onPressed: () => _launchURL("https://www.diving-fish.com/"),
              ),
            ],
          ),

          const SizedBox(height: 16),

          const Text("落雪查分器", style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500)),
          const SizedBox(height: 8),
          TextField(
            controller: _lxKeyController,
            decoration: const InputDecoration(
              labelText: "lxKey",
              isDense: true,
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 8),
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              TextButton.icon(
                icon: const Icon(Icons.check_circle_outline, size: 18),
                label: const Text("验证落雪账号"),
                onPressed: _verifyLuoxue,
              ),
              const SizedBox(width: 8),
              TextButton.icon(
                icon: const Icon(Icons.open_in_new, size: 18),
                label: const Text("跳转落雪官网"),
                onPressed: () => _launchURL("https://maimai.lxns.net/"),
              ),
            ],
          ),

          const SizedBox(height: 16),
          const Text("Mai2Links 账号", style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500)),
          const SizedBox(height: 8),
          if (user.mai2links != null && user.mai2links!.isNotEmpty)
            ...user.mai2links!.keys.map((name) {
              final isUser = name.toLowerCase().contains("user");
              return Padding(
                padding: const EdgeInsets.only(bottom: 6),
                child: Row(
                  children: [
                    Container(
                      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
                      decoration: BoxDecoration(
                        color: isUser ? Colors.purpleAccent : Colors.green,
                        borderRadius: BorderRadius.circular(4),
                      ),
                      child: Text(
                        isUser ? "用户账号" : "机台账号",
                        style: const TextStyle(color: Colors.white, fontSize: 12),
                      ),
                    ),
                    const SizedBox(width: 10),
                    Text("mai2Link用户 · $name"),
                  ],
                ),
              );
            })
          else
            const Text("无mai2links绑定"),
          const SizedBox(height: 20),

          const Text("国服多账号", style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500)),
          const SizedBox(height: 6),
          if(user.userName2userId!=null && user.userName2userId!.isNotEmpty)
            ...user.userName2userId!.keys.map((name) {
              return Padding(
                padding: const EdgeInsets.only(bottom: 6),
                child: Row(
                  children: [
                    Container(
                      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
                      decoration: BoxDecoration(
                        color: Colors.pinkAccent,
                        borderRadius: BorderRadius.circular(4),
                      ),
                      child: const Text(
                        "舞萌账号",
                        style: TextStyle(color: Colors.white, fontSize: 12),
                      ),
                    ),
                    const SizedBox(width: 10),
                    Text("国服用户 - $name"),
                    const Spacer(),
                    // 移除按钮（仿照sega移除）
                    _buildSmallButton("移除", Colors.red, () => _removeGuoFuAccount(name, user)),
                  ],
                ),
              );
            }).toList(),
        ],
      ),
    );
  }

  String _formatLastLoginTime(int? timestamp) {
    if (timestamp == null || timestamp == 0) return "未登录";
    final date = DateTime.fromMillisecondsSinceEpoch(timestamp)
        .toUtc()
        .add(const Duration(hours: 8));
    return date.toString().substring(0, 19);
  }

  Widget _buildEditableSexItem() {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 7),
      child: Row(
        children: [
          const SizedBox(width: 120, child: Text("性别")),
          Expanded(
            child: TextField(
              controller: _sexController,
              decoration: InputDecoration(
                isDense: true,
                border: const UnderlineInputBorder(),
                suffixIcon: IconButton(
                  icon: const Icon(Icons.arrow_drop_down, size: 20),
                  onPressed: _showSexSelectDialog,
                ),
              ),
              enabled: true,
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildEditableItem(String label, TextEditingController controller) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 7),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SizedBox(width: 120, child: Text(label)),
          Expanded(
            child: TextField(
              controller: controller,
              decoration: const InputDecoration(
                isDense: true,
                border: UnderlineInputBorder(),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Future<void> _refreshUserInfo() async {
    final provider = Provider.of<UserProvider>(context, listen: false);
    await provider.initUser();
    final user = provider.user;
    if (user != null) {
      _nameController.text = user.name ?? '';
      _emailController.text = user.email ?? '';
      _sexController.text = user.sex ?? '';
      _bioController.text = user.bio ?? '';
      _dfUserController.text = user.dfUsername ?? '';
      _dfPwdController.text = user.dfPassword ?? '';
      _lxKeyController.text = user.lxKey ?? '';

      setState(() {
        _isDisagreeRecommend = user.isDisagreeRecommend ?? false;
        _isDisagreeFriend = user.isDisagreeFriend ?? false;
      });
    }
    await provider.fetchSexTags();
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("用户信息已刷新 ✅")),
      );
    }
  }

  Widget _buildProfileHeader(
      BuildContext context, UserProvider provider, UserModel user) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    return _webCard(
      child: Row(
        children: [
          ClipRRect(
            borderRadius: BorderRadius.circular(8),
            child: CacheImage.network(
              provider.avatarUrl,
              width: 80,
              height: 80,
              fit: BoxFit.cover,
            ),
          ),
          const SizedBox(width: 20),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  user.name ?? "Unknown",
                  style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
                ),
                const SizedBox(height: 6),
                Text(
                  "Rating: ${user.rating ?? 0}",
                  style: TextStyle(
                      fontSize: 15,
                      color: isDark ? Colors.grey[400] : Colors.grey[600]),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildFloatingBackButton() {
    return Padding(
      padding: const EdgeInsets.only(bottom: 100),
      child: FloatingActionButton(
        elevation: 6,
        backgroundColor: Colors.black87,
        onPressed: () async {
          await _refreshUserInfo();
          if (mounted) {
            Navigator.maybePop(context);
          }
        },
        child: const Icon(Icons.refresh, color: Colors.white),
      ),
    );
  }

  Widget _buildUserCardSlider(UserProvider provider, UserModel user) {
    return _webCard(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text("用户卡牌",
              style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
          const SizedBox(height: 12),
          SizedBox(
            height: 340,
            child: PageView.builder(
              itemCount: user.userCards!.length,
              itemBuilder: (context, index) {
                final card = user.userCards![index];
                return _buildSingleCard(card);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSingleCard(dynamic card) {
    final charaId = card.charaId?.toString().padLeft(6, '0') ?? "000000";
    final iconId = card.iconId?.toString().padLeft(6, '0') ?? "000000";

    return Container(
      margin: const EdgeInsets.symmetric(horizontal: 4),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(9),
        image: DecorationImage(
          image: NetworkImage(
            "https://cdn.godserver.cn/resource/static/coll/Chara/UI_Chara_$charaId.png",
          ),
          fit:BoxFit.cover,
          colorFilter: ColorFilter.mode(
              Colors.black.withOpacity(0.4), BlendMode.darken),
        ),
      ),
      child: Padding(
        padding: const EdgeInsets.all(14),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            ClipRRect(
              borderRadius: BorderRadius.circular(6),
              child: CacheImage.network(
                "https://cdn.godserver.cn/resource/static/coll/Icon/UI_Icon_$iconId.png",
                width: 50,
                height: 50,
              ),
            ),
            const SizedBox(height: 8),
            Text(
              card.username ?? "",
              style: const TextStyle(
                  color: Colors.white,
                  fontSize: 16,
                  fontWeight: FontWeight.w600),
            ),
            Text("Rating: ${card.rating ?? 0}",
                style: const TextStyle(color: Colors.white70)),
          ],
        ),
      ),
    );
  }

  Widget _buildSaveButton(UserProvider provider) {
    return SizedBox(
      width: double.infinity,
      height: 50,
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          backgroundColor: Colors.greenAccent.shade400,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        ),
        onPressed: () async {
          final user = provider.user;
          if (user == null) return;

          final newUser = UserModel(
            id: user.id,
            name: _nameController.text.trim(),
            userId: user.userId,
            teamId: user.teamId,
            email: _emailController.text.trim(),
            password: user.password,
            twoFactorKey: user.twoFactorKey,
            apiKey: user.apiKey,
            apiBindKey: user.apiBindKey,
            protectRole: user.protectRole,
            risks: user.risks,
            mcName: user.mcName,
            userName2userId: user.userName2userId,

            lxKey: _lxKeyController.text.trim(),
            dfUsername: _dfUserController.text.trim(),
            dfPassword: _dfPwdController.text.trim(),

            nuoId: user.nuoId,
            botId: user.botId,
            spasolBotId: user.spasolBotId,
            githubId: user.githubId,
            rating: user.rating,
            ratingMax: user.ratingMax,
            iconId: user.iconId,
            plateId: user.plateId,
            plateIds: user.plateIds,
            frameId: user.frameId,
            charaSlots: user.charaSlots,
            qiandaoDay: user.qiandaoDay,
            inviter: user.inviter,
            successLogoutTime: user.successLogoutTime,
            lastLoginTime: user.lastLoginTime,
            friendIds: user.friendIds,
            bio: _bioController.text.trim(),
            friendBio: user.friendBio,
            sex: _sexController.text.trim(),

            isDisagreeRecommend: _isDisagreeRecommend,
            isDisagreeFriend: _isDisagreeFriend,

            points: user.points,
            planPoints: user.planPoints,
            cardIds: user.cardIds,
            userCards: user.userCards,
            tags: user.tags,
            useBeta: user.useBeta,
            useNuo: user.useNuo,
            useServer: user.useServer,
            useB50Type: user.useB50Type,
            userHot: user.userHot,
            chatInGroupNumbers: user.chatInGroupNumbers,
            sc: user.sc,
            id2pcNuo: user.id2pcNuo,
            mai2links: user.mai2links,
            key2KeychipEn: user.key2KeychipEn,
            key2key2KeychipEn: user.key2key2KeychipEn,
            mai2link: user.mai2link,
            userRegion: user.userRegion,
            rinUsernameOrEmail: user.rinUsernameOrEmail,
            rinPassword: user.rinPassword,
            rinChusanUser: user.rinChusanUser,
            segaCards: user.segaCards,
            placeList: user.placeList,
            lastKeyChip: user.lastKeyChip,
            token: user.token,
            timesRegionData: user.timesRegionData,
            yearTotal: user.yearTotal,
            yearTotalComment: user.yearTotalComment,
            userCollCardMap: user.userCollCardMap,
            collName2musicIds: user.collName2musicIds,
            ai: user.ai,
            pkScore: user.pkScore,
            pkScoreStr: user.pkScoreStr,
            pkScoreReality: user.pkScoreReality,
            pkUserId: user.pkUserId,
            limitPkTimestamp: user.limitPkTimestamp,
            hasAcceptPk: user.hasAcceptPk,
            pkPlayNum: user.pkPlayNum,
            pkWin: user.pkWin,
            userData: user.userData,
            banState: user.banState,
          );

          provider.updateUser(newUser);

          try {
            await provider.saveUserInfo();
            if (mounted) {
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text("保存成功 ✅")),
              );
            }
          } catch (e) {
            if (mounted) {
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(content: Text("保存失败：${e.toString()}")),
              );
            }
          }
        },
        child: const Text(
          "保存修改",
          style: TextStyle(color: Colors.black87, fontSize: 16),
        ),
      ),
    );
  }

  Widget _buildSegaCard(UserModel user) {
    return _webCard(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text(
            "SegaID 账号",
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
          const SizedBox(height: 10),

          if (user.segaCards != null && user.segaCards!.isNotEmpty)
            ...user.segaCards!.map((SegaCard card) {
              return Padding(
                padding: const EdgeInsets.only(bottom: 12),
                child: Row(
                  children: [
                    // 服务器标签
                    Container(
                      padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3),
                      decoration: BoxDecoration(
                        color: (card.type ?? "intl") == "jp" ? Colors.purple : Colors.blue,
                        borderRadius: BorderRadius.circular(4),
                      ),
                      child: Text(
                        card.type == "jp" ? "日服" : "国际服",
                        style: const TextStyle(color: Colors.white, fontSize: 12),
                      ),
                    ),
                    const SizedBox(width: 10),

                    // ID 文本（自动占剩余空间）
                    Expanded(child: Text(card.segaId ?? "")),

                    // 三个紧凑按钮
                    _buildSmallButton("移除", Colors.red, () => _removeSegaCard(card, user)),
                    _buildSmallButton("验证", null, () => _verifyBoundSega(card)),
                    _buildSmallButton("刷新成绩", null, () => _refreshBoundSegaScore(card)),
                  ],
                ),
              );
           }).toList(),

          if (user.segaCards == null || user.segaCards!.isEmpty)
            const Padding(
              padding: EdgeInsets.symmetric(vertical: 8),
              child: Text("暂无 SegaID"),
            ),

          const SizedBox(height: 12),

          SizedBox(
            width: double.infinity,
            child: OutlinedButton.icon(
              onPressed: _showAddSegaSheet,
              icon: const Icon(Icons.add, size: 18),
              label: const Text("添加 Sega 账号"),
            ),
          ),
        ],
      ),
    );
  }
  Widget _buildSmallButton(String text, Color? color, VoidCallback onTap) {
    return TextButton(
      style: TextButton.styleFrom(
        foregroundColor: color,
        padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
        minimumSize: Size.zero,
        tapTargetSize: MaterialTapTargetSize.shrinkWrap,
      ),
      onPressed: onTap,
      child: Text(
        text,
        style: const TextStyle(fontSize: 12),
      ),
    );
  }
  Widget _webCard({required Widget child}) {
    return Builder(
      builder: (context) {
        final isDark = Theme.of(context).brightness == Brightness.dark;
        return Container(
          width: double.infinity,
          decoration: BoxDecoration(
            color: isDark ? Colors.grey[850] : Colors.white,
            borderRadius: BorderRadius.circular(16),
            border: Border.all(
                color: isDark ? Colors.grey[700]! : Colors.grey[200]!,
                width: 1),
            boxShadow: [
              BoxShadow(
                color: Colors.black12.withOpacity(isDark ? 0.3 : 0.08),
                blurRadius: 12,
                offset: const Offset(0, 2),
              ),
              BoxShadow(
                color: Colors.greenAccent.withOpacity(0.2),
                blurRadius: 15,
                spreadRadius: 3,
                offset: const Offset(0, 3),
              ),
            ],
          ),
          padding: const EdgeInsets.all(20),
          child: child,
        );
      },
    );
  }

  Widget _buildSectionCard(List<Widget> children) {
    return _webCard(child: Column(children: children));
  }

  Widget _buildCopyableItem(
      BuildContext context, String label, String? value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 5),
      child: InkWell(
        borderRadius: BorderRadius.circular(2),
        onTap: () {
          if (value == null || value.isEmpty) {
            ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text("暂无绑定 API Key")));
            return;
          }
          Clipboard.setData(ClipboardData(text: value));
          ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text("已复制：$value")));
        },
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            SizedBox(width: 120, child: Text(label)),
            Expanded(
              child: Text(
                value ?? "-",
                style: const TextStyle(
                    fontSize: 12,
                    color: Colors.blueAccent,
                    decoration: TextDecoration.underline),
              ),
            ),
            const SizedBox(width: 6),
            const Icon(Icons.copy, size: 14, color: Colors.grey),
          ],
        ),
      ),
    );
  }

  Widget _buildItem(String label, String? value) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 7),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(width: 120, child: Text(label)),
          Expanded(child: Text(value ?? "-")),
        ],
      ),
    );
  }

  Widget _buildSwitchItem(String title, bool value, ValueChanged<bool> onChanged) {
    return SwitchListTile(
      contentPadding: EdgeInsets.zero,
      title: Text(title),
      value: value,
      onChanged: onChanged,
    );
  }

  Widget _buildLogoutButton(BuildContext context, UserProvider provider) {
    return SizedBox(
      width: double.infinity,
      height: 50,
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          backgroundColor: Colors.redAccent,
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        ),
        onPressed: () async {
          await provider.logout();
          if (context.mounted) {
            Navigator.maybePop(context);
          }
        },
        child: const Text("退出登录",
            style: TextStyle(color: Colors.white, fontSize: 16)),
      ),
    );
  }

  Widget _buildLoginCard({required VoidCallback onTap}) {
    return Builder(
      builder: (context) {
        final isDark = Theme.of(context).brightness == Brightness.dark;
        final primaryColor = _pinkColor;

        return Container(
          width: double.infinity,
          constraints: const BoxConstraints(maxWidth: 400),
          padding: const EdgeInsets.all(24),
          decoration: BoxDecoration(
            color: isDark ? Colors.grey[850] : Colors.white,
            borderRadius: BorderRadius.circular(20),
            border: Border.all(
              color: isDark ? Colors.grey[700]! : Colors.grey[200]!,
              width: 1,
            ),
            boxShadow: [
              BoxShadow(
                color: Colors.pinkAccent.withOpacity(isDark ? 0.4 : 0.1),
                blurRadius: 20,
                spreadRadius: 10,
                offset: const Offset(0, 10),
              ),
            ],
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: primaryColor.withOpacity(0.1),
                  shape: BoxShape.circle,
                ),
                child: Icon(
                  Icons.account_circle_outlined,
                  size: 48,
                  color: primaryColor,
                ),
              ),
              const SizedBox(height: 16),
              Text(
                "加入Union",
                style: TextStyle(
                  fontSize: 22,
                  fontWeight: FontWeight.bold,
                  color: isDark ? Colors.white : Colors.black87,
                ),
              ),
              const SizedBox(height: 8),
              Text(
                "登录以解锁完整功能",
                style: TextStyle(
                  fontSize: 14,
                  color: isDark ? Colors.grey[400] : Colors.grey[600],
                ),
                textAlign: TextAlign.center,
              ),

              const SizedBox(height: 24),

              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: isDark ? Colors.grey[800] : Colors.grey[50],
                  borderRadius: BorderRadius.circular(12),
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    _buildBenefitItem(
                      icon: Icons.sync,
                      title: "多端数据同步",
                      desc: "水鱼/落雪查分器一键绑定",
                      isDark: isDark,
                    ),
                    const Divider(height: 16),
                    _buildBenefitItem(
                      icon: Icons.palette,
                      title: "无需其他查分器即可使用",
                      desc: "不依赖水鱼&落雪,同时支持日服与国际服全套服务",
                      isDark: isDark,
                    ),
                    const Divider(height: 16),
                    _buildBenefitItem(
                      icon: Icons.insights,
                      title: "深度数据分析",
                      desc: "查看 B50,Rating,歌曲详细推分 趋势与详情",
                      isDark: isDark,
                    ),
                  ],
                ),
              ),

              const SizedBox(height: 24),

              SizedBox(
                width: double.infinity,
                height: 50,
                child: ElevatedButton(
                  onPressed: onTap,
                  style: ElevatedButton.styleFrom(
                    backgroundColor: primaryColor,
                    foregroundColor: Colors.white,
                    elevation: 0,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(12),
                    ),
                  ),
                  child: const Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(
                        "立即登录 / 注册",
                        style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
                      ),
                      SizedBox(width: 8),
                      Icon(Icons.arrow_forward, size: 18),
                    ],
                  ),
                ),
              ),
            ],
          ),
        );
      },
    );
  }
// 移除 国服账号（仿照移除Sega）
  Future<void> _removeGuoFuAccount(String name, UserModel user) async {
    final confirm = await showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text("确认移除"),
        content: Text("确定要删除国服账号 $name 吗？"),
        actions: [
          TextButton(onPressed: () => Navigator.pop(ctx), child: const Text("取消")),
          TextButton(
            onPressed: () => Navigator.pop(ctx, true),
            style: TextButton.styleFrom(foregroundColor: Colors.red),
            child: const Text("删除"),
          ),
        ],
      ),
    );

    if (confirm != true) return;

    final provider = Provider.of<UserProvider>(context, listen: false);

    // 复制并删除指定name的国服账号
    Map<String, int> newMap = Map.from(user.userName2userId ?? {});
    newMap.remove(name);

    // 完全沿用你原来的 UserModel 构造（一模一样）
    UserModel updatedUser = UserModel(
      id: user.id,
      name: user.name,
      userId: user.userId,
      teamId: user.teamId,
      email: user.email,
      password: user.password,
      twoFactorKey: user.twoFactorKey,
      apiKey: user.apiKey,
      apiBindKey: user.apiBindKey,
      protectRole: user.protectRole,
      risks: user.risks,
      mcName: user.mcName,
      userName2userId: newMap,
      lxKey: user.lxKey,
      dfUsername: user.dfUsername,
      dfPassword: user.dfPassword,
      nuoId: user.nuoId,
      botId: user.botId,
      spasolBotId: user.spasolBotId,
      githubId: user.githubId,
      rating: user.rating,
      ratingMax: user.ratingMax,
      iconId: user.iconId,
      plateId: user.plateId,
      plateIds: user.plateIds,
      frameId: user.frameId,
      charaSlots: user.charaSlots,
      qiandaoDay: user.qiandaoDay,
      inviter: user.inviter,
      successLogoutTime: user.successLogoutTime,
      lastLoginTime: user.lastLoginTime,
      friendIds: user.friendIds,
      bio: user.bio,
      friendBio: user.friendBio,
      sex: user.sex,
      isDisagreeRecommend: user.isDisagreeRecommend,
      isDisagreeFriend: user.isDisagreeFriend,
      points: user.points,
      planPoints: user.planPoints,
      cardIds: user.cardIds,
      userCards: user.userCards,
      tags: user.tags,
      useBeta: user.useBeta,
      useNuo: user.useNuo,
      useServer: user.useServer,
      useB50Type: user.useB50Type,
      userHot: user.userHot,
      chatInGroupNumbers: user.chatInGroupNumbers,
      sc: user.sc,
      id2pcNuo: user.id2pcNuo,
      mai2links: user.mai2links,
      key2KeychipEn: user.key2KeychipEn,
      key2key2KeychipEn: user.key2key2KeychipEn,
      mai2link: user.mai2link,
      userRegion: user.userRegion,
      rinUsernameOrEmail: user.rinUsernameOrEmail,
      rinPassword: user.rinPassword,
      rinChusanUser: user.rinChusanUser,
      segaCards: user.segaCards,
      placeList: user.placeList,
      lastKeyChip: user.lastKeyChip,
      token: user.token,
      timesRegionData: user.timesRegionData,
      yearTotal: user.yearTotal,
      yearTotalComment: user.yearTotalComment,
      userCollCardMap: user.userCollCardMap,
      collName2musicIds: user.collName2musicIds,
      ai: user.ai,
      pkScore: user.pkScore,
      pkScoreStr: user.pkScoreStr,
      pkScoreReality: user.pkScoreReality,
      pkUserId: user.pkUserId,
      limitPkTimestamp: user.limitPkTimestamp,
      hasAcceptPk: user.hasAcceptPk,
      pkPlayNum: user.pkPlayNum,
      pkWin: user.pkWin,
      userData: user.userData,
      banState: user.banState,
    );

    provider.updateUser(updatedUser);
    await provider.saveUserInfo();

    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("✅ 已移除国服账号：$name")),
      );
    }
  }
  Widget _buildBenefitItem({
    required IconData icon,
    required String title,
    required String desc,
    required bool isDark,
  }) {
    return Row(
      children: [
        Icon(icon, size: 20, color: isDark ? Colors.grey[400] : Colors.grey[600]),
        const SizedBox(width: 12),
        Expanded(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                title,
                style: TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.w600,
                  color: isDark ? Colors.white : Colors.black87,
                ),
              ),
              Text(
                desc,
                style: TextStyle(
                  fontSize: 12,
                  color: isDark ? Colors.grey[500] : Colors.grey[500],
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  Widget _buildRadarChartSection() {
    return _webCard(
      child: Column(
        children: [
          const Text(
            "能力雷达图",
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
          const SizedBox(height: 16),

          if (_radarData == null)
            TextButton(
              onPressed: _loadRadarData,
              child: const Text("点击加载雷达图数据"),
            )
          else
            SizedBox(
              height: 300,
              width: double.infinity,
              child: CustomRadarChart(
                data: _radarData!.map((key, value) =>
                    MapEntry(key.toString(), double.tryParse(value.toString()) ?? 0.0)
                ),
                maxValue: 1.2,
                lineColor: Colors.grey.shade200,
                areaColor: Colors.pink.withOpacity(0.15),
                borderColor: Colors.pinkAccent,
              ),
            ),

          const SizedBox(height: 20),

          if (_radarData != null)
            GridView.count(
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              crossAxisCount: 3,
              childAspectRatio: 2.4,
              crossAxisSpacing: 8,
              mainAxisSpacing: 8,
              children: _radarData!.entries.map((e) {
                final key = e.key.toString();
                final value = double.tryParse(e.value.toString()) ?? 0.0;
                final isHigh = value >= 1.0;

                return Container(
                  padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(8),
                    border: Border.all(
                      color: isHigh ? Colors.pink.shade200 : Colors.grey.shade300,
                      width: 1,
                    ),
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        key,
                        style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
                      ),
                      Text(
                        value.toStringAsFixed(2),
                        style: const TextStyle(
                          fontSize: 12,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ],
                  ),
                );
              }).toList(),
            ),
        ],
      ),
    );
  }
}




class CustomRadarChart extends StatelessWidget {
  final Map<String, double> data; // 维度名 -> 数值
  final double maxValue; // 最大值，用于计算比例
  final Color lineColor; // 网格线颜色
  final Color areaColor; // 填充区域颜色
  final Color borderColor; // 边框线条颜色

  const CustomRadarChart({
    super.key,
    required this.data,
    this.maxValue = 1.3,
    this.lineColor = const Color(0xFFE0E0E0), // 极淡的灰色，几乎看不见
    this.areaColor = const Color(0x40FF69B4), // 半透明粉色
    this.borderColor = const Color(0xFFEC407A), // 实线粉色
  });

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        // 取宽高较小者作为绘图区域，保证是正方形
        final size = math.min(constraints.maxWidth, constraints.maxHeight);
        return SizedBox(
          width: size,
          height: size,
          child: CustomPaint(
            painter: _RadarPainter(
              data: data,
              maxValue: maxValue,
              lineColor: lineColor,
              areaColor: areaColor,
              borderColor: borderColor,
            ),
          ),
        );
      },
    );
  }
}

class _RadarPainter extends CustomPainter {
  final Map<String, double> data;
  final double maxValue;
  final Color lineColor;
  final Color areaColor;
  final Color borderColor;

  _RadarPainter({
    required this.data,
    required this.maxValue,
    required this.lineColor,
    required this.areaColor,
    required this.borderColor,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    // 半径留一点 padding，防止文字贴边
    final radius = math.min(size.width, size.height) / 2 * 0.85;
    final count = data.length;

    if (count == 0) return;

    final angleStep = (2 * math.pi) / count;

    // --- 1. 绘制背景网格 (同心多边形) ---
    final gridPaint = Paint()
      ..color = lineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.0;

    // 画 5 层网格 (0.2, 0.4, 0.6, 0.8, 1.0 比例)
    for (int i = 1; i <= 5; i++) {
      final levelRadius = radius * (i / 5);
      final path = Path();
      for (int j = 0; j < count; j++) {
        final angle = j * angleStep - math.pi / 2; // -pi/2 让第一个点朝上
        final x = center.dx + levelRadius * math.cos(angle);
        final y = center.dy + levelRadius * math.sin(angle);
        if (j == 0) {
          path.moveTo(x, y);
        } else {
          path.lineTo(x, y);
        }
      }
      path.close();
      canvas.drawPath(path, gridPaint);
    }

    // --- 2. 绘制辐射轴线 (从中心到顶点) ---
    // 如果你连这个轴线也不想要，可以注释掉这一段
    for (int i = 0; i < count; i++) {
      final angle = i * angleStep - math.pi / 2;
      final x = center.dx + radius * math.cos(angle);
      final y = center.dy + radius * math.sin(angle);

      canvas.drawLine(
        center,
        Offset(x, y),
        gridPaint, // 使用同样的淡色
      );
    }

    // --- 3. 绘制数据区域 ---
    final dataPath = Path();
    final dataPoints = <Offset>[];

    for (int i = 0; i < count; i++) {
      final key = data.keys.elementAt(i);
      final value = data[key] ?? 0.0;

      // 计算当前值的比例半径
      final ratio = (value / maxValue).clamp(0.0, 1.0);
      final currentRadius = radius * ratio;

      final angle = i * angleStep - math.pi / 2;
      final x = center.dx + currentRadius * math.cos(angle);
      final y = center.dy + currentRadius * math.sin(angle);

      dataPoints.add(Offset(x, y));

      if (i == 0) {
        dataPath.moveTo(x, y);
      } else {
        dataPath.lineTo(x, y);
      }
    }
    dataPath.close();

    // 填充颜色
    final fillPaint = Paint()
      ..color = areaColor
      ..style = PaintingStyle.fill;
    canvas.drawPath(dataPath, fillPaint);

    // 描边颜色
    final borderPaint = Paint()
      ..color = borderColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0
      ..strokeJoin = StrokeJoin.round; // 圆角连接，更美观
    canvas.drawPath(dataPath, borderPaint);

    // --- 4. 绘制顶点小圆点 (可选，增加精致感) ---
    final dotPaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;
    final dotBorderPaint = Paint()
      ..color = borderColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.5;

    for (var point in dataPoints) {
      canvas.drawCircle(point, 3.5, dotPaint);
      canvas.drawCircle(point, 3.5, dotBorderPaint);
    }

    final textPainter = TextPainter(
      textAlign: TextAlign.center,
      textDirection: TextDirection.ltr,
    );

    for (int i = 0; i < count; i++) {
      final key = data.keys.elementAt(i);
      final angle = i * angleStep - math.pi / 2;

      // 文字位置再往外扩一点
      final labelRadius = radius + 20;
      final x = center.dx + labelRadius * math.cos(angle);
      final y = center.dy + labelRadius * math.sin(angle);

      textPainter.text = TextSpan(
        text: key,
        style: const TextStyle(fontSize: 12,color: Colors.pinkAccent),
      );
      textPainter.layout();

      // 修正文字居中
      textPainter.paint(canvas, Offset(x - textPainter.width / 2, y - textPainter.height / 2));
    }
  }

  @override
  bool shouldRepaint(covariant _RadarPainter oldDelegate) {
    return oldDelegate.data != data || oldDelegate.maxValue != maxValue;
  }
}
/// 最外层响应结构
class LuoxueResponse {
  final bool success;
  final int code;
  final LuoxuePlayer data;

  LuoxueResponse({
    required this.success,
    required this.code,
    required this.data,
  });

  factory LuoxueResponse.fromJson(Map<String, dynamic> json) {
    return LuoxueResponse(
      success: json['success'] ?? false,
      code: json['code'] ?? 0,
      data: LuoxuePlayer.fromJson(json['data'] ?? {}),
    );
  }
}

/// 玩家信息
class LuoxuePlayer {
  final String name;
  final int rating;
  final int friendCode;
  final int courseRank;
  final int classRank;
  final int star;
  final String uploadTime;
  final LuoxueTrophy trophy;
  final LuoxueIcon icon;
  final LuoxueNamePlate namePlate;
  final LuoxueFrame frame;

  LuoxuePlayer({
    required this.name,
    required this.rating,
    required this.friendCode,
    required this.courseRank,
    required this.classRank,
    required this.star,
    required this.uploadTime,
    required this.trophy,
    required this.icon,
    required this.namePlate,
    required this.frame,
  });

  factory LuoxuePlayer.fromJson(Map<String, dynamic> json) {
    return LuoxuePlayer(
      name: json['name'] ?? '',
      rating: json['rating'] ?? 0,
      friendCode: json['friend_code'] ?? 0,
      courseRank: json['course_rank'] ?? 0,
      classRank: json['class_rank'] ?? 0,
      star: json['star'] ?? 0,
      uploadTime: json['upload_time'] ?? '',
      trophy: LuoxueTrophy.fromJson(json['trophy'] ?? {}),
      icon: LuoxueIcon.fromJson(json['icon'] ?? {}),
      namePlate: LuoxueNamePlate.fromJson(json['name_plate'] ?? {}),
      frame: LuoxueFrame.fromJson(json['frame'] ?? {}),
    );
  }
}

/// 称号
class LuoxueTrophy {
  final int id;
  final String name;
  final String genre;
  final String color;

  LuoxueTrophy({
    required this.id,
    required this.name,
    required this.genre,
    required this.color,
  });

  factory LuoxueTrophy.fromJson(Map<String, dynamic> json) {
    return LuoxueTrophy(
      id: json['id'] ?? 0,
      name: json['name'] ?? '',
      genre: json['genre'] ?? '',
      color: json['color'] ?? '',
    );
  }
}

/// 头像
class LuoxueIcon {
  final int id;
  final String name;
  final String genre;

  LuoxueIcon({
    required this.id,
    required this.name,
    required this.genre,
  });

  factory LuoxueIcon.fromJson(Map<String, dynamic> json) {
    return LuoxueIcon(
      id: json['id'] ?? 0,
      name: json['name'] ?? '',
      genre: json['genre'] ?? '',
    );
  }
}

/// 姓名框
class LuoxueNamePlate {
  final int id;
  final String name;
  final String genre;

  LuoxueNamePlate({
    required this.id,
    required this.name,
    required this.genre,
  });

  factory LuoxueNamePlate.fromJson(Map<String, dynamic> json) {
    return LuoxueNamePlate(
      id: json['id'] ?? 0,
      name: json['name'] ?? '',
      genre: json['genre'] ?? '',
    );
  }
}

/// 背景
class LuoxueFrame {
  final int id;
  final String name;
  final String genre;

  LuoxueFrame({
    required this.id,
    required this.name,
    required this.genre,
  });

  factory LuoxueFrame.fromJson(Map<String, dynamic> json) {
    return LuoxueFrame(
      id: json['id'] ?? 0,
      name: json['name'] ?? '',
      genre: json['genre'] ?? '',
    );
  }
}