import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'tcp_server_state.dart';

class TcpServerCubit extends Cubit<TcpServerState> {
  ServerSocket? _serverSocket;
  final List<Socket> _clients = [];

  /// 服务端 Socket 监听的订阅
  StreamSubscription<Socket>? _serverSub;

  /// 每个客户端 Socket 的订阅
  final List<StreamSubscription<dynamic>> _clientSubs = [];

  final StreamController<Map<String, dynamic>> _dataController =
      StreamController.broadcast();

  /// 接收到的客户端数据流
  Stream<Map<String, dynamic>> get onClientData => _dataController.stream;

  TcpServerCubit() : super(const TcpServerState());

  /// 设置端口
  void setPort(int port) {
    emit(state.copyWith(port: port));
  }

  /// 启动服务端
  Future<void> start() async {
    try {
      _serverSocket =
          await ServerSocket.bind(InternetAddress.anyIPv4, state.port);
      if (isClosed) {
        _serverSocket?.close();
        _serverSocket = null;
        return;
      }
      emit(state.copyWith(isRunning: true, port: _serverSocket!.port));
      _listenClients();
    } catch (e) {
      if (isClosed) return;
      if (e.toString().contains('already in use')) {
        emit(state.copyWith(port: state.port + 1));
        start();
      } else {
        emit(state.copyWith(error: e.toString()));
      }
    }
  }

  /// 监听客户端连接
  void _listenClients() {
    _serverSub?.cancel();
    _serverSub = _serverSocket!.listen((client) {
      if (isClosed) {
        client.close();
        return;
      }
      _clients.add(client);
      emit(state.copyWith(connectedClients: _clients.length));
      _handleClient(client);
    });
  }

  /// 处理单个客户端数据
  void _handleClient(Socket client) {
    final sub = client.listen(
      (data) {
        if (_dataController.isClosed) return;
        _dataController.add({
          'client': client,
          'address': client.remoteAddress.address,
          'port': client.remotePort,
          'data': Uint8List.fromList(data),
        });
      },
      onDone: () => _removeClient(client),
      onError: (e) => _removeClient(client),
    );
    _clientSubs.add(sub);
  }

  /// 群发字节数据给所有客户端
  void sendToAll(Uint8List data) {
    for (var c in _clients) {
      try {
        c.add(data);
      } catch (_) {}
    }
  }

  /// 群发十六进制字符串给所有客户端
  void sendHexToAll(String hex) {
    hex = hex.replaceAll(RegExp(r'\s+'), '');
    List<int> bytes = [];
    for (int i = 0; i < hex.length; i += 2) {
      bytes.add(int.parse(hex.substring(i, i + 2), radix: 16));
    }
    sendToAll(Uint8List.fromList(bytes));
  }

  /// 移除客户端
  void _removeClient(Socket client) {
    _clients.remove(client);
    client.destroy();
    if (!isClosed) {
      emit(state.copyWith(connectedClients: _clients.length));
    }
  }

  /// 停止服务端
  Future<void> stop() async {
    for (var sub in _clientSubs) {
      await sub.cancel();
    }
    _clientSubs.clear();
    for (var c in _clients) {
      await c.close();
    }
    _clients.clear();
    await _serverSocket?.close();
    _serverSocket = null;
    if (!isClosed) {
      emit(state.copyWith(isRunning: false, connectedClients: 0));
    }
  }

  @override
  Future<void> close() async {
    await stop();
    _serverSub?.cancel();
    _serverSub = null;
    await _dataController.close();
    return super.close();
  }
}
