import 'dart:async';
import 'package:get/get.dart';

import 'package:kaer_with_panels/app/model/response/kr_node_group_list.dart';

import 'package:kaer_with_panels/app/model/response/kr_user_available_subscribe.dart';
import 'package:kaer_with_panels/app/services/api_service/kr_subscribe_api.dart';
import 'package:kaer_with_panels/app/services/singbox_imp/kr_sing_box_imp.dart';
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';

import 'package:kaer_with_panels/app/utils/kr_common_util.dart';
import 'package:kaer_with_panels/app/localization/app_translations.dart';

import '../../singbox/model/singbox_status.dart';
import '../model/business/kr_group_outbound_list.dart';
import '../model/business/kr_outbound_item.dart';
import '../model/business/kr_outbounds_list.dart';
import '../model/response/kr_already_subscribe.dart';

/// 首页列表视图状态枚举
enum KRSubscribeServiceStatus { kr_none, kr_loading, kr_error, kr_success }

/// 订阅服务类
/// 用于管理用户订阅相关的所有操作
class KRSubscribeService {
  /// 单例实例
  static final KRSubscribeService _instance = KRSubscribeService._internal();

  /// 工厂构造函数
  factory KRSubscribeService() => _instance;

  /// 私有构造函数
  KRSubscribeService._internal() {}

  /// 订阅API
  final KRSubscribeApi kr_subscribeApi = KRSubscribeApi();

  /// 可用订阅列表
  final RxList<KRUserAvailableSubscribeItem> kr_availableSubscribes =
      <KRUserAvailableSubscribeItem>[].obs;

  /// 当前选中的订阅
  final Rx<KRUserAvailableSubscribeItem?> kr_currentSubscribe =
      Rx<KRUserAvailableSubscribeItem?>(null);

  /// 节点分组列表
  final RxList<KRNodeGroupListItem> kr_nodeGroups = <KRNodeGroupListItem>[].obs;

  /// 服务器分组
  final RxList<KRGroupOutboundList> groupOutboundList =
      <KRGroupOutboundList>[].obs;

  /// 国家分组，包含所有国家
  final RxList<KRCountryOutboundList> countryOutboundList =
      <KRCountryOutboundList>[].obs;

  /// 全部列表
  final RxList<KROutboundItem> allList = <KROutboundItem>[].obs;

  /// 标签列表
  Map<String, KROutboundItem> keyList = {}; // 存储国家分组的列表

  /// 试用剩余时间
  final RxString kr_trialRemainingTime = ''.obs;

  /// 订阅剩余时间
  final RxString kr_subscriptionRemainingTime = ''.obs;

  /// 剩余时间
  final RxString remainingTime = ''.obs;

  /// 是否处于试用状态
  final RxBool kr_isTrial = false.obs;

  /// 订阅记录
  final RxList<KRAlreadySubscribe> kr_alreadySubscribe =
      <KRAlreadySubscribe>[].obs;

  /// 是否处于订阅最后一天
  final RxBool kr_isLastDayOfSubscription = false.obs;

  /// 定期更新计时器
  Timer? _kr_updateTimer;

  /// 试用倒计时计时器
  Timer? _kr_trialTimer;

  /// 订阅倒计时计时器
  Timer? _kr_subscriptionTimer;

  /// 当前状态
  final kr_currentStatus = KRSubscribeServiceStatus.kr_none.obs;

  /// 重置订阅周期
  Future<void> kr_resetSubscribePeriod() async {
    if (kr_currentSubscribe.value == null) {
      KRCommonUtil.kr_showToast('请先选择订阅');
      return;
    }

    final result = await kr_subscribeApi
        .kr_resetSubscribePeriod(kr_currentSubscribe.value!.id);
    result.fold(
      (error) {
        KRCommonUtil.kr_showToast(error.msg);
        KRLogUtil.kr_e('重置订阅周期失败: ${error.msg}', tag: 'SubscribeService');
      },
      (success) {
        kr_refreshAll();
        KRLogUtil.kr_i('重置订阅周期成功', tag: 'SubscribeService');
      },
    );
  }

  /// 获取可用订阅列表
  Future<void> _kr_fetchAvailableSubscribes() async {
    try {
      KRLogUtil.kr_i('开始获取可用订阅列表', tag: 'SubscribeService');

      final result = await kr_subscribeApi.kr_userAvailableSubscribe();

      result.fold(
        (error) {
          KRLogUtil.kr_e('获取可用订阅失败: ${error.msg}', tag: 'SubscribeService');
        },
        (subscribes) {
          // 如果当前有选中的订阅，检查是否还在可用列表中
          if (kr_currentSubscribe.value != null) {
            final currentSubscribeExists = subscribes.any(
              (subscribe) => subscribe.id == kr_currentSubscribe.value?.id,
            );

            // 如果当前订阅不在可用列表中，清除当前订阅
            if (!currentSubscribeExists) {
              // 如果当前订阅为null或者已过期，才设置新的订阅
              if (kr_currentSubscribe.value == null ||
                  DateTime.parse(kr_currentSubscribe.value!.expireTime)
                      .isBefore(DateTime.now())) {
                kr_availableSubscribes.assignAll(subscribes);
                if (subscribes.isNotEmpty) {
                  kr_currentSubscribe.value = subscribes.first;
                  KRLogUtil.kr_i('设置新的订阅: ${subscribes.first.name}',
                      tag: 'SubscribeService');
                } else {
                  kr_currentSubscribe.value = null;
                  KRLogUtil.kr_i('没有可用的订阅，清除选中状态', tag: 'SubscribeService');
                }
                kr_clearCutNodeData();
              } else {
                KRLogUtil.kr_i('当前订阅仍然有效，保持选中状态', tag: 'SubscribeService');
              }
            } else {
              // 如果当前订阅仍然有效，更新为最新的订阅信息
              final updatedSubscribe = subscribes.firstWhere(
                (subscribe) => subscribe.id == kr_currentSubscribe.value?.id,
              );

              // 检查订阅是否有效（未过期且未超出流量限制）
              final isExpired = DateTime.parse(updatedSubscribe.expireTime)
                  .isBefore(DateTime.now());
              final isOverTraffic = updatedSubscribe.traffic > 0 &&
                  (updatedSubscribe.download + updatedSubscribe.upload) >=
                      updatedSubscribe.traffic;

              if (isExpired || isOverTraffic) {
                if (KRSingBoxImp.instance.kr_status ==
                    SingboxStatus.started()) {
                  KRSingBoxImp.instance.kr_stop();
                }
              }

              kr_currentSubscribe.value = updatedSubscribe;
              KRLogUtil.kr_i('更新当前订阅信息', tag: 'SubscribeService');

              // 更新可用订阅列表
              kr_availableSubscribes.assignAll(subscribes);
            }
          }

          KRLogUtil.kr_i('获取可用订阅列表成功: ${subscribes.length} 个订阅',
              tag: 'SubscribeService');
          KRLogUtil.kr_i(
              '订阅列表: ${subscribes.map((s) => '${s.name}(${s.id})').join(', ')}',
              tag: 'SubscribeService');
        },
      );
    } catch (err) {
      KRLogUtil.kr_e('获取可用订阅异常: $err', tag: 'SubscribeService');
    }
  }

  /// 切换订阅
  Future<void> kr_switchSubscribe(
      KRUserAvailableSubscribeItem subscribe) async {
    // 如果切换的是当前订阅，直接返回
    if (subscribe.id == kr_currentSubscribe.value?.id) {
      KRLogUtil.kr_i('切换的订阅与当前订阅相同，无需切换', tag: 'SubscribeService');
      return;
    }

    try {
      kr_currentStatus.value = KRSubscribeServiceStatus.kr_loading;
      await kr_clearCutNodeData();
      KRLogUtil.kr_i('开始切换订阅: ${subscribe.name + subscribe.id.toString()}',
          tag: 'SubscribeService');

      // 更新当前订阅
      kr_currentSubscribe.value = subscribe;

      final result =
          await kr_subscribeApi.kr_nodeList(kr_currentSubscribe.value!.id);

      result.fold((error) {
        kr_currentStatus.value = KRSubscribeServiceStatus.kr_error;
      }, (nodes) {
        // 处理节点列表
        final listModel = KrOutboundsList();
        listModel.processOutboundItems(nodes.list, kr_nodeGroups);

        // 更新UI数据
        groupOutboundList.value = listModel.groupOutboundList;
        countryOutboundList.value = listModel.countryOutboundList;
        allList.value = listModel.allList;
        keyList = listModel.keyList;

        // 保存配置
        KRSingBoxImp.instance.kr_saveOutbounds(listModel.configJsonList);

        // 更新试用和订阅状态
        _kr_updateSubscribeStatus();
        kr_currentStatus.value = KRSubscribeServiceStatus.kr_success;
      });
    } catch (e) {
      kr_currentStatus.value = KRSubscribeServiceStatus.kr_error;
      KRLogUtil.kr_e('切换订阅失败: $e', tag: 'SubscribeService');
      rethrow;
    }
  }

  /// 更新订阅状态
  void _kr_updateSubscribeStatus() {
    // 停止之前的计时器
    _kr_trialTimer?.cancel();
    _kr_subscriptionTimer?.cancel();

    // 检查试用状态
    final bool kr_isSubscribed = kr_currentSubscribe.value != null &&
        kr_alreadySubscribe.any((subscribe) =>
            kr_currentSubscribe.value?.id == subscribe.userSubscribeId);

    KRLogUtil.kr_i('当前订阅状态: ${kr_isSubscribed ? "已订阅" : "未订阅"}',
        tag: 'SubscribeService');
    KRLogUtil.kr_i('当前订阅ID: ${kr_currentSubscribe.value?.id}',
        tag: 'SubscribeService');
    KRLogUtil.kr_i(
        '已订阅记录: ${kr_alreadySubscribe.map((s) => s.userSubscribeId).join(', ')}',
        tag: 'SubscribeService');

    // 设置试用状态
    kr_isTrial.value = kr_currentSubscribe.value != null && !kr_isSubscribed;

    KRLogUtil.kr_i('试用状态: ${kr_isTrial.value ? "是" : "否"}',
        tag: 'SubscribeService');

    if (kr_isTrial.value) {
      // 启动试用倒计时
      _kr_startTrialTimer();
    }
    // 检查订阅状态
    else if (kr_currentSubscribe.value != null) {
      final expireTime = DateTime.parse(kr_currentSubscribe.value!.expireTime);
      final now = DateTime.now();
      final difference = expireTime.difference(now);

      // 检查是否最后一天
      kr_isLastDayOfSubscription.value = difference.inDays <= 1;

      if (kr_isLastDayOfSubscription.value) {
        // 启动订阅倒计时
        _kr_startSubscriptionTimer();
        KRLogUtil.kr_i('当前订阅最后一天', tag: 'SubscribeService');
      }
    }
  }

  /// 启动试用倒计时
  void _kr_startTrialTimer() {
    _kr_trialTimer?.cancel();

    // 立即执行一次
    _kr_updateTrialTime();

    // 设置定时器
    _kr_trialTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      _kr_updateTrialTime();
    });
  }

  /// 更新试用时间
  void _kr_updateTrialTime() {
    if (kr_currentSubscribe.value == null) {
      _kr_trialTimer?.cancel();
      return;
    }

    final expireTime = DateTime.parse(kr_currentSubscribe.value!.expireTime);
    final now = DateTime.now();
    final difference = expireTime.difference(now);

    if (difference.isNegative) {
      /// 停止
      if (KRSingBoxImp.instance.kr_status == SingboxStatus.started()) {
        KRSingBoxImp.instance.kr_stop();
      }

      _kr_trialTimer?.cancel();
      kr_trialRemainingTime.value = 'error.60001'.tr;
      return;
    }

    final days = difference.inDays;
    final hours = difference.inHours % 24;
    final minutes = difference.inMinutes % 60;
    final seconds = difference.inSeconds % 60;

    kr_trialRemainingTime.value = AppTranslations.kr_home.trialTimeWithDays(
      days,
      hours,
      minutes,
      seconds,
    );
  }

  /// 启动订阅倒计时
  void _kr_startSubscriptionTimer() {
    _kr_subscriptionTimer?.cancel();

    // 立即执行一次
    _kr_updateSubscriptionTime();

    // 设置定时器
    _kr_subscriptionTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      _kr_updateSubscriptionTime();
    });
  }

  /// 更新订阅时间
  void _kr_updateSubscriptionTime() {
    if (kr_currentSubscribe.value == null) {
      _kr_subscriptionTimer?.cancel();
      return;
    }

    final expireTime = DateTime.parse(kr_currentSubscribe.value!.expireTime);
    final now = DateTime.now();
    final difference = expireTime.difference(now);

    if (difference.isNegative) {
      _kr_subscriptionTimer?.cancel();

      /// 停止
      if (KRSingBoxImp.instance.kr_status == SingboxStatus.started()) {
        KRSingBoxImp.instance.kr_stop();
      }

      kr_subscriptionRemainingTime.value = 'error.60001'.tr;
      ;
      return;
    }

    final days = difference.inDays;
    final hours = difference.inHours % 24;
    final minutes = difference.inMinutes % 60;
    final seconds = difference.inSeconds % 60;

    kr_subscriptionRemainingTime.value =
        AppTranslations.kr_home.trialTimeWithDays(
      days,
      hours,
      minutes,
      seconds,
    );
  }

  /// 启动定期更新
  void _kr_startPeriodicUpdate() {
    // 每5分钟更新一次可用订阅列表
    _kr_updateTimer = Timer.periodic(const Duration(seconds: 60), (timer) {
      _kr_fetchAvailableSubscribes();
    });
  }

  /// 刷新所有数据
  Future<void> kr_refreshAll() async {
    try {
      kr_currentStatus.value = KRSubscribeServiceStatus.kr_loading;
      await kr_clearData();
      KRLogUtil.kr_i('开始刷新所有数据', tag: 'SubscribeService');

      ///  数组有值 ，表示订阅过， 用于判断试用的
      final alreadySubscribeResult =
          await kr_subscribeApi.kr_getAlreadySubscribe();
      alreadySubscribeResult.fold(
        (error) {
          throw Exception('获取已订阅列表失败: ${error.msg}');
        },
        (subscribes) {
          kr_alreadySubscribe.value = subscribes;
          KRLogUtil.kr_i('订阅记录: ${subscribes.length} 个订阅',
              tag: 'SubscribeService');
        },
      );

      final result = await kr_subscribeApi.kr_nodeGroupList();
      result.fold(
        (error) {
          throw Exception('获取节点分组失败: ${error.msg}');
        },
        (groups) {
          kr_nodeGroups.value = groups;
        },
      );

      // 保存当前选中的订阅名称
      final currentSubscribeID = kr_currentSubscribe.value?.id;

      // 获取可用订阅列表
      final subscribeResult = await kr_subscribeApi.kr_userAvailableSubscribe();

      // 处理订阅列表结果
      final subscribes = await subscribeResult.fold(
        (error) {
          throw Exception('获取可用订阅失败: ${error.msg}');
        },
        (subscribes) => subscribes,
      );

      // 如果获取订阅列表失败，直接返回
      if (subscribes.isEmpty) {
        kr_currentStatus.value = KRSubscribeServiceStatus.kr_none;
        kr_availableSubscribes.clear();
        return;
      }

      // 更新订阅列表
      kr_availableSubscribes.assignAll(subscribes);

      KRLogUtil.kr_i('获取可用订阅列表成功: ${subscribes.length} 个订阅',
          tag: 'SubscribeService');

      // 如果之前的订阅名称在可用列表中，保持选中
      if (subscribes.isNotEmpty) {
        final previousSubscribe = subscribes.firstWhere(
          (subscribe) => subscribe.id == currentSubscribeID,
          orElse: () => subscribes.first,
        );

        if (previousSubscribe.id != currentSubscribeID) {
          kr_currentSubscribe.value = previousSubscribe;
          KRLogUtil.kr_i('切换订阅: ${previousSubscribe.name}',
              tag: 'SubscribeService');
        } else {
          kr_currentSubscribe.value = previousSubscribe;
        }

        // 获取节点列表
        final nodeResult =
            await kr_subscribeApi.kr_nodeList(kr_currentSubscribe.value!.id);

        // 处理节点列表结果
        final nodes = await nodeResult.fold(
          (error) {
            throw Exception('获取节点列表失败: ${error.msg}');
          },
          (nodes) => nodes,
        );

        // 处理节点列表
        final listModel = KrOutboundsList();
        listModel.processOutboundItems(nodes.list, kr_nodeGroups);

        // 更新UI数据
        groupOutboundList.value = listModel.groupOutboundList;
        countryOutboundList.value = listModel.countryOutboundList;
        allList.value = listModel.allList;
        keyList = listModel.keyList;

        // 保存配置
        KRSingBoxImp.instance.kr_saveOutbounds(listModel.configJsonList);
        // 更新试用和订阅状态
        _kr_updateSubscribeStatus();

        kr_currentStatus.value = KRSubscribeServiceStatus.kr_success;

        _kr_startPeriodicUpdate();
      } else {
        KRLogUtil.kr_w('没有可用的订阅', tag: 'SubscribeService');
        kr_currentStatus.value = KRSubscribeServiceStatus.kr_error;
        return;
      }
    } catch (err, stackTrace) {
      kr_currentStatus.value = KRSubscribeServiceStatus.kr_error;
      KRLogUtil.kr_e('刷新数据异常: $err\n$stackTrace', tag: 'SubscribeService');
    }
  }

  //// 清楚
  Future<void> kr_clearData() async {
    _kr_subscriptionTimer?.cancel();
    _kr_trialTimer?.cancel();
    _kr_updateTimer?.cancel();

    kr_availableSubscribes.clear();

    await kr_clearCutNodeData();
  }

  Future<void> kr_logout() async {
    kr_alreadySubscribe.clear();
    kr_nodeGroups.clear();
    kr_currentSubscribe.value = null;

    await kr_clearData();
  }

  Future<void> kr_clearCutNodeData() async {
    kr_isLastDayOfSubscription.value = false;
    kr_isTrial.value = false;

    kr_subscriptionRemainingTime.value = '';
    kr_trialRemainingTime.value = '';

    /// 停止
    if (KRSingBoxImp.instance.kr_status == SingboxStatus.started()) {
      await KRSingBoxImp.instance.kr_stop();
    }

    // 更新UI数据
    groupOutboundList.clear();
    countryOutboundList.clear();
    allList.clear();
    keyList.clear();

    // 保存配置
    KRSingBoxImp.instance.kr_saveOutbounds([]);
  }

  /// 获取当前订阅
  KRUserAvailableSubscribeItem? get kr_getCurrentSubscribe =>
      kr_currentSubscribe.value;
}
