const { WebSocketServer } = require("ws");
const { encoderModule, calcSpeedFromRpm } = require("../encoder-module");
const logger = require("../lib/logger");

module.exports = class EncoderServer {
  constructor({ server, broadcast }) {
    this.broadcast = broadcast;
    this.clients = new Set();
    
    const path = `/encoder`;
    logger.info(`Encoder websocket server starting`, path);

    const wss = new WebSocketServer({ noServer: true, path }, () => {
      logger.info(`Encoder websocket server started`, path);
    });

    server.on("upgrade", (request, socket, head) => {
      if (request.url === path)
        wss.handleUpgrade(request, socket, head, (ws) => {
          wss.emit("connection", ws, request);
        });
    });

    this.wss = wss;

    wss.on("connection", (socket) => {
      logger.info(`Encoder client connected`);
      this.clients.add(socket);

      // 发送当前编码器状态
      const status = encoderModule.getStatus();
      socket.send(JSON.stringify({
        type: "encoder-status",
        payload: status
      }));

      socket.on("message", (data) => {
        try {
          const message = JSON.parse(data);
          this.handleMessage(socket, message);
        } catch (error) {
          logger.error("Encoder server message parse error: " + error.message);
        }
      });

      socket.on("close", () => {
        logger.info(`Encoder client disconnected`);
        this.clients.delete(socket);
      });
    });

    // 注册编码器数据处理函数
    this.setupEncoderHandler();
  }

  setupEncoderHandler() {
    // 监听编码器数据变化
    encoderModule.start(encoderModule.getConfig(), (data) => {
      // 当收到编码器数据时，广播给所有客户端
      this.broadcastEncoderData(data);
    });
  }

  handleMessage(socket, message) {
    const { action, payload } = message;
    
    switch (action) {
      case "get-status":
        const status = encoderModule.getStatus();
        socket.send(JSON.stringify({
          type: "encoder-status",
          payload: status
        }));
        break;
      case "update-config":
        encoderModule.updateConfig(payload);
        // 重启编码器以应用新配置
        encoderModule.start(encoderModule.getConfig(), (data) => {
          this.broadcastEncoderData(data);
        });
        socket.send(JSON.stringify({
          type: "config-updated",
          payload: encoderModule.getConfig()
        }));
        break;
      default:
        logger.warn(`Unknown encoder action: ${action}`);
    }
  }

  broadcastEncoderData(data) {
    // 广播编码器数据给所有客户端
    this.clients.forEach(client => {
      if (client.readyState === client.OPEN) {
        client.send(JSON.stringify({
          type: "encoder-data",
          payload: data
        }));
      }
    });
  }
};