import 'dart:async';
import 'dart:math';

import 'package:PiliPalaX/grpc/grpc_repo.dart';
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:PiliPalaX/http/member.dart';
import 'package:PiliPalaX/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:get/get_navigation/src/dialog/dialog_route.dart';
import 'package:hive/hive.dart';
import 'package:PiliPalaX/http/constants.dart';
import 'package:PiliPalaX/http/user.dart';
import 'package:PiliPalaX/http/video.dart';
import 'package:PiliPalaX/models/user/fav_folder.dart';
import 'package:PiliPalaX/models/video/ai.dart';
import 'package:PiliPalaX/models/video_detail_res.dart';
import 'package:PiliPalaX/pages/video/detail/controller.dart';
import 'package:PiliPalaX/pages/video/detail/reply/index.dart';
import 'package:PiliPalaX/plugin/pl_player/models/play_repeat.dart';
import 'package:PiliPalaX/utils/feed_back.dart';
import 'package:PiliPalaX/utils/id_utils.dart';
import 'package:PiliPalaX/utils/storage.dart';
import 'package:share_plus/share_plus.dart';
import 'package:PiliPalaX/pages/member/controller.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../../../http/search.dart';
import '../../../../models/model_hot_video_item.dart';
import '../related/index.dart';
import 'widgets/group_panel.dart';

class VideoIntroController extends GetxController
    with GetTickerProviderStateMixin {
  // 视频bvid
  late String bvid;

  // 是否预渲染 骨架屏
  bool preRender = false;

  // 视频详情 上个页面传入
  Map? videoItem = {};

  // 请求状态
  RxBool isLoading = false.obs;

  // 视频详情 请求返回
  Rx<VideoDetailData> videoDetail = VideoDetailData().obs;

  // up主粉丝数
  Rx<Map<String, dynamic>> userStat =
      Rx<Map<String, dynamic>>({'follower': '-'});

  dynamic videoTags;

  // 是否点赞
  RxBool hasLike = false.obs;
  // 是否点踩
  RxBool hasDislike = false.obs;
  // 是否投币
  RxBool hasCoin = false.obs;
  // 是否收藏
  RxBool hasFav = false.obs;
  Box userInfoCache = GStorage.userInfo;
  bool userLogin = false;
  Rx<FavFolderData> favFolderData = FavFolderData().obs;
  List addMediaIdsNew = [];
  List delMediaIdsNew = [];
  // 关注状态 默认未关注
  RxMap followStatus = {}.obs;

  RxInt lastPlayCid = 0.obs;
  dynamic userInfo;

  // 同时观看
  bool isShowOnlineTotal = false;
  RxString total = '1'.obs;
  Timer? timer;
  bool isPaused = false;
  String heroTag = '';
  late ModelResult modelResult;
  Rx<Map<String, dynamic>> queryVideoIntroData =
      Rx<Map<String, dynamic>>({"status": true});

  @override
  void onInit() {
    super.onInit();
    userInfo = userInfoCache.get('userInfoCache');
    try {
      if (heroTag.isEmpty) {
        heroTag = Get.arguments['heroTag'];
      }
      bvid = Get.parameters['bvid']!;
    } catch (_) {}
    if (Get.arguments.isNotEmpty) {
      if (Get.arguments.containsKey('videoItem')) {
        preRender = true;
        var args = Get.arguments['videoItem'];
        var keys = Get.arguments.keys.toList();
        videoItem!['pic'] = args.pic;
        if (args.title is String) {
          videoItem!['title'] = args.title;
        } else {
          String str = '';
          for (Map map in args.title) {
            str += map['text'];
          }
          videoItem!['title'] = str;
        }
        videoItem!['stat'] = keys.contains('stat') ? args.stat : null;
        videoItem!['pubdate'] = keys.contains('pubdate') ? args.pubdate : null;
        videoItem!['owner'] = keys.contains('owner') ? args.owner : null;
      }
    }
    userLogin = userInfo != null;
    lastPlayCid.value = int.parse(Get.parameters['cid']!);
    isShowOnlineTotal =
        setting.get(SettingBoxKey.enableOnlineTotal, defaultValue: true);
    startTimer();
    queryVideoIntro();
  }

  late final videoDetailController =
      Get.find<VideoDetailController>(tag: heroTag);

  // 获取视频简介&分p
  void queryVideoIntro() async {
    queryVideoTags();
    var result = await VideoHttp.videoIntro(bvid: bvid);
    if (result['status']) {
      videoDetail.value = result['data']!;
      videoItem!['staff'] = result['data'].staff;
      if (videoDetailController.videoItem['pic'] == null ||
          videoDetailController.videoItem['pic'] == '') {
        try {
          videoDetailController.videoItem['pic'] = result['data'].pic;
        } catch (e) {
          debugPrint(e.toString());
        }
      }
      if (videoDetail.value.pages != null &&
          videoDetail.value.pages!.isNotEmpty &&
          lastPlayCid.value == 0) {
        lastPlayCid.value = videoDetail.value.pages!.first.cid!;
      }
      // Get.find<VideoDetailController>(tag: heroTag).tabs.value = [
      //   '简介',
      //   '评论 ${result['data']!.stat!.reply}'
      // ];
      // 获取到粉丝数再返回
      await queryUserStat();
    } else {
      SmartDialog.showToast(
          "${result['code']} ${result['msg']} ${result['data']}");
    }
    queryVideoIntroData.value = result;
    if (userLogin) {
      // 获取点赞状态
      queryHasLikeVideo();
      // 获取投币状态
      queryHasCoinVideo();
      // 获取收藏状态
      queryHasFavVideo();
      //
      queryFollowStatus();
    }
  }

  Future queryVideoTags() async {
    var result = await UserHttp.videoTags(bvid: bvid);
    if (result['status']) {
      videoTags = result['data'];
      // debugPrint('tags: ${result['data']}');
    }
  }

  // 获取up主粉丝数
  Future queryUserStat() async {
    var result = await UserHttp.userStat(mid: videoDetail.value.owner!.mid!);
    if (result['status']) {
      print(result['data']);
      userStat.value = result['data'];
      userStat.refresh();
    }
  }

  // 获取点赞状态
  Future queryHasLikeVideo() async {
    var result = await VideoHttp.hasLikeVideo(bvid: bvid);
    // data	num	被点赞标志	0：未点赞  1：已点赞  2：已点踩
    hasLike.value = result["data"] == 1;
    hasDislike.value = result["data"] == 2;
  }

  // 获取投币状态
  Future queryHasCoinVideo() async {
    var result = await VideoHttp.hasCoinVideo(bvid: bvid);
    if (result['status']) {
      hasCoin.value = result["data"]['multiply'] != 0;
    }
  }

  // 获取收藏状态
  Future queryHasFavVideo() async {
    /// fix 延迟查询
    await Future.delayed(const Duration(milliseconds: 200));
    var result = await VideoHttp.hasFavVideo(aid: IdUtils.bv2av(bvid));
    if (result['status']) {
      hasFav.value = result["data"]['favoured'];
    } else {
      hasFav.value = false;
    }
  }

  // 一键三连
  Future actionOneThree() async {
    feedBack();
    if (userInfo == null) {
      SmartDialog.showToast('账号未登录');
      return;
    }
    if (hasLike.value && hasCoin.value && hasFav.value) {
      // 已点赞、投币、收藏
      SmartDialog.showToast('已三连');
      return false;
    }
    var result = await VideoHttp.oneThree(bvid: bvid);
    if (result['status']) {
      hasLike.value = result["data"]["like"];
      hasCoin.value = result["data"]["coin"];
      hasFav.value = result["data"]["fav"];
      SmartDialog.showToast('三连成功');
    } else {
      SmartDialog.showToast(result['msg']);
    }
  }

  // （取消）点赞
  Future actionLikeVideo() async {
    if (userInfo == null) {
      SmartDialog.showToast('账号未登录');
      return;
    }
    var result = await VideoHttp.likeVideo(bvid: bvid, type: !hasLike.value);
    if (result['status']) {
      // hasLike.value = result["data"] == 1 ? true : false;
      if (!hasLike.value) {
        SmartDialog.showToast(result['data']['toast']);
        hasLike.value = true;
        hasDislike.value = false;
        videoDetail.value.stat!.like = videoDetail.value.stat!.like! + 1;
      } else if (hasLike.value) {
        SmartDialog.showToast('取消赞');
        hasLike.value = false;
        videoDetail.value.stat!.like = videoDetail.value.stat!.like! - 1;
      }
      hasLike.refresh();
    } else {
      SmartDialog.showToast(result['msg']);
    }
  }

  Future actionDislikeVideo() async {
    if (userInfo == null) {
      SmartDialog.showToast('账号未登录');
      return;
    }
    var result =
        await VideoHttp.dislikeVideo(bvid: bvid, type: !hasDislike.value);
    if (result['status']) {
      // hasLike.value = result["data"] == 1 ? true : false;
      if (!hasDislike.value) {
        SmartDialog.showToast('点踩成功');
        hasDislike.value = true;
        hasLike.value = false;
      } else {
        SmartDialog.showToast('取消踩');
        hasDislike.value = false;
      }
      // hasDislike.refresh();
    } else {
      SmartDialog.showToast(result['msg']);
    }
  }

  void coinVideo(int coin) async {
    var res = await VideoHttp.coinVideo(bvid: bvid, multiply: coin);
    if (res['status']) {
      print(res);
      SmartDialog.showToast('投币成功');
      hasCoin.value = true;
      videoDetail.value.stat!.coin = videoDetail.value.stat!.coin! + coin;
    } else {
      SmartDialog.showToast(res['msg']);
    }
  }

  // 投币
  Future actionCoinVideo() async {
    if (userInfo == null) {
      SmartDialog.showToast('账号未登录');
      return;
    }

    Navigator.of(Get.context!).push(
      GetDialogRoute(
        pageBuilder: (buildContext, animation, secondaryAnimation) {
          return PayCoinsPage(
            callback: coinVideo,
            copyright: (queryVideoIntroData.value['data'] as VideoDetailData?)
                    ?.copyright ??
                1,
          );
        },
        transitionDuration: const Duration(milliseconds: 225),
        transitionBuilder: (context, animation, secondaryAnimation, child) {
          const begin = 0.0;
          const end = 1.0;
          const curve = Curves.linear;

          var tween = Tween<double>(begin: begin, end: end)
              .chain(CurveTween(curve: curve));

          return FadeTransition(
            opacity: animation.drive(tween),
            child: child,
          );
        },
      ),
    );
    // showDialog(
    //   context: Get.context!,
    //   builder: (context) {
    //     return AlertDialog(
    //       title: const Text('选择投币个数'),
    //       contentPadding: const EdgeInsets.fromLTRB(0, 12, 0, 12),
    //       actions: [
    //         TextButton(
    //             onPressed: () => Get.back(),
    //             child: Text('取消',
    //                 style: TextStyle(
    //                     color: Theme.of(context).colorScheme.outline))),
    //         TextButton(
    //             onPressed: () async {
    //               coinVideo(1);
    //               Get.back();
    //             },
    //             child: const Text('投 1 枚')),
    //         TextButton(
    //             onPressed: () async {
    //               coinVideo(2);
    //               Get.back();
    //             },
    //             child: const Text('投 2 枚'))
    //       ],
    //     );
    //   },
    // );
  }

  // （取消）收藏
  Future actionFavVideo({type = 'choose'}) async {
    // 收藏至默认文件夹
    if (type == 'default') {
      SmartDialog.showLoading(msg: '请求中');
      await queryVideoInFolder();
      int defaultFolderId = favFolderData.value.list!.first.id!;
      int favStatus = favFolderData.value.list!.first.favState!;
      var result = await VideoHttp.favVideo(
        aid: IdUtils.bv2av(bvid),
        addIds: favStatus == 0 ? '$defaultFolderId' : '',
        delIds: favStatus == 1 ? '$defaultFolderId' : '',
      );
      SmartDialog.dismiss();
      if (result['status']) {
        // 重新获取收藏状态
        await queryHasFavVideo();
        SmartDialog.showToast('✅ 快速收藏/取消收藏成功');
      } else {
        SmartDialog.showToast(result['msg']);
      }
      return;
    }
    try {
      for (var i in favFolderData.value.list!.toList()) {
        if (i.favState == 1) {
          addMediaIdsNew.add(i.id);
        } else {
          delMediaIdsNew.add(i.id);
        }
      }
    } catch (e) {
      // ignore: avoid_print
      print(e);
    }
    SmartDialog.showLoading(msg: '请求中');
    var result = await VideoHttp.favVideo(
        aid: IdUtils.bv2av(bvid),
        addIds: addMediaIdsNew.join(','),
        delIds: delMediaIdsNew.join(','));
    SmartDialog.dismiss();
    if (result['status']) {
      addMediaIdsNew = [];
      delMediaIdsNew = [];
      Get.back();
      // 重新获取收藏状态
      await queryHasFavVideo();
      SmartDialog.showToast('操作成功');
    } else {
      SmartDialog.showToast(result['msg']);
    }
  }

  // 分享视频
  Future actionShareVideo() async {
    showDialog(
        context: Get.context!,
        builder: (context) {
          String videoUrl = '${HttpString.baseUrl}/video/$bvid';
          return AlertDialog(
            clipBehavior: Clip.hardEdge,
            contentPadding: const EdgeInsets.symmetric(vertical: 12),
            content: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                ListTile(
                  title: const Text(
                    '复制链接',
                    style: TextStyle(fontSize: 14),
                  ),
                  onTap: () {
                    Get.back();
                    Clipboard.setData(ClipboardData(text: videoUrl));
                    SmartDialog.showToast('已复制');
                  },
                ),
                ListTile(
                  title: const Text(
                    '其它app打开',
                    style: TextStyle(fontSize: 14),
                  ),
                  onTap: () {
                    Get.back();
                    Utils.launchURL(videoUrl);
                  },
                ),
                ListTile(
                  title: const Text(
                    '分享视频',
                    style: TextStyle(fontSize: 14),
                  ),
                  onTap: () {
                    Get.back();
                    Share.share('${videoDetail.value.title} '
                        'UP主: ${videoDetail.value.owner!.name!}'
                        ' - $videoUrl');
                  },
                ),
              ],
            ),
          );
        });
  }

  Future queryVideoInFolder() async {
    var result = await VideoHttp.videoInFolder(
        mid: userInfo.mid, rid: IdUtils.bv2av(bvid));
    if (result['status']) {
      favFolderData.value = result['data'];
    }
    return result;
  }

  // 选择文件夹
  onChoose(bool checkValue, int index) {
    feedBack();
    List<FavFolderItemData> datalist = favFolderData.value.list!;
    for (var i = 0; i < datalist.length; i++) {
      if (i == index) {
        datalist[i].favState = checkValue == true ? 1 : 0;
        datalist[i].mediaCount = checkValue == true
            ? datalist[i].mediaCount! + 1
            : datalist[i].mediaCount! - 1;
      }
    }
    favFolderData.value.list = datalist;
    favFolderData.refresh();
  }

  // 查询关注状态
  Future queryFollowStatus() async {
    if (videoDetail.value.owner == null) {
      return;
    }
    var result = await VideoHttp.hasFollow(mid: videoDetail.value.owner!.mid!);
    if (result['status']) {
      followStatus.value = result['data'];
    }
    return result;
  }

  // 关注/取关up
  Future actionRelationMod(BuildContext context) async {
    if (userInfo == null) {
      SmartDialog.showToast('账号未登录');
      return;
    }
    if (videoDetail.value.owner?.mid == null) {
      return;
    }
    feedBack();
    int mid = videoDetail.value.owner!.mid!;
    if ((followStatus['attribute'] ?? 0) == 0) {
      var res = await VideoHttp.relationMod(
        mid: mid,
        act: 1,
        reSrc: 11,
      );
      SmartDialog.showToast(res['status'] ? "关注成功" : res['msg']);
      if (res['status']) {
        followStatus['attribute'] = 2;
        followStatus.refresh();
      }
    } else {
      /// TODO
      showDialog(
        context: context,
        builder: (_) {
          bool isSpecialFollowed = followStatus['special'] == 1;
          String text = isSpecialFollowed ? '移除特别关注' : '加入特别关注';
          return AlertDialog(
            clipBehavior: Clip.hardEdge,
            contentPadding: const EdgeInsets.symmetric(vertical: 12),
            content: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                ListTile(
                  dense: true,
                  onTap: () async {
                    Get.back();
                    final res = await MemberHttp.specialAction(
                      fid: mid,
                      isAdd: !isSpecialFollowed,
                    );
                    if (res['status']) {
                      followStatus['special'] = isSpecialFollowed ? 0 : 1;
                      List tags = followStatus['tag'] ?? [];
                      if (isSpecialFollowed) {
                        tags.remove(-10);
                      } else {
                        tags.add(-10);
                      }
                      followStatus['tag'] = tags;
                      followStatus.refresh();
                      SmartDialog.showToast('$text成功');
                    } else {
                      SmartDialog.showToast(res['msg']);
                    }
                  },
                  title: Text(
                    text,
                    style: TextStyle(fontSize: 14),
                  ),
                ),
                ListTile(
                  dense: true,
                  onTap: () async {
                    Get.back();
                    dynamic result = await showModalBottomSheet(
                      context: context,
                      useSafeArea: true,
                      isScrollControlled: true,
                      transitionAnimationController: AnimationController(
                        duration: const Duration(milliseconds: 200),
                        vsync: this,
                      ),
                      sheetAnimationStyle: AnimationStyle(curve: Curves.ease),
                      builder: (BuildContext context) {
                        return DraggableScrollableSheet(
                          minChildSize: 0,
                          maxChildSize: 1,
                          initialChildSize: 0.6,
                          snap: true,
                          expand: false,
                          snapSizes: const [0.6],
                          builder: (BuildContext context,
                              ScrollController scrollController) {
                            return GroupPanel(
                              mid: mid,
                              tags: followStatus['tag'],
                              scrollController: scrollController,
                            );
                          },
                        );
                      },
                    );
                    await Future.delayed(const Duration(milliseconds: 500));
                    if (result == true) {
                      queryFollowStatus();
                    }
                  },
                  title: const Text(
                    '设置分组',
                    style: TextStyle(fontSize: 14),
                  ),
                ),
                ListTile(
                  dense: true,
                  onTap: () async {
                    Get.back();
                    var res = await VideoHttp.relationMod(
                      mid: mid,
                      act: 2,
                      reSrc: 11,
                    );
                    SmartDialog.showToast(
                        res['status'] ? "取消关注成功" : res['msg']);
                    if (res['status']) {
                      followStatus['attribute'] = 0;
                      followStatus.refresh();
                    }
                  },
                  title: const Text(
                    '取消关注',
                    style: TextStyle(fontSize: 14),
                  ),
                ),
              ],
            ),
          );
        },
      );
    }

    // MemberController _ = Get.put<MemberController>(MemberController(mid: mid),
    //     tag: mid.toString());
    // await _.getInfo();
    // if (context.mounted) await _.actionRelationMod(context);
    // followStatus['attribute'] = _.attribute.value;
    // followStatus.refresh();
    // Get.delete<MemberController>(tag: mid.toString());
  }

  // 修改分P或番剧分集
  Future changeSeasonOrbangu(epid, bvid, cid, aid, cover) async {
    // 重新获取视频资源
    final VideoDetailController videoDetailCtr =
        Get.find<VideoDetailController>(tag: heroTag);
    videoDetailCtr.bvid = bvid;
    videoDetailCtr.oid.value = aid ?? IdUtils.bv2av(bvid);
    videoDetailCtr.cid.value = cid;
    if (cover is String && cover.isNotEmpty) {
      videoDetailCtr.videoItem['pic'] = cover;
    }
    videoDetailCtr.danmakuCid.value = cid;
    videoDetailCtr.queryVideoUrl();
    // 重新请求相关视频
    try {
      final RelatedController relatedCtr =
          Get.find<RelatedController>(tag: heroTag);
      relatedCtr.bvid = bvid;
      relatedCtr.queryData();
    } catch (_) {}
    // 重新请求评论
    try {
      final VideoReplyController videoReplyCtr =
          Get.find<VideoReplyController>(tag: heroTag);
      videoReplyCtr.aid = aid;
      videoReplyCtr.onRefresh();
    } catch (_) {}
    this.bvid = bvid;
    lastPlayCid.value = cid;
    queryVideoIntro();
  }

  void startTimer() {
    if (isShowOnlineTotal) {
      queryOnlineTotal();
      const duration = Duration(seconds: 10); // 设置定时器间隔为10秒
      timer ??= Timer.periodic(duration, (Timer timer) {
        if (!isPaused) {
          queryOnlineTotal(); // 定时器回调函数，发起请求
        }
      });
    }
  }

  void canelTimer() {
    timer?.cancel();
    timer = null;
  }

  // 查看同时在看人数
  Future queryOnlineTotal() async {
    // var result = await VideoHttp.onlineTotal(
    //   aid: IdUtils.bv2av(bvid),
    //   bvid: bvid,
    //   cid: lastPlayCid.value,
    // );
    dynamic result = await GrpcRepo.playerOnline(
      aid: IdUtils.bv2av(bvid),
      cid: lastPlayCid.value,
    );
    if (result['status']) {
      total.value = result['data'];
    }
  }

  @override
  void onClose() {
    if (timer != null) {
      timer!.cancel(); // 销毁页面时取消定时器
    }
    super.onClose();
  }

  /// 播放上一个
  bool prevPlay() {
    final List episodes = [];
    bool isPages = false;
    if (videoDetail.value.ugcSeason != null) {
      final UgcSeason ugcSeason = videoDetail.value.ugcSeason!;
      final List<SectionItem> sections = ugcSeason.sections!;
      for (int i = 0; i < sections.length; i++) {
        final List<EpisodeItem> episodesList = sections[i].episodes!;
        episodes.addAll(episodesList);
      }
    } else if (videoDetail.value.pages != null) {
      isPages = true;
      final List<Part> pages = videoDetail.value.pages!;
      episodes.addAll(pages);
    }

    final int currentIndex =
        episodes.indexWhere((e) => e.cid == lastPlayCid.value);
    int prevIndex = currentIndex - 1;
    final VideoDetailController videoDetailCtr =
        Get.find<VideoDetailController>(tag: heroTag);
    final PlayRepeat platRepeat = videoDetailCtr.plPlayerController.playRepeat;

    // 列表循环
    if (prevIndex < 0) {
      if (platRepeat == PlayRepeat.listCycle) {
        prevIndex = episodes.length - 1;
      } else {
        return false;
      }
    }
    final int cid = episodes[prevIndex].cid!;
    final String rBvid = isPages ? bvid : episodes[prevIndex].bvid;
    final int rAid = isPages ? IdUtils.bv2av(bvid) : episodes[prevIndex].aid!;
    changeSeasonOrbangu(null, rBvid, cid, rAid, null);
    return true;
  }

  /// 列表循环或者顺序播放时，自动播放下一个
  bool nextPlay() {
    final List episodes = [];
    bool isPages = false;
    if (videoDetail.value.ugcSeason != null) {
      final UgcSeason ugcSeason = videoDetail.value.ugcSeason!;
      final List<SectionItem> sections = ugcSeason.sections!;
      for (int i = 0; i < sections.length; i++) {
        final List<EpisodeItem> episodesList = sections[i].episodes!;
        episodes.addAll(episodesList);
      }
    } else if (videoDetail.value.pages != null) {
      isPages = true;
      final List<Part> pages = videoDetail.value.pages!;
      episodes.addAll(pages);
    }
    final VideoDetailController videoDetailCtr =
        Get.find<VideoDetailController>(tag: heroTag);
    final PlayRepeat platRepeat = videoDetailCtr.plPlayerController.playRepeat;

    if (episodes.isEmpty) {
      if (platRepeat == PlayRepeat.autoPlayRelated) {
        return playRelated();
      }
      return false;
    }

    final int currentIndex =
        episodes.indexWhere((e) => e.cid == lastPlayCid.value);
    int nextIndex = currentIndex + 1;

    // 列表循环
    if (nextIndex >= episodes.length) {
      if (platRepeat == PlayRepeat.listCycle) {
        nextIndex = 0;
      } else if (platRepeat == PlayRepeat.autoPlayRelated) {
        return playRelated();
      } else {
        return false;
      }
    }
    final int cid = episodes[nextIndex].cid!;
    final String rBvid = isPages ? bvid : episodes[nextIndex].bvid;
    final int rAid = isPages ? IdUtils.bv2av(bvid) : episodes[nextIndex].aid!;
    changeSeasonOrbangu(null, rBvid, cid, rAid, null);
    return true;
  }

  bool playRelated() {
    late RelatedController relatedCtr;
    try {
      relatedCtr = Get.find<RelatedController>(tag: heroTag);
      if (relatedCtr.loadingState.value is Empty) {
        SmartDialog.showToast('暂无相关视频，停止连播');
        return false;
      }
    } catch (_) {
      relatedCtr = Get.put(RelatedController(), tag: heroTag);
      relatedCtr.queryData().then((value) {
        if (value['status']) {
          playRelated();
        }
      });
      return false;
    }

    final HotVideoItemModel videoItem =
        (relatedCtr.loadingState.value as Success).response[0];
    try {
      if (videoItem.cid != null) {
        Get.offNamed('/video?bvid=${videoItem.bvid}&cid=${videoItem.cid}',
            arguments: {'videoItem': videoItem, 'heroTag': heroTag});
        // changeSeasonOrbangu(videoItem.bvid, videoItem.cid, videoItem.aid);
      } else {
        SearchHttp.ab2c(aid: videoItem.aid, bvid: videoItem.bvid).then((cid) =>
            Get.offNamed('/video?bvid=${videoItem.bvid}&cid=${videoItem.cid}',
                arguments: {'videoItem': videoItem, 'heroTag': heroTag}));
      }
    } catch (err) {
      SmartDialog.showToast(err.toString());
    }
    return true;
  }

  // 设置关注分组
  void setFollowGroup() {
    Get.bottomSheet(
      GroupPanel(mid: videoDetail.value.owner!.mid!),
      isScrollControlled: true,
    );
  }

  // ai总结
  Future aiConclusion() async {
    SmartDialog.showLoading(msg: '正在生产ai总结');
    final res = await VideoHttp.aiConclusion(
      bvid: bvid,
      cid: lastPlayCid.value,
      upMid: videoDetail.value.owner?.mid,
    );
    SmartDialog.dismiss();
    if (res['status']) {
      modelResult = res['data'].modelResult;
    } else {
      SmartDialog.showToast("当前视频可能暂不支持AI视频总结");
    }
    return res;
  }
}

class PayCoinsPage extends StatefulWidget {
  const PayCoinsPage({
    super.key,
    required this.callback,
    this.copyright = 1,
  });

  final Function callback;
  final int copyright;

  @override
  State<PayCoinsPage> createState() => _PayCoinsPageState();
}

class _PayCoinsPageState extends State<PayCoinsPage>
    with TickerProviderStateMixin {
  bool _isPaying = false;
  late final _controller = PageController(viewportFraction: 0.30);

  int get _index => _controller.hasClients ? _controller.page?.round() ?? 0 : 0;

  late AnimationController _slide22Controller;
  late AnimationController _scale22Controller;
  late AnimationController _coinSlideController;
  late AnimationController _coinFadeController;
  late AnimationController _boxAnimController;

  final List _images = [
    'assets/images/paycoins/ic_thunder_1.png',
    'assets/images/paycoins/ic_thunder_2.png',
    'assets/images/paycoins/ic_thunder_3.png',
  ];
  late int _imageIndex = -1;
  Timer? _timer;
  bool get _showThunder => _imageIndex != -1 && _imageIndex != _images.length;

  @override
  void initState() {
    super.initState();
    _slide22Controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 50),
    );
    _scale22Controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 50),
    );
    _coinSlideController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 200),
    );
    _coinFadeController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 100),
    );
    _boxAnimController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 50),
    );
    _scale();
  }

  @override
  void dispose() {
    _timer?.cancel();
    _slide22Controller.dispose();
    _scale22Controller.dispose();
    _coinSlideController.dispose();
    _coinFadeController.dispose();
    _boxAnimController.dispose();
    _controller.dispose();
    super.dispose();
  }

  void _scale() {
    _scale22Controller.forward().whenComplete(() {
      _scale22Controller.reverse();
    });
  }

  void _onScroll(int index) {
    _controller.animateToPage(
      index,
      duration: const Duration(milliseconds: 200),
      curve: Curves.ease,
    );
    _scale();
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (_, constraints) {
      return _buildBody(constraints.maxHeight > constraints.maxWidth);
    });
  }

  Widget _buildBody(isV) => Stack(
        alignment: Alignment.center,
        children: [
          Visibility(
            visible: _showThunder,
            maintainSize: true,
            maintainAnimation: true,
            maintainState: true,
            child: Image.asset(_images[_showThunder ? _imageIndex : 0]),
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              Row(
                children: [
                  Visibility(
                    visible: !_isPaying && widget.copyright == 1,
                    maintainSize: true,
                    maintainAnimation: true,
                    maintainState: true,
                    child: GestureDetector(
                      onTap: _index == 0
                          ? null
                          : () {
                              _onScroll(0);
                            },
                      child: Padding(
                        padding: const EdgeInsets.only(left: 12),
                        child: Image.asset(
                          width: 16,
                          height: 28,
                          _index == 0
                              ? 'assets/images/paycoins/ic_left_disable.png'
                              : 'assets/images/paycoins/ic_left.png',
                        ),
                      ),
                    ),
                  ),
                  Expanded(
                    child: SizedBox(
                      height: 100,
                      child: PageView.builder(
                        itemCount: widget.copyright == 1 ? 2 : 1,
                        controller: _controller,
                        onPageChanged: (index) => setState(() {
                          _scale();
                        }),
                        itemBuilder: (context, index) {
                          return ListenableBuilder(
                            listenable: _controller,
                            builder: (context, child) {
                              double factor = index == 0 ? 1 : 0;
                              if (_controller.position.hasContentDimensions) {
                                factor = 1 - (_controller.page! - index).abs();
                              }
                              return Visibility(
                                visible: !_isPaying || _index == index,
                                child: Center(
                                  child: SizedBox(
                                    height: 70 + (factor * 30),
                                    width: 70 + (factor * 30),
                                    child: Stack(
                                      alignment: Alignment.center,
                                      children: [
                                        SlideTransition(
                                          position: _boxAnimController.drive(
                                            Tween(
                                              begin: const Offset(0.0, 0.0),
                                              end: const Offset(0.0, -0.2),
                                            ),
                                          ),
                                          child: Image.asset(
                                            'assets/images/paycoins/ic_pay_coins_box.png',
                                          ),
                                        ),
                                        SlideTransition(
                                          position: _coinSlideController.drive(
                                            Tween(
                                              begin: const Offset(0.0, 0.0),
                                              end: const Offset(0.0, -2),
                                            ),
                                          ),
                                          child: FadeTransition(
                                            opacity: Tween<double>(
                                                    begin: 1, end: 0)
                                                .animate(_coinFadeController),
                                            child: Image.asset(
                                              height: 35 + (factor * 15),
                                              width: 35 + (factor * 15),
                                              index == 0
                                                  ? 'assets/images/paycoins/ic_coins_one.png'
                                                  : 'assets/images/paycoins/ic_coins_two.png',
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ),
                              );
                            },
                          );
                        },
                      ),
                    ),
                  ),
                  Visibility(
                    visible: !_isPaying && widget.copyright == 1,
                    maintainSize: true,
                    maintainAnimation: true,
                    maintainState: true,
                    child: GestureDetector(
                      onTap: _index == 1
                          ? null
                          : () {
                              _onScroll(1);
                            },
                      child: Padding(
                        padding: const EdgeInsets.only(right: 12),
                        child: Image.asset(
                          width: 16,
                          height: 28,
                          _index == 1
                              ? 'assets/images/paycoins/ic_right_disable.png'
                              : 'assets/images/paycoins/ic_right.png',
                        ),
                      ),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 25),
              GestureDetector(
                behavior: HitTestBehavior.opaque,
                onPanUpdate: _handlePanUpdate,
                child: SizedBox(
                  width: double.infinity,
                  height: 140,
                  child: Center(
                    child: GestureDetector(
                      onTap: _onPayCoin,
                      onPanUpdate: (e) => _handlePanUpdate(e, true),
                      child: ScaleTransition(
                        scale: _scale22Controller.drive(
                          Tween(begin: 1, end: 1.2),
                        ),
                        child: SlideTransition(
                          position: _slide22Controller.drive(
                            Tween(
                              begin: const Offset(0.0, 0.0),
                              end: const Offset(0.0, -0.2),
                            ),
                          ),
                          child: SizedBox(
                            width: 100,
                            height: 140,
                            child: Image.asset(
                              _index == 0
                                  ? 'assets/images/paycoins/ic_22_mario.png'
                                  : 'assets/images/paycoins/ic_22_gun_sister.png',
                            ),
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ),
              SizedBox(
                  height:
                      (isV ? 50 : 0) + MediaQuery.of(context).padding.bottom),
            ],
          ),
        ],
      );

  void _handlePanUpdate(DragUpdateDetails e, [bool needV = false]) {
    if (needV && e.delta.dy.abs() > max(2, e.delta.dx.abs())) {
      if (e.delta.dy < 0) {
        _onPayCoin();
      }
    } else if (widget.copyright == 1 &&
        e.delta.dx.abs() > max(2, e.delta.dy.abs())) {
      if (e.delta.dx > 0) {
        if (_index == 1) {
          _onScroll(0);
          setState(() {});
        }
      } else {
        if (_index == 0) {
          _onScroll(1);
          setState(() {});
        }
      }
    }
  }

  void _onPayCoin() {
    if (_isPaying) return;
    setState(() {
      _isPaying = true;
    });
    _slide22Controller.forward().whenComplete(() {
      _slide22Controller.reverse().whenComplete(() {
        if (_index == 1) {
          _timer ??= Timer.periodic(const Duration(milliseconds: 50 ~/ 3), (_) {
            if (_imageIndex != _images.length) {
              setState(() {
                _imageIndex = _imageIndex + 1;
              });
            } else {
              _timer?.cancel();
            }
          });
        }
        _boxAnimController.forward().whenComplete(() {
          _boxAnimController.reverse();
        });
        _coinSlideController.forward().whenComplete(() {
          _coinFadeController.forward().whenComplete(() {
            Get.back();
            widget.callback(_index + 1);
          });
        });
      });
    });
  }
}
