import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:uuid/uuid.dart';

import '../app/api/core/api_core_paths.dart';
import '../app/constants/configs.dart';
import '../app/constants/enums.dart';
import '../app/data/sp/ix_sp.dart';
import 'log/logger.dart';

/// API请求统计记录
class ApiStatRecord {
  final String id;
  final String domain;
  final String path;
  final bool success;
  final int errorCode;
  final String errorMessage;
  final int apiRequestTime;
  final int apiResponseTime;

  ApiStatRecord({
    required this.id,
    required this.domain,
    required this.path,
    required this.success,
    required this.errorCode,
    required this.errorMessage,
    required this.apiRequestTime,
    required this.apiResponseTime,
  });

  /// 从JSON创建
  factory ApiStatRecord.fromJson(Map<String, dynamic> json) {
    return ApiStatRecord(
      id: json['id'] ?? '',
      domain: json['domain'] ?? '',
      path: json['path'] ?? '',
      success: json['success'] ?? false,
      errorCode: json['errorCode'] ?? 0,
      errorMessage: json['errorMessage'] ?? '',
      apiRequestTime: json['apiRequestTime'] ?? 0,
      apiResponseTime: json['apiResponseTime'] ?? 0,
    );
  }

  /// 转换为JSON
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'domain': domain,
      'path': path,
      'success': success,
      'errorCode': errorCode,
      'errorMessage': errorMessage,
      'apiRequestTime': apiRequestTime,
      'apiResponseTime': apiResponseTime,
    };
  }

  @override
  String toString() {
    return jsonEncode(toJson());
  }
}

/// API统计管理器
///
/// 功能：
/// - 记录 API 请求的成功/失败统计
/// - 最大保存 100 条记录（FIFO）
/// - 支持文件持久化存储
/// - 批量写入优化（每 10 条）
class ApiStatistics {
  // 单例模式
  static final ApiStatistics _instance = ApiStatistics._internal();
  factory ApiStatistics() => _instance;
  ApiStatistics._internal();

  static ApiStatistics get instance => _instance;

  static const String TAG = 'ApiStatistics';

  // 最大保存记录数
  static const int maxRecords = 100;

  // 批量写入阈值
  static const int _batchWriteThreshold = 10;

  // 文件名
  static const String _fileName = 'api_statistics.json';

  // 使用Queue来保持FIFO顺序
  final Queue<ApiStatRecord> _records = Queue<ApiStatRecord>();

  // UUID生成器
  final Uuid _uuid = const Uuid();

  // 操作锁，防止在遍历时修改
  bool _isOperating = false;

  // 是否已初始化
  bool _isInitialized = false;

  // 未保存的记录数
  int _unsavedCount = 0;

  // 是否正在写入文件
  bool _isWriting = false;

  // 文件路径缓存
  String? _filePath;

  // 禁用的日志模块缓存
  Set<String> _disabledModules = {};

  /// 初始化（需要在 App 启动时调用）
  Future<void> initialize() async {
    if (_isInitialized) return;

    try {
      // 获取文件路径
      _filePath = await _getFilePath();

      // 从文件加载数据
      await _loadFromFile();

      _isInitialized = true;
      log(TAG, 'ApiStatistics initialized, loaded ${_records.length} records');
    } catch (e) {
      log(TAG, 'ApiStatistics initialize error: $e');
    }
  }

  /// 更新禁用模块列表（在 launch 数据更新后调用）
  void updateDisabledModules() {
    try {
      final launch = IXSP.getLaunch();
      _disabledModules = (launch?.appConfig?.disabledLogModules ?? []).toSet();
      log(TAG, 'ApiStatistics disabled modules updated: $_disabledModules');
    } catch (e) {
      log(TAG, 'ApiStatistics updateDisabledModules error: $e');
    }
  }

  /// 检查模块是否被禁用
  bool _isModuleDisabled(String path) {
    var moduleName = LogModule.NM_ApiOtherLog.name;
    if (path == ApiCorePaths.launch) {
      moduleName = LogModule.NM_ApiLaunchLog.name;
    } else if (path == ApiCorePaths.getDispatchInfo) {
      moduleName = LogModule.NM_ApiRouterLog.name;
    }
    return _disabledModules.contains(moduleName);
  }

  /// 获取文件路径
  Future<String> _getFilePath() async {
    if (_filePath != null) return _filePath!;
    final directory = await getApplicationDocumentsDirectory();
    _filePath = '${directory.path}/$_fileName';
    return _filePath!;
  }

  /// 从文件加载数据
  Future<void> _loadFromFile() async {
    try {
      final filePath = await _getFilePath();
      final file = File(filePath);

      if (!await file.exists()) {
        log(TAG, 'ApiStatistics file not exists, skip loading');
        return;
      }

      final content = await file.readAsString();
      if (content.isEmpty) return;

      final List<dynamic> jsonList = jsonDecode(content);
      _records.clear();

      for (final json in jsonList) {
        if (json is Map<String, dynamic>) {
          _records.addLast(ApiStatRecord.fromJson(json));
        }
      }

      // 确保不超过最大数量
      while (_records.length > maxRecords) {
        _records.removeFirst();
      }

      log(TAG, 'ApiStatistics loaded ${_records.length} records from file');
    } catch (e) {
      log(TAG, 'ApiStatistics load error: $e');
    }
  }

  /// 保存到文件
  Future<void> _saveToFile() async {
    if (_isWriting) return;
    if (_unsavedCount == 0) return;

    _isWriting = true;
    try {
      // 更新禁用模块列表
      updateDisabledModules();

      final filePath = await _getFilePath();
      final file = File(filePath);

      // 过滤掉被禁用模块的记录
      _filterDisabledRecords();

      // 获取记录副本
      final records = getRecordsJson();

      // 写入文件
      await file.writeAsString(jsonEncode(records));

      _unsavedCount = 0;
      log(TAG, 'ApiStatistics saved ${records.length} records to file');
    } catch (e) {
      log(TAG, 'ApiStatistics save error: $e');
    } finally {
      _isWriting = false;
    }
  }

  /// 过滤掉被禁用模块的记录
  void _filterDisabledRecords() {
    if (_disabledModules.isEmpty) return;

    final toRemove = <ApiStatRecord>[];
    for (final record in _records) {
      if (_isModuleDisabled(record.path)) {
        toRemove.add(record);
      }
    }

    for (final record in toRemove) {
      _records.remove(record);
    }

    if (toRemove.isNotEmpty) {
      log(
        TAG,
        'ApiStatistics filtered out ${toRemove.length} disabled module records',
      );
    }
  }

  /// 检查是否需要保存
  void _checkAndSave() {
    if (_unsavedCount >= _batchWriteThreshold) {
      _saveToFile();
    }
  }

  /// 添加一条成功记录
  void addSuccess({
    required String domain,
    required String path,
    required int apiRequestTime,
    required int apiResponseTime,
    int errorCode = 200,
  }) {
    _addRecord(
      domain: domain,
      path: path,
      success: true,
      errorCode: errorCode,
      errorMessage: '',
      apiRequestTime: apiRequestTime,
      apiResponseTime: apiResponseTime,
    );
  }

  /// 添加一条失败记录
  void addFailure({
    required String domain,
    required String path,
    required int apiRequestTime,
    required int apiResponseTime,
    required int errorCode,
    required String errorMessage,
  }) {
    _addRecord(
      domain: domain,
      path: path,
      success: false,
      errorCode: errorCode,
      errorMessage: errorMessage,
      apiRequestTime: apiRequestTime,
      apiResponseTime: apiResponseTime,
    );
  }

  /// 内部添加记录方法（同步，线程安全）
  void _addRecord({
    required String domain,
    required String path,
    required bool success,
    required int errorCode,
    required String errorMessage,
    required int apiRequestTime,
    required int apiResponseTime,
  }) {
    // 如果正在进行其他操作，延迟添加
    if (_isOperating) {
      scheduleMicrotask(
        () => _addRecord(
          domain: domain,
          path: path,
          success: success,
          errorCode: errorCode,
          errorMessage: errorMessage,
          apiRequestTime: apiRequestTime,
          apiResponseTime: apiResponseTime,
        ),
      );
      return;
    }

    final record = ApiStatRecord(
      id: _uuid.v4(),
      domain: domain,
      path: path,
      success: success,
      errorCode: errorCode,
      errorMessage: errorMessage,
      apiRequestTime: apiRequestTime,
      apiResponseTime: apiResponseTime,
    );

    _records.addLast(record);
    _unsavedCount++;

    // 超出最大数量时，移除最早的记录
    while (_records.length > maxRecords) {
      _records.removeFirst();
    }

    // 检查是否需要保存
    _checkAndSave();
  }

  /// 获取所有记录（返回副本，避免并发修改问题）
  List<ApiStatRecord> getRecords() {
    _isOperating = true;
    try {
      return List<ApiStatRecord>.from(_records);
    } finally {
      _isOperating = false;
    }
  }

  /// 获取所有记录的JSON列表（返回副本）
  List<Map<String, dynamic>> getRecordsJson() {
    _isOperating = true;
    try {
      return _records.map((r) => r.toJson()).toList();
    } finally {
      _isOperating = false;
    }
  }

  /// 获取所有记录的JSON字符串
  String getRecordsJsonString({bool pretty = false}) {
    final json = getRecordsJson();
    if (pretty) {
      return const JsonEncoder.withIndent('  ').convert(json);
    }
    return jsonEncode(json);
  }

  /// 获取成功记录数
  int get successCount {
    final records = getRecords();
    return records.where((r) => r.success).length;
  }

  /// 获取失败记录数
  int get failureCount {
    final records = getRecords();
    return records.where((r) => !r.success).length;
  }

  /// 获取总记录数
  int get totalCount => _records.length;

  /// 获取成功率
  double get successRate {
    final total = totalCount;
    if (total == 0) return 0.0;
    return successCount / total;
  }

  /// 获取平均响应时间（毫秒）
  double get averageResponseTime {
    final records = getRecords();
    if (records.isEmpty) return 0.0;
    final totalTime = records.fold<int>(0, (sum, r) => sum + r.apiResponseTime);
    return totalTime / records.length;
  }

  /// 清空所有记录
  Future<void> clear() async {
    _isOperating = true;
    try {
      _records.clear();
      _unsavedCount = 0;
      // 清空文件
      await _saveToFile();
    } finally {
      _isOperating = false;
    }
  }

  /// 移除已上传的记录，保留上传过程中新增的记录
  Future<void> _removeUploadedRecords(
    List<ApiStatRecord> uploadedRecords,
  ) async {
    _isOperating = true;
    try {
      // 获取已上传记录的 ID 集合
      final uploadedIds = uploadedRecords.map((r) => r.id).toSet();
      // 移除已上传的记录
      _records.removeWhere((r) => uploadedIds.contains(r.id));
      _unsavedCount = _records.length;
      // 保存剩余记录到文件（包括上传过程中新增的记录）
      await _forceSaveToFile();
    } finally {
      _isOperating = false;
    }
  }

  /// 强制保存到文件（忽略 _unsavedCount 检查）
  Future<void> _forceSaveToFile() async {
    if (_isWriting) return;

    _isWriting = true;
    try {
      final filePath = await _getFilePath();
      final file = File(filePath);
      final records = _records.map((r) => r.toJson()).toList();
      await file.writeAsString(jsonEncode(records));
      _unsavedCount = 0;
      log(TAG, 'ApiStatistics force saved ${records.length} records to file');
    } catch (e) {
      log(TAG, 'ApiStatistics force save error: $e');
    } finally {
      _isWriting = false;
    }
  }

  /// 获取最近N条记录（返回副本）
  List<ApiStatRecord> getRecentRecords(int count) {
    final records = getRecords();
    if (count >= records.length) {
      return records;
    }
    return records.sublist(records.length - count);
  }

  /// 获取统计摘要
  Map<String, dynamic> getSummary() {
    final records = getRecords();
    final total = records.length;
    final success = records.where((r) => r.success).length;
    final failure = total - success;
    final rate = total > 0 ? success / total : 0.0;
    final avgTime = total > 0
        ? records.fold<int>(0, (sum, r) => sum + r.apiResponseTime) / total
        : 0.0;

    return {
      'totalCount': total,
      'successCount': success,
      'failureCount': failure,
      'successRate': '${(rate * 100).toStringAsFixed(2)}%',
      'averageResponseTime': '${avgTime.toStringAsFixed(2)}ms',
    };
  }

  /// 强制保存到文件（App 进入后台或退出时调用）
  Future<void> flush() async {
    await _saveToFile();
  }

  /// 释放资源（App 退出时调用）
  Future<void> dispose() async {
    await _saveToFile();
    _isInitialized = false;
  }

  /// App 进入后台时调用（不阻塞，fire-and-forget）
  void onAppPaused() {
    // 异步保存，不等待结果
    _saveToFile();
  }

  /// App 进入前台时调用（不阻塞，fire-and-forget）
  Future<List<Map<String, dynamic>>> onAppResumed() async {
    await _loadFromFile();
    return await _uploadAndClear();
  }

  /// 上传统计数据并清空
  Future<List<Map<String, dynamic>>> _uploadAndClear() async {
    try {
      // 先更新禁用模块列表
      updateDisabledModules();

      final records = getRecords();
      if (records.isEmpty) return [];

      // 检查模块是否禁用
      final isLaunchDisabled = _disabledModules.contains(
        LogModule.NM_ApiLaunchLog.name,
      );
      final isRouterDisabled = _disabledModules.contains(
        LogModule.NM_ApiRouterLog.name,
      );
      final isOtherDisabled = _disabledModules.contains(
        LogModule.NM_ApiOtherLog.name,
      );

      // 过滤掉禁用模块的记录
      final enabledRecords = records.where((record) {
        if (record.path == ApiCorePaths.launch) {
          return !isLaunchDisabled;
        } else if (record.path == ApiCorePaths.getDispatchInfo) {
          return !isRouterDisabled;
        } else {
          return !isOtherDisabled;
        }
      }).toList();
      // 移除已上传的记录，保留上传过程中新增的记录（如上传接口本身的记录）
      await _removeUploadedRecords(records);
      log(
        TAG,
        'ApiStatistics uploaded ${enabledRecords.length}/${records.length} records '
        '(launch disabled: $isLaunchDisabled, router disabled: $isRouterDisabled)',
      );
      // 合并上传（一次接口调用）
      if (enabledRecords.isNotEmpty) {
        final logs = _formatLogsForUpload(enabledRecords);
        log(TAG, 'ApiStatistics upload ${logs.length} records');
        return logs;
      }
      return [];
    } catch (e) {
      log(TAG, 'ApiStatistics upload error: $e');
      return [];
    }
  }

  /// 格式化日志数据用于上传
  List<Map<String, dynamic>> _formatLogsForUpload(List<ApiStatRecord> records) {
    return records.map((record) {
      var moduleName = LogModule.NM_ApiOtherLog.name;
      if (record.path == ApiCorePaths.launch) {
        moduleName = LogModule.NM_ApiLaunchLog.name;
      } else if (record.path == ApiCorePaths.getDispatchInfo) {
        moduleName = LogModule.NM_ApiRouterLog.name;
      }
      return {
        'id': record.id,
        'time': record.apiRequestTime,
        'level': LogLevel.info.name,
        'module': moduleName,
        'category': Configs.productCode,
        'fields': record.toJson(),
      };
    }).toList();
  }
}
