import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:dio/dio.dart';
import '../session/session_manager.dart';
import '../session/session_events.dart';
import 'presence_config.dart';

/// 心跳服务
///
/// 职责：
/// 1. 在 App 前台时定期发送心跳
/// 2. 进入后台时停止心跳
/// 3. 心跳失败时不立即重试，等待下一个周期
class HeartbeatService {
  static HeartbeatService? _instance;

  HeartbeatService._();

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

  /// 配置
  PresenceConfig _config = PresenceConfig.defaultConfig;

  /// 心跳定时器
  Timer? _heartbeatTimer;

  /// 是否正在运行
  bool _isRunning = false;
  bool get isRunning => _isRunning;

  /// 最后一次心跳时间
  DateTime? _lastHeartbeatAt;
  DateTime? get lastHeartbeatAt => _lastHeartbeatAt;

  /// 心跳计数（调试用）
  int _heartbeatCount = 0;
  int get heartbeatCount => _heartbeatCount;

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

  /// 获取 installId 的回调
  String Function()? getInstallId;

  /// 获取 userId 的回调
  String? Function()? getUserId;

  /// 获取 appVersion 的回调
  String Function()? getAppVersion;

  /// 获取认证头的回调
  Map<String, String> Function()? getAuthHeaders;

  late Dio _dio;

  bool _isInitialized = false;

  /// 初始化
  void initialize({
    required String apiBaseUrl,
    PresenceConfig? config,
    required String Function() getInstallId,
    required String? Function() getUserId,
    required String Function() getAppVersion,
    Map<String, String> Function()? getAuthHeaders,
  }) {
    if (_isInitialized) return;

    _apiBaseUrl = apiBaseUrl;
    _config = config ?? PresenceConfig.defaultConfig;
    this.getInstallId = getInstallId;
    this.getUserId = getUserId;
    this.getAppVersion = getAppVersion;
    this.getAuthHeaders = getAuthHeaders;

    _dio = Dio(BaseOptions(
      baseUrl: apiBaseUrl,
      connectTimeout: const Duration(seconds: 5),
      receiveTimeout: const Duration(seconds: 5),
    ));

    // 监听会话状态变化
    final sessionManager = SessionManager();
    sessionManager.onSessionStart = _onSessionStart;
    sessionManager.onSessionEnd = _onSessionEnd;

    // 如果当前已经在前台，立即启动心跳
    if (sessionManager.state == SessionState.foreground) {
      _startHeartbeat();
    }

    _isInitialized = true;
    debugPrint(
        '💓 [Heartbeat] Initialized, interval: ${_config.heartbeatIntervalSeconds}s');
  }

  /// 更新配置（支持远程配置热更新）
  void updateConfig(PresenceConfig config) {
    final wasRunning = _isRunning;

    if (wasRunning) {
      _stopHeartbeat();
    }

    _config = config;

    if (wasRunning && _config.enabled) {
      _startHeartbeat();
    }

    debugPrint('💓 [Heartbeat] Config updated');
  }

  /// 销毁
  void dispose() {
    _stopHeartbeat();
    _isInitialized = false;
    _instance = null;
    debugPrint('💓 [Heartbeat] Disposed');
  }

  /// 会话开始回调
  void _onSessionStart() {
    if (_config.enabled) {
      _startHeartbeat();
    }
  }

  /// 会话结束回调
  void _onSessionEnd() {
    _stopHeartbeat();
  }

  /// 启动心跳
  void _startHeartbeat() {
    if (_isRunning) return;
    if (!_config.enabled) return;

    _isRunning = true;
    _heartbeatCount = 0;

    // 立即发送第一次心跳
    _sendHeartbeat();

    // 启动定时器
    _heartbeatTimer = Timer.periodic(
      Duration(seconds: _config.heartbeatIntervalSeconds),
      (_) => _sendHeartbeat(),
    );

    debugPrint('💓 [Heartbeat] Started');
  }

  /// 停止心跳
  void _stopHeartbeat() {
    _heartbeatTimer?.cancel();
    _heartbeatTimer = null;
    _isRunning = false;

    debugPrint('💓 [Heartbeat] Stopped (count: $_heartbeatCount)');
  }

  /// 发送心跳
  Future<void> _sendHeartbeat() async {
    // 检查是否需要登录
    if (_config.requiresAuth && (getUserId?.call() == null)) {
      debugPrint('💓 [Heartbeat] Skipped: user not logged in');
      return;
    }

    try {
      final response = await _dio.post(
        '/api/v1/presence/heartbeat',
        data: {
          'installId': getInstallId?.call() ?? '',
          'appVersion': getAppVersion?.call() ?? '',
          'clientTs': DateTime.now().millisecondsSinceEpoch ~/ 1000,
        },
        options: Options(
          headers: getAuthHeaders?.call(),
        ),
      );

      if (response.statusCode == 200) {
        _lastHeartbeatAt = DateTime.now();
        _heartbeatCount++;
        debugPrint('💓 [Heartbeat] Sent #$_heartbeatCount');
      }
    } on DioException catch (e) {
      // 心跳失败不重试，等待下一个周期
      debugPrint('💓 [Heartbeat] Failed (DioException): ${e.message}');
    } catch (e) {
      // 心跳失败不重试，等待下一个周期
      debugPrint('💓 [Heartbeat] Failed: $e');
    }
  }

  /// 手动触发心跳（用于测试）
  @visibleForTesting
  Future<void> forceHeartbeat() async {
    await _sendHeartbeat();
  }
}
