import 'dart:async';
import 'dart:math';
import 'package:uuid/uuid.dart';
import 'package:flutter/material.dart';
import 'models/telemetry_event.dart';
import 'models/device_context.dart';
import 'models/telemetry_config.dart';
import 'collectors/device_info_collector.dart';
import 'storage/telemetry_storage.dart';
import 'uploader/telemetry_uploader.dart';
import 'session/session_manager.dart';
import 'presence/heartbeat_service.dart';
import 'presence/presence_config.dart';

/// 遥测服务
/// 统一管理设备信息收集、事件记录、上传等功能
class TelemetryService {
  static TelemetryService? _instance;
  TelemetryService._();

  factory TelemetryService() {
    _instance ??= TelemetryService._();
    return _instance!;
  }

  final _storage = TelemetryStorage();
  late TelemetryUploader _uploader;

  DeviceContext? _deviceContext;

  /// 安装ID（设备唯一标识，首次安装生成，用于未登录用户的DAU去重）
  late String _installId;
  String get installId => _installId;

  /// 用户ID（登录后设置）
  String? _userId;
  String? get userId => _userId;

  /// 访问令牌（登录后缓存，用于心跳/上传认证头）
  String? _accessToken;

  /// API 基础地址
  late String _apiBaseUrl;

  bool _isInitialized = false;
  bool get isInitialized => _isInitialized;

  /// 会话管理器
  late SessionManager _sessionManager;

  /// 心跳服务
  late HeartbeatService _heartbeatService;

  Timer? _configSyncTimer;

  /// 初始化(在main.dart中调用)
  Future<void> initialize({
    required String apiBaseUrl,
    required BuildContext context,
    String? userId,
    Duration configSyncInterval = const Duration(hours: 1),
    PresenceConfig? presenceConfig,
  }) async {
    if (_isInitialized) return;

    _apiBaseUrl = apiBaseUrl;

    // 1. 初始化存储
    await _storage.init();

    // 2. 初始化或获取 installId
    await _initInstallId();

    // 3. 加载用户选择
    await TelemetryConfig().loadUserOptIn();

    // 4. 同步远程配置（非阻塞，后台执行）
    // 不阻塞启动流程，使用本地缓存的配置先启动
    TelemetryConfig().syncFromRemote(apiBaseUrl).catchError((e) {
      debugPrint('📊 [Telemetry] Remote config sync failed (non-blocking): $e');
    });

    // 5. 收集设备信息
    _deviceContext = await DeviceInfoCollector().collect(context);
    await _storage.saveDeviceContext(_deviceContext!.toJson());

    // 6. 设置用户ID
    _userId = userId;

    // 7. 初始化上传器
    _uploader = TelemetryUploader(
      apiBaseUrl: apiBaseUrl,
      storage: _storage,
      getAuthHeaders: _getAuthHeaders,
    );

    // 8. 启动定时上传（如果启用）
    if (TelemetryConfig().globalEnabled) {
      _uploader.startPeriodicUpload();
    }

    // 9. 定期同步配置
    _configSyncTimer = Timer.periodic(configSyncInterval, (_) async {
      await TelemetryConfig().syncFromRemote(apiBaseUrl);

      // 根据最新配置调整上传器状态
      if (TelemetryConfig().globalEnabled) {
        _uploader.startPeriodicUpload();
      } else {
        _uploader.stopPeriodicUpload();
      }

      // 更新心跳配置
      if (TelemetryConfig().presenceConfig != null) {
        _heartbeatService.updateConfig(TelemetryConfig().presenceConfig!);
      }
    });

    // 10. 初始化会话管理器
    _sessionManager = SessionManager();
    _sessionManager.initialize(this);

    // 11. 初始化心跳服务
    _heartbeatService = HeartbeatService();
    _heartbeatService.initialize(
      apiBaseUrl: apiBaseUrl,
      config: presenceConfig ?? TelemetryConfig().presenceConfig,
      getInstallId: () => _installId,
      getUserId: () => _userId,
      getAppVersion: () => _deviceContext?.appVersion ?? 'unknown',
      getAuthHeaders: _getAuthHeaders,
    );

    _isInitialized = true;
    debugPrint('📊 TelemetryService initialized');
    debugPrint('   InstallId: $_installId');
    debugPrint('   UserId: $_userId');
  }

  /// 初始化 installId
  Future<void> _initInstallId() async {
    final storedId = _storage.getInstallId();

    if (storedId != null) {
      _installId = storedId;
    } else {
      _installId = const Uuid().v4();
      await _storage.saveInstallId(_installId);
    }

    debugPrint('📊 [Telemetry] Install ID: $_installId');
  }

  /// 获取认证头（使用缓存的 access token，由 AccountService 登录时注入）
  Map<String, String> _getAuthHeaders() {
    if (_accessToken != null) {
      return {'Authorization': 'Bearer $_accessToken'};
    }
    return {};
  }

  /// 记录事件(核心方法)
  void logEvent(
    String eventName, {
    EventType type = EventType.userAction,
    EventLevel level = EventLevel.info,
    Map<String, dynamic>? properties,
  }) {
    if (!_isInitialized) {
      debugPrint('⚠️ TelemetryService not initialized, event ignored');
      return;
    }

    // 检查配置：是否应该记录
    if (!TelemetryConfig().shouldLog(type, eventName)) {
      return; // 配置禁止记录
    }

    // 采样判断（错误和崩溃不采样）
    if (_needsSampling(type)) {
      if (Random().nextDouble() > TelemetryConfig().samplingRate) {
        return; // 未被采样
      }
    }

    final deviceProps = _deviceContext != null
        ? {
            'device_brand': _deviceContext!.brand,
            'device_model': _deviceContext!.model,
            'device_os': _deviceContext!.osVersion,
            'app_version': _deviceContext!.appVersion,
            'locale': _deviceContext!.locale,
          }
        : <String, dynamic>{};

    final event = TelemetryEvent(
      eventId: const Uuid().v4(),
      type: type,
      level: level,
      name: eventName,
      properties: {...deviceProps, ...?properties},
      timestamp: DateTime.now(),
      userId: _userId,
      sessionId: _sessionManager.currentSessionId,
      installId: _installId,
      deviceContextId: _deviceContext?.androidId ?? '',
    );

    _storage.enqueueEvent(event);

    // 检查是否需要立即上传
    _uploader.uploadIfNeeded();
  }

  /// 判断是否需要采样
  bool _needsSampling(EventType type) {
    // 错误、崩溃、会话事件 100% 上报，不采样
    return type != EventType.error &&
        type != EventType.crash &&
        type != EventType.session;
  }

  /// 记录页面访问
  void logPageView(String pageName, {Map<String, dynamic>? extra}) {
    logEvent(
      'page_view',
      type: EventType.pageView,
      properties: {'page': pageName, ...?extra},
    );
  }

  /// 记录用户行为
  void logUserAction(String action, {Map<String, dynamic>? properties}) {
    logEvent(
      action,
      type: EventType.userAction,
      properties: properties,
    );
  }

  /// 记录错误
  void logError(
    String errorMessage, {
    Object? error,
    StackTrace? stackTrace,
    Map<String, dynamic>? extra,
  }) {
    logEvent(
      'error_occurred',
      type: EventType.error,
      level: EventLevel.error,
      properties: {
        'message': errorMessage,
        'error': error?.toString(),
        'stack_trace': stackTrace?.toString(),
        ...?extra,
      },
    );
  }

  /// 记录API调用
  void logApiCall({
    required String url,
    required String method,
    required int statusCode,
    required int durationMs,
    String? error,
  }) {
    logEvent(
      'api_call',
      type: EventType.apiCall,
      level: error != null ? EventLevel.error : EventLevel.info,
      properties: {
        'url': url,
        'method': method,
        'status_code': statusCode,
        'duration_ms': durationMs,
        'error': error,
      },
    );
  }

  /// 记录性能指标
  void logPerformance(
    String metricName, {
    required int durationMs,
    Map<String, dynamic>? extra,
  }) {
    logEvent(
      metricName,
      type: EventType.performance,
      properties: {'duration_ms': durationMs, ...?extra},
    );
  }

  /// 设置用户ID(登录后调用)
  void setUserId(String? userId) {
    _userId = userId;
    debugPrint('📊 [Telemetry] User ID set: $userId');
  }

  /// 清除用户ID(退出登录时)
  void clearUserId() {
    _userId = null;
    debugPrint('📊 [Telemetry] User ID cleared');
  }

  /// 设置访问令牌（登录/切换账号后调用，用于心跳认证）
  void setAccessToken(String? token) {
    _accessToken = token;
    debugPrint('📊 [Telemetry] Access token ${token != null ? 'set' : 'cleared'}');
  }

  /// 清除访问令牌（退出登录时调用）
  void clearAccessToken() {
    _accessToken = null;
  }

  /// 暂停遥测上传（退出登录时调用）
  /// 停止定期上传任务，清空事件队列
  Future<void> pauseForLogout() async {
    _uploader.stopPeriodicUpload();
    await _storage.clearEventQueue();
    _userId = null;
    debugPrint('📊 [Telemetry] Paused for logout');
  }

  /// 恢复遥测上传（登录后调用）
  void resumeAfterLogin() {
    if (TelemetryConfig().globalEnabled) {
      _uploader.startPeriodicUpload();
      debugPrint('📊 [Telemetry] Resumed after login');
    }
  }

  /// 设置用户是否同意数据收集
  Future<void> setUserOptIn(bool optIn) async {
    await TelemetryConfig().setUserOptIn(optIn);

    if (!optIn) {
      // 用户拒绝，停止上传并清空队列
      _uploader.stopPeriodicUpload();
      await _storage.clearEventQueue();
      debugPrint('📊 Telemetry disabled by user');
    } else {
      // 用户同意，重新启动
      if (TelemetryConfig().globalEnabled) {
        _uploader.startPeriodicUpload();
      }
      debugPrint('📊 Telemetry enabled by user');
    }
  }

  // ========== 会话和在线状态相关方法 ==========

  /// 获取当前会话 ID
  String? get currentSessionId => _sessionManager.currentSessionId;

  /// 获取会话时长（秒）
  int get sessionDurationSeconds => _sessionManager.sessionDurationSeconds;

  /// 心跳是否运行中
  bool get isHeartbeatRunning => _heartbeatService.isRunning;

  /// 心跳计数
  int get heartbeatCount => _heartbeatService.heartbeatCount;

  /// 更新心跳配置
  void updatePresenceConfig(PresenceConfig config) {
    _heartbeatService.updateConfig(config);
  }

  /// 获取设备上下文
  DeviceContext? get deviceContext => _deviceContext;

  /// App进入后台时调用：忽略10条阈值，立即上传队列中的事件
  Future<void> flushOnBackground() async {
    await _uploader.uploadBatch(batchSize: 50);
    debugPrint('📊 [Telemetry] Flushed on background');
  }

  /// App退出前调用
  Future<void> dispose() async {
    _configSyncTimer?.cancel();
    _sessionManager.dispose();
    _heartbeatService.dispose();
    await _uploader.forceUploadAll();
    _isInitialized = false;
    debugPrint('📊 TelemetryService disposed');
  }

  /// 重置实例
  static void reset() {
    _instance = null;
  }
}
