import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:nomo/app/api/router/api_router.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../utils/crypto.dart';
import '../../utils/developer/ix_developer_tools.dart';
import '../../utils/log/logger.dart';
import '../api/core/api_core.dart';
import '../api/file/api_file.dart';
import '../api/log/api_log.dart';
import 'configs.dart';
import '../data/models/launch/launch.dart';
import 'keys.dart';

class ApiDomains {
  static final ApiDomains _instance = ApiDomains._internal();
  static ApiDomains get instance => _instance;

  factory ApiDomains() => _instance;

  ApiDomains._internal();

  // 常量定义
  static const String _STORAGE_API_URLS = 'api_urls';
  static const String _STORAGE_ROUTER_URLS = 'router_urls';
  static const String _STORAGE_LOG_URLS = 'log_urls';
  static const String _STORAGE_FILE_URLS = 'file_urls';
  static const String _STORAGE_BACKUP_URLS = 'backup_api_urls';
  static const String _STORAGE_API_URLS_INDEX = 'api_urls_index';
  static const String _STORAGE_ROUTER_URLS_INDEX = 'router_urls_index';
  static const String _STORAGE_LOG_URLS_INDEX = 'log_urls_index';
  static const String _STORAGE_FILE_URLS_INDEX = 'file_urls_index';
  static const String _STORAGE_IS_HARDCODED = 'is_hardcoded';
  static const int RETRY_COUNT_PER_LAUNCH = 2;

  final Dio dio = Dio(
    BaseOptions(
      connectTimeout: const Duration(seconds: 30),
      receiveTimeout: const Duration(seconds: 30),
      sendTimeout: const Duration(seconds: 30),
    ),
  );

  // 标记是否已经添加了监控拦截器
  bool _monitorInterceptorAdded = false;

  setProxy(String proxy) {
    dio.httpClientAdapter = IOHttpClientAdapter(
      createHttpClient: () {
        final client = HttpClient();
        client.findProxy = (uri) => proxy;
        client.badCertificateCallback =
            (X509Certificate cert, String host, int port) => true;
        return client;
      },
    );
  }

  // 默认API URL列表
  final List<String> _defaultApiUrls = [
    "https://d2aphju2iq7g2g.cloudfront.net",
    "https://api.turboaccel.website",
    "https://d1rvevafipy7o6.cloudfront.net",
    "https://api.speedboost.website",
    "https://dqmkongldmyxf.cloudfront.net",
    "https://api.fastforward.website",
    "https://d2cvqygi5xlqp3.cloudfront.net",
    "https://api.odyxighs.com",
    "https://service.fkey.club",
  ];

  // 默认Router URL列表
  final List<String> _defaultRouterUrls = [];

  // 默认LOG API URL列表
  final List<String> _defaultLogUrls = ['https://stat.fkey.win'];

  // 默认FILE API URL列表
  final List<String> _defaultFileUrls = [];

  // 默认备用URL列表（txt文件地址）
  final List<String> _defaultBackupApiUrls = [
    'https://drive.google.com/uc?export=download&id=1YMEZiAHPhlAg_xZqD7dSDt0WjlcogwVz',
    'https://fkey.win/.well-known/backup/backup_fk.data',
  ];

  // 当前使用的URL列表
  List<String> _apiUrls = [];

  // 当前使用的Router URL列表
  List<String> _routerUrls = [];

  // 当前使用的LogURL列表
  List<String> _logUrls = [];

  // 当前使用的FILE URL列表
  List<String> _fileUrls = [];

  // 当前使用的备用URL列表
  List<String> _backupApiUrls = [];

  // 当前尝试的索引
  int _currentIndex = 0;

  // 当前使用的Router URL索引
  int _currentRouterIndex = 0;

  // 当前使用的LogURL索引
  int _currentLogIndex = 0;

  // 当前使用的FILE URL索引
  int _currentFileIndex = 0;

  // 当前正在使用的备用列表索引
  int _currentBackupListIndex = 0;

  // 添加标志位，标识是否使用的是硬编码URL
  bool _isUsingHardcodedUrls = true;

  // 添加标志位，记录硬编码请求次数
  int _hardcodedRequestCount = 0;

  // 初始化方法
  Future<void> init() async {
    initUrls();
    // 尝试加载保存的URLs
    await _loadSavedUrls();
  }

  void initUrls() {
    if (Configs.debug) {
      _apiUrls = [
        // 'https://api.znomo.com', // 测试环境
        "https://nomo-api.clickto.dev", // 开发环境
      ];
      _routerUrls = [];
      _logUrls = [];
      _fileUrls = [];
      _backupApiUrls = [];
    } else {
      _apiUrls = List.from(_defaultApiUrls);
      _routerUrls = List.from(_defaultRouterUrls);
      _logUrls = List.from(_defaultLogUrls);
      _fileUrls = List.from(_defaultFileUrls);
      _backupApiUrls = List.from(_defaultBackupApiUrls);
    }
  }

  // 修改加载保存的URL方法，返回是否成功加载
  Future<void> _loadSavedUrls() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      _currentIndex = prefs.getInt(_STORAGE_API_URLS_INDEX) ?? 0;
      _currentRouterIndex = prefs.getInt(_STORAGE_ROUTER_URLS_INDEX) ?? 0;
      _currentLogIndex = prefs.getInt(_STORAGE_LOG_URLS_INDEX) ?? 0;
      _currentFileIndex = prefs.getInt(_STORAGE_FILE_URLS_INDEX) ?? 0;
      _isUsingHardcodedUrls = prefs.getBool(_STORAGE_IS_HARDCODED) ?? true;

      final savedApiUrls = prefs.getStringList(_STORAGE_API_URLS);
      final savedRouterUrls = prefs.getStringList(_STORAGE_ROUTER_URLS);
      final savedBackupUrls = prefs.getStringList(_STORAGE_BACKUP_URLS);

      final savedLogUrls = prefs.getStringList(_STORAGE_LOG_URLS);

      final savedFileUrls = prefs.getStringList(_STORAGE_FILE_URLS);

      if (savedApiUrls != null && savedApiUrls.isNotEmpty) {
        _apiUrls = savedApiUrls;
      }
      if (savedRouterUrls != null && savedRouterUrls.isNotEmpty) {
        _routerUrls = savedRouterUrls;
      }
      if (savedBackupUrls != null && savedBackupUrls.isNotEmpty) {
        _backupApiUrls = savedBackupUrls;
      }
      if (savedLogUrls != null && savedLogUrls.isNotEmpty) {
        _logUrls = savedLogUrls;
      }
      if (savedFileUrls != null && savedFileUrls.isNotEmpty) {
        _fileUrls = savedFileUrls;
      }
      log(
        'ApiDomains',
        'Loaded saved URLs: ${_apiUrls.length} APIs, ${_backupApiUrls.length} backups, ${_logUrls.length} logs, ${_fileUrls.length} files',
      );
    } catch (e) {
      log('ApiDomains', 'Error loading saved URLs: $e');
    }
  }

  Future<void> setApiUrls(List<String> urls) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setStringList(_STORAGE_API_URLS, urls);
      _currentIndex = 0;
      await prefs.setInt(_STORAGE_API_URLS_INDEX, _currentIndex);
      ApiCore().setbaseUrl(urls[_currentIndex]);
    } catch (e) {
      log('ApiDomains', 'Error saving URLs: $e');
    }
  }

  // 添加Router URL
  Future<void> addRouterUrls(List<String> urls) async {
    try {
      var routerList = List<String>.from(_routerUrls);
      routerList.insertAll(0, urls);
      _routerUrls = routerList.toSet().toList();
      await _saveRouterUrls();
    } catch (e) {
      log('ApiDomains', 'Error add Router URL: $e');
    }
  }

  // 添加logUrl
  Future<void> addLogUrls(List<String> urls) async {
    try {
      var logList = List<String>.from(_logUrls);
      logList.insertAll(0, urls);
      _logUrls = logList.toSet().toList();
      await _saveLogUrls();
    } catch (e) {
      log('ApiDomains', 'Error add Log URL: $e');
    }
  }

  // 添加fileUrl
  Future<void> addFileUrls(List<String> urls) async {
    try {
      var fileList = List<String>.from(_fileUrls);
      fileList.insertAll(0, urls);
      _fileUrls = fileList.toSet().toList();
      await _saveFileUrls();
    } catch (e) {
      log('ApiDomains', 'Error add File URL: $e');
    }
  }

  // 保存当前URL列表到持久化存储
  Future<void> _saveApiUrls() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setStringList(_STORAGE_API_URLS, _apiUrls);
      await prefs.setStringList(_STORAGE_BACKUP_URLS, _backupApiUrls);
    } catch (e) {
      log('ApiDomains', 'Error saving URLs: $e');
    }
  }

  // 保存当前Router URL列表到持久化存储
  Future<void> _saveRouterUrls() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setStringList(_STORAGE_ROUTER_URLS, _routerUrls);
    } catch (e) {
      log('ApiDomains', 'Error saving Router URLs: $e');
    }
  }

  // 保存当前LogURL列表到持久化存储
  Future<void> _saveLogUrls() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setStringList(_STORAGE_LOG_URLS, _logUrls);
    } catch (e) {
      log('ApiDomains', 'Error saving Log URLs: $e');
    }
  }

  // 保存当前FILE URL列表到持久化存储
  Future<void> _saveFileUrls() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setStringList(_STORAGE_FILE_URLS, _fileUrls);
    } catch (e) {
      log('ApiDomains', 'Error saving File URLs: $e');
    }
  }

  // 保存硬编码状态
  Future<void> _saveIsHardcodedUrls() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setBool(_STORAGE_IS_HARDCODED, _isUsingHardcodedUrls);
    } catch (e) {
      log('ApiDomains', 'Error saving is hardcoded URLs: $e');
    }
  }

  // 保存硬编码索引
  Future<void> _saveApiUrlsIndex() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setInt(_STORAGE_API_URLS_INDEX, _currentIndex);
    } catch (e) {
      log('ApiDomains', 'Error saving hardcoded index: $e');
    }
  }

  // 保存硬编码索引
  Future<void> _saveRouterUrlsIndex() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setInt(_STORAGE_ROUTER_URLS_INDEX, _currentRouterIndex);
    } catch (e) {
      log('ApiDomains', 'Error saving Router URLs index: $e');
    }
  }

  // 保存LogURL硬编码索引
  Future<void> _saveLogUrlsIndex() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setInt(_STORAGE_LOG_URLS_INDEX, _currentLogIndex);
    } catch (e) {
      log('ApiDomains', 'Error saving Log URLs index: $e');
    }
  }

  // 保存FILE URL硬编码索引
  Future<void> _saveFileUrlsIndex() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setInt(_STORAGE_FILE_URLS_INDEX, _currentFileIndex);
    } catch (e) {
      log('ApiDomains', 'Error saving File URLs index: $e');
    }
  }

  // 从Launch数据更新URL列表
  Future<void> updateFromLaunch(Launch launch) async {
    try {
      if (launch.appConfig?.apiUrls != null &&
          launch.appConfig!.apiUrls!.isNotEmpty) {
        _apiUrls = List<String>.from(launch.appConfig!.apiUrls!);

        // 如果ApiCore的baseUrl不在launch的apiUrls中，或者使用硬编码的url，则设置ApiCore的baseUrl为launch的apiUrls的第一个
        if (!_apiUrls.contains(ApiCore().baseUrl) || _isUsingHardcodedUrls) {
          ApiCore().setbaseUrl(_apiUrls[0]);
        }
        final baseUrl = ApiCore().baseUrl;
        _apiUrls.insert(0, baseUrl);
        _apiUrls = _apiUrls.toSet().toList();
        _currentIndex = 0;
        log('ApiDomains', 'Add ApiCore baseUrl to index 0: $baseUrl');
      }

      if (launch.appConfig?.routerApiUrls != null &&
          launch.appConfig!.routerApiUrls!.isNotEmpty) {
        _routerUrls = launch.appConfig!.routerApiUrls!;
        final baseUrl = _routerUrls[0];
        ApiRouter().setbaseUrl(baseUrl);
        _currentRouterIndex = 0;
        log('ApiDomains', 'Add Router baseUrl to index 0: $baseUrl');
      }

      if (launch.appConfig?.backupApiUrls != null &&
          launch.appConfig!.backupApiUrls!.isNotEmpty) {
        _backupApiUrls = launch.appConfig!.backupApiUrls!;
        _currentBackupListIndex = 0;
      }

      if (launch.appConfig?.appStatUrls != null &&
          launch.appConfig!.appStatUrls!.isNotEmpty) {
        _logUrls = launch.appConfig!.appStatUrls!;
        // 设置ApiLog的baseUrl为launch的appStatUrls的第一个
        final baseUrl = _logUrls[0];
        ApiLog().setbaseUrl(baseUrl);
        _currentLogIndex = 0;
        log('ApiDomains', 'Add ApiLog baseUrl to index 0: $baseUrl');
      }

      if (launch.appConfig?.logFileUploadUrls != null &&
          launch.appConfig!.logFileUploadUrls!.isNotEmpty) {
        _fileUrls = launch.appConfig!.logFileUploadUrls!;
        // 设置ApiFile的baseUrl为launch的logFileUploadUrls的第一个
        final baseUrl = _fileUrls[0];
        ApiFile().setbaseUrl(baseUrl);
        _currentFileIndex = 0;
        log('ApiDomains', 'Add ApiFile baseUrl to index 0: $baseUrl');
      }

      _isUsingHardcodedUrls = false;
      await _saveIsHardcodedUrls();
      await _saveApiUrls();
      await _saveApiUrlsIndex();
      await _saveRouterUrls();
      await _saveRouterUrlsIndex();
      await _saveLogUrls();
      await _saveLogUrlsIndex();
      await _saveFileUrls();
      await _saveFileUrlsIndex();
      log('ApiDomains', 'Updated URLs from launch data');
    } catch (e) {
      log('ApiDomains', 'Error updating URLs from launch data: $e');
    }
  }

  // 获取当前ApiURL
  String getApiUrl() {
    if (_currentIndex >= _apiUrls.length) {
      _currentIndex = 0;
    }
    return _apiUrls[_currentIndex];
  }

  // 获取当前Router URL
  String getRouterUrl() {
    if (_currentRouterIndex >= _routerUrls.length) {
      _currentRouterIndex = 0;
    }
    return _routerUrls[_currentRouterIndex];
  }

  // 获取当前LogURL
  String getLogUrl() {
    if (_currentLogIndex >= _logUrls.length) {
      _currentLogIndex = 0;
    }
    return _logUrls[_currentLogIndex];
  }

  // 获取当前FILE URL
  String getFileUrl() {
    if (_currentFileIndex >= _fileUrls.length) {
      _currentFileIndex = 0;
    }
    return _fileUrls[_currentFileIndex];
  }

  Future<bool> isHardcodedUrls() async {
    return _isUsingHardcodedUrls;
  }

  // 获取下一次要尝试的URL
  Future<String> getNextApiUrl() async {
    // 使用硬编码URLs的情况
    if (_isUsingHardcodedUrls) {
      // 如果硬编码请求次数大于等于最大重试次数，返回空字符串
      if (_hardcodedRequestCount >= RETRY_COUNT_PER_LAUNCH) {
        _hardcodedRequestCount = 0;
        return '';
      }
      // 获取下一个索引
      int nextIndex = _currentIndex + 1;
      if (nextIndex >= _apiUrls.length) {
        if (_hardcodedRequestCount < RETRY_COUNT_PER_LAUNCH) {
          final isSuccess = await _switchToBackupList();
          if (isSuccess) {
            return getApiUrl();
          } else {
            _hardcodedRequestCount = 0;
            return '';
          }
        }
        return '';
      }
      final url = _apiUrls[nextIndex];
      _currentIndex++;
      _hardcodedRequestCount++;
      await _saveApiUrlsIndex();
      return url;
    }
    // 使用Launch数据的情况
    else {
      // 如果当前列表已用完
      int nextIndex = _currentIndex + 1;
      if (nextIndex >= _apiUrls.length) {
        // 尝试切换到备用列表
        final isSuccess = await _switchToBackupList();
        if (isSuccess) {
          return getApiUrl();
        } else {
          return '';
        }
      }

      // 返回当前URL
      final url = _apiUrls[nextIndex];
      _currentIndex++;
      await _saveApiUrlsIndex();
      return url;
    }
  }

  // 获取下一次要尝试的Router URL
  Future<String> getNextRouterUrl() async {
    // 获取下一个索引
    int nextIndex = _currentRouterIndex + 1;
    if (nextIndex >= _routerUrls.length) {
      _currentRouterIndex = 0;
      await _saveRouterUrlsIndex();
      return '';
    }

    // 返回所有剩余的URL
    final url = _routerUrls[nextIndex];
    _currentRouterIndex++;
    await _saveRouterUrlsIndex();
    return url;
  }

  // 获取下一次要尝试的LogURL
  Future<String> getNextLogUrl() async {
    // 获取下一个索引
    int nextIndex = _currentLogIndex + 1;
    if (nextIndex >= _logUrls.length) {
      _currentLogIndex = 0;
      await _saveLogUrlsIndex();
      return '';
    }

    // 返回所有剩余的URL
    final url = _logUrls[nextIndex];
    _currentLogIndex++;
    await _saveLogUrlsIndex();
    return url;
  }

  // 获取下一次要尝试的FILE URL
  Future<String> getNextFileUrl() async {
    // 获取下一个索引
    int nextIndex = _currentFileIndex + 1;
    if (nextIndex >= _fileUrls.length) {
      _currentFileIndex = 0;
      await _saveFileUrlsIndex();
      return '';
    }

    // 返回所有剩余的URL
    final url = _fileUrls[nextIndex];
    _currentFileIndex++;
    await _saveFileUrlsIndex();
    return url;
  }

  // 切换到备用列表
  Future<bool> _switchToBackupList() async {
    while (_currentBackupListIndex < _backupApiUrls.length) {
      try {
        if (_currentBackupListIndex >= _backupApiUrls.length) {
          log('ApiDomains', 'Error: Backup URL index out of bounds');
          break;
        }
        final backupUrl = _backupApiUrls[_currentBackupListIndex];
        log('ApiDomains', 'Trying backup URL: $backupUrl');

        // 添加talker日志（避免重复添加）
        if (!_monitorInterceptorAdded) {
          dio.interceptors.add(SimpleNoSignApiMonitorInterceptor());
          _monitorInterceptorAdded = true;
        }
        final response = await dio.get(backupUrl);
        if (response.statusCode == 200) {
          log('Before decryption: ${response.data}');
          final decryptedBytes = Crypto.decryptBytes(
            response.data.toString().trim(),
            Keys.aesKey,
            Keys.aesIv,
          );
          final jsonText = utf8.decode(decryptedBytes);
          log('Decryption results: $jsonText');
          final Map<String, dynamic> map = jsonDecode(jsonText);
          if (map['apiUrls'] != null) {
            final list = List<String>.from(map['apiUrls']);
            _apiUrls = list;
            _currentIndex = 0;
            // 当前备用文件成功，标志可以尝试下一个
            _currentBackupListIndex++;
            await _saveApiUrls();
            await _saveApiUrlsIndex();

            log('ApiDomains', 'Switched to backup list: ${list.length} URLs');
            return true;
          }
        }
        // 当前备用文件失败，尝试下一个
        _currentBackupListIndex++;
      } catch (e) {
        log('ApiDomains', 'Error switching to backup list: $e');
        _currentBackupListIndex++;
      }
    }

    // 如果所有备用URL都失败了，重置为硬编码模式
    _isUsingHardcodedUrls = true;
    _currentIndex = 0;
    _currentBackupListIndex = 0;
    initUrls();
    await _saveIsHardcodedUrls();
    await _saveApiUrls();
    await _saveApiUrlsIndex();
    return false;
  }
}
