import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/cupertino.dart';

typedef MessageCallback = void Function(dynamic message);
typedef ErrorCallback = void Function(dynamic error);
typedef DoneCallback = void Function();
typedef ConnectedCallback = void Function();
typedef ReconnectCallback = void Function(ReconnectStatus);

enum ReconnectStatus { start, trying, success }

class WebSocketService with WidgetsBindingObserver {
  // 单例
  static final WebSocketService _instance = WebSocketService._internal();
  static bool doReconnect = false;

  factory WebSocketService() => _instance;

  WebSocketService._internal();

  // 初始化/销毁生命周期
  void init() {
    WidgetsBinding.instance.addObserver(this);
  }

  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _reconnectTimer?.cancel();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      if (doReconnect) {
        // 亮屏，主动检测连接
        _socket?.close();
        _socket = null;
        _startReconnect();
        doReconnect = false;
      }
    } else if (state == AppLifecycleState.paused) {
      doReconnect = true;
      // 锁屏时暂停计时器
      _reconnectTimer?.cancel();
      _reconnectTimer = null;
    }
  }

  WebSocket? _socket;
  String? _url;
  bool _isConnecting = false;
  bool _manuallyClosed = false;
  Timer? _reconnectTimer;

  final List<MessageCallback> _messageListeners = [];
  final List<ErrorCallback> _errorListeners = [];
  final List<DoneCallback> _doneListeners = [];
  final List<ConnectedCallback> _connectedListeners = [];
  final List<ReconnectCallback> _reconnectListeners = [];

  bool _hasTriggeredStart = false;

  /// 建立连接
  Future<void> connect(String url) async {
    _url = url;
    _manuallyClosed = false;
    _hasTriggeredStart = false;
    _triggerReconnectCallback(ReconnectStatus.start);
    await _tryConnect();
  }

  /// 发送消息
  void send(String message) {
    if (_socket != null && _socket!.readyState == WebSocket.open) {
      _socket!.add(message);
    } else {
      for (var listener in _errorListeners) {
        listener("WebSocket 未连接，无法发送: $message");
      }
    }
  }

  /// 手动关闭
  Future<void> close() async {
    _manuallyClosed = true;
    _reconnectTimer?.cancel();
    _reconnectTimer = null;
    await _socket?.close();
    _socket = null;
    _hasTriggeredStart = false;
  }

  /// 添加监听
  void addMessageListener(MessageCallback listener) =>
      _messageListeners.add(listener);

  void removeMessageListener(MessageCallback listener) =>
      _messageListeners.remove(listener);

  void addErrorListener(ErrorCallback listener) =>
      _errorListeners.add(listener);

  void removeErrorListener(ErrorCallback listener) =>
      _errorListeners.remove(listener);

  void addDoneListener(DoneCallback listener) => _doneListeners.add(listener);

  void removeDoneListener(DoneCallback listener) =>
      _doneListeners.remove(listener);

  void addConnectedListener(ConnectedCallback listener) =>
      _connectedListeners.add(listener);

  void removeConnectedListener(ConnectedCallback listener) =>
      _connectedListeners.remove(listener);

  void addReconnectListener(ReconnectCallback listener) =>
      _reconnectListeners.add(listener);

  void removeReconnectListener(ReconnectCallback listener) =>
      _reconnectListeners.remove(listener);

  /// 内部尝试连接
  Future<void> _tryConnect() async {
    if (_socket != null && _socket!.readyState == WebSocket.open) return;
    if (_isConnecting) return;

    _isConnecting = true;
    _triggerReconnectCallback(ReconnectStatus.trying);

    try {
      _socket = await WebSocket.connect(_url!);

      // 连接成功回调
      for (var callback in _connectedListeners) callback();
      _triggerReconnectCallback(ReconnectStatus.success);
      _hasTriggeredStart = false;

      _socket!.listen(
        (data) {
          dynamic msg;
          try {
            msg = jsonDecode(data);
          } catch (_) {
            msg = data.toString();
          }
          for (var listener in _messageListeners) listener(msg);
        },
        onError: (error) {
          for (var listener in _errorListeners) listener(error);
          _startReconnect();
        },
        onDone: () {
          for (var listener in _doneListeners) listener();
          _startReconnect();
        },
        cancelOnError: true,
      );
    } catch (e) {
      for (var listener in _errorListeners) listener(e);
      _startReconnect();
    } finally {
      _isConnecting = false;
    }
  }

  /// 开始重连
  void _startReconnect() {
    if (_manuallyClosed) return;
    if (_reconnectTimer?.isActive ?? false) return;

    if (!_hasTriggeredStart) {
      _triggerReconnectCallback(ReconnectStatus.start);
      _hasTriggeredStart = true;
    }

    _reconnectTimer = Timer.periodic(const Duration(seconds: 5), (timer) {
      if (_socket == null || _socket!.readyState != WebSocket.open) {
        _triggerReconnectCallback(ReconnectStatus.trying);
        _tryConnect();
      } else {
        timer.cancel();
        _reconnectTimer = null;
      }
    });
  }


  /// 触发重连状态回调
  void _triggerReconnectCallback(ReconnectStatus status) {
    for (var listener in _reconnectListeners) {
      listener(status);
    }
  }
}
