import 'dart:convert';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_app_group_directory/flutter_app_group_directory.dart';

import 'log/logger.dart';

class BoostLogger {
  static const String LOG_FOLDER = 'boost_logs';
  static const String APP_LOG_FILE = 'app.json';
  static const String CORE_LOG_FILE = 'core.json';
  static const String TAG = 'BoostLogger';

  Map<String, dynamic> _currentSession = {};
  String? _logPath;

  /// 单例模式实现
  static final BoostLogger _instance = BoostLogger._internal();
  factory BoostLogger() => _instance;
  BoostLogger._internal();

  /// 获取日志目录
  Future<Directory> _getLogDirectory() async {
    if (Platform.isAndroid) {
      final appDir = await getApplicationSupportDirectory();
      final logDir = Directory('${appDir.path}/$LOG_FOLDER');
      if (!await logDir.exists()) {
        await logDir.create(recursive: true);
      }
      return logDir;
    } else {
      try {
        // iOS 使用 App Group 目录
        final Directory? appGroupDirectory =
            await FlutterAppGroupDirectory.getAppGroupDirectory(
              'group.com.flashlink.vpn',
            );

        // 验证 App Group 目录是否有效
        if (appGroupDirectory != null) {
          final logDir = Directory('${appGroupDirectory.path}/$LOG_FOLDER');
          if (!await logDir.exists()) {
            await logDir.create(recursive: true);
          }
          return logDir;
        } else {
          // App Group 目录不可用，回退到应用文档目录
          log(
            TAG,
            'App Group directory not available, falling back to documents directory',
          );
          final appDir = await getApplicationDocumentsDirectory();
          final logDir = Directory('${appDir.path}/$LOG_FOLDER');
          if (!await logDir.exists()) {
            await logDir.create(recursive: true);
          }
          return logDir;
        }
      } catch (e) {
        // 如果 App Group 出现错误，回退到应用文档目录
        log(
          TAG,
          'Error with App Group directory: $e, falling back to documents directory',
        );
        final appDir = await getApplicationDocumentsDirectory();
        final logDir = Directory('${appDir.path}/$LOG_FOLDER');
        if (!await logDir.exists()) {
          await logDir.create(recursive: true);
        }
        return logDir;
      }
    }
  }

  /// 初始化日志系统
  Future<void> init() async {
    try {
      final logDir = await _getLogDirectory();
      _logPath = logDir.path;

      // 清除旧的app日志文件
      final appFile = File('${logDir.path}/$APP_LOG_FILE');
      if (await appFile.exists()) {
        await appFile.delete();
      }

      // 清除旧的内核日志文件
      final coreFile = File('${logDir.path}/$CORE_LOG_FILE');
      if (await coreFile.exists()) {
        await coreFile.delete();
      }

      // 初始化空的会话数据
      _currentSession = {};
      await _saveSession();
    } catch (e) {
      log(TAG, 'BoostLogger init error: $e');
    }
  }

  //读取历史日志
  Future<void> readHistoryLog() async {
    try {
      final logDir = await _getLogDirectory();
      _logPath = logDir.path;

      getCurrentSession();
    } catch (e) {
      log(TAG, 'BoostLogger readHistoryLog error: $e');
    }
  }

  /// 设置整个部分的数据
  Future<void> setSection(String section, Map<String, dynamic> data) async {
    try {
      _currentSession[section] = data;
      await _saveSession();
    } catch (e) {
      log(TAG, 'BoostLogger setSection error: $e');
    }
  }

  /// 设置整个部分的数据
  Future<void> setSectionObj(String section, dynamic data) async {
    try {
      _currentSession[section] = data;
      await _saveSession();
    } catch (e) {
      log(TAG, 'BoostLogger setSectionObj error: $e');
    }
  }

  /// 更新部分中的特定字段
  Future<void> updateField(String section, String field, dynamic value) async {
    try {
      final sectionData = _currentSession[section] as Map<String, dynamic>;
      sectionData[field] = value;
      _currentSession[section] = sectionData;

      await _saveSession();
    } catch (e) {
      log(TAG, 'BoostLogger updateField error: $e');
    }
  }

  /// 向数组添加数据
  Future<void> appendToArray(
    String section,
    String arrayField,
    Map<String, dynamic> data,
  ) async {
    try {
      final sectionData =
          _currentSession[section] as Map<String, dynamic>? ?? {};
      final array = sectionData[arrayField] as List<dynamic>? ?? [];
      array.add(data);
      sectionData[arrayField] = array;
      _currentSession[section] = sectionData;
      await _saveSession();
    } catch (e) {
      log(TAG, 'BoostLogger appendToArray error: $e');
    }
  }

  /// 保存会话数据到文件
  Future<void> _saveSession() async {
    if (_logPath == null) return;

    try {
      final file = File('$_logPath/$APP_LOG_FILE');
      // 使用 writeAsStringSync 确保写入完成
      final jsonString = const JsonEncoder.withIndent(
        '  ',
      ).convert(_currentSession);
      await file.writeAsString(jsonString, flush: true);

      // 验证文件写入
      final content = await file.readAsString();
      final savedData = jsonDecode(content) as Map<String, dynamic>;
      log(TAG, 'BoostLogger verify saved data: $savedData');
    } catch (e) {
      log(TAG, 'BoostLogger save session error: $e');
    }
  }

  /// 获取当前会话数据
  Map<String, dynamic> getCurrentSession() {
    try {
      // 从文件读取最新数据
      final file = File('$_logPath/$APP_LOG_FILE');
      if (file.existsSync()) {
        final content = file.readAsStringSync();
        _currentSession = jsonDecode(content) as Map<String, dynamic>;
      }
      return Map<String, dynamic>.from(_currentSession);
    } catch (e) {
      log(TAG, 'BoostLogger getCurrentSession error: $e');
      return {};
    }
  }

  /// 获取日志文件路径
  Future<String?> getAppLogFilePath() async {
    return _logPath != null ? '$_logPath/$APP_LOG_FILE' : null;
  }

  /// 获取核心日志文件路径
  Future<String?> getCoreLogFilePath() async {
    return _logPath != null ? '$_logPath/$CORE_LOG_FILE' : null;
  }

  /// 清理资源
  Future<void> release() async {
    try {
      // 检查 _currentSession 是否为空
      if (_currentSession.isEmpty) {
        return;
      }
      await _saveSession();
      _currentSession.clear();
    } catch (e) {
      log(TAG, 'BoostLogger release error: $e');
    }
  }
}
