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 = [];

  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);
      emit(state.copyWith(isRunning: true, port: _serverSocket!.port));
      _listenClients();
    } catch (e) {
      if (e.toString().contains('already in use')) {
        emit(state.copyWith(port: state.port + 1));
        start();
      } else {
        emit(state.copyWith(error: e.toString()));
      }
    }
  }

  /// 监听客户端连接
  void _listenClients() {
    _serverSocket!.listen((client) {
      _clients.add(client);
      emit(state.copyWith(connectedClients: _clients.length));
      _handleClient(client);
    });
  }

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

  /// 群发字节数据给所有客户端
  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);
    emit(state.copyWith(connectedClients: _clients.length));
    client.destroy();
  }

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

  @override
  Future<void> close() async {
    await stop();
    _dataController.close();
    return super.close();
  }
}