const prisma = require('../prisma/client');
const { getRoomTimerSnapshot } = require('./roomHandler');

/**
 * 注册大屏相关 WebSocket 事件处理
 *
 * 事件列表（客户端 → 服务器）：
 *   screen:join      大屏连接注册
 *   screen:bindRoom  管理后台绑定大屏到指定房间
 *
 * 事件列表（服务器 → 客户端）：
 *   screen:joined        注册成功确认
 *   screen:roomChanged   通知大屏切换展示房间
 *   screen:bindRoom:ok   绑定成功确认
 *   error                错误通知
 *
 * @param {import('ws').WebSocket} ws
 * @param {{ sendToScreen, joinRoom, leaveAllRooms, screenSockets, broadcastToRoom }} helpers
 * @returns {Function} cleanup 函数，ws 关闭时调用
 */
function registerScreenHandlers(ws, { sendToScreen, joinRoom, leaveAllRooms, screenSockets, broadcastToRoom }) {
  if (!ws._handlers) ws._handlers = {};

  // ── screen:join ────────────────────────────────────────────────────────────
  ws._handlers['screen:join'] = async ({ screenName } = {}) => {
    if (!screenName) {
      ws.sendEvent('error', { message: '缺少 screenName' });
      return;
    }

    try {
      const screenConfig = await prisma.screenConfig.upsert({
        where: { screenName },
        update: {},
        create: { screenName },
      });

      // 注册大屏 ws 到全局表
      screenSockets.set(screenName, ws);
      ws.ctx.screenName = screenName;
      ws.ctx.role = 'screen';

      // 如果已绑定房间，订阅该房间
      if (screenConfig.currentRoomId) {
        joinRoom(ws, screenConfig.currentRoomId);
      }

      console.log(`[Screen] 大屏注册: ${screenName}，当前房间: ${screenConfig.currentRoomId || '无'}`);
      ws.sendEvent('screen:joined', {
        screenName,
        currentRoomId: screenConfig.currentRoomId,
      });
      const timerSnapshot = getRoomTimerSnapshot(screenConfig.currentRoomId);
      if (timerSnapshot) {
        ws.sendEvent('room:gameStart', {
          roomId: timerSnapshot.roomId,
          gameDuration: timerSnapshot.durationSec,
          startAtMs: timerSnapshot.startAtMs,
        });
      }
    } catch (err) {
      console.error('[screen:join] 错误:', err);
      ws.sendEvent('error', { message: '大屏注册失败' });
    }
  };

  // ── screen:bindRoom ────────────────────────────────────────────────────────
  ws._handlers['screen:bindRoom'] = async ({ screenName, roomId } = {}) => {
    if (!screenName) {
      ws.sendEvent('error', { message: '缺少 screenName' });
      return;
    }

    try {
      await prisma.screenConfig.upsert({
        where: { screenName },
        update: { currentRoomId: roomId || null },
        create: { screenName, currentRoomId: roomId || null },
      });

      // 找到目标大屏的 ws
      const targetWs = screenSockets.get(screenName);
      if (targetWs && targetWs.readyState === targetWs.OPEN) {
        // 先退订所有旧房间
        leaveAllRooms(targetWs);
        // 订阅新房间
        if (roomId) {
          joinRoom(targetWs, roomId);
        }
        // 通知大屏切换房间
        targetWs.sendEvent('screen:roomChanged', { roomId: roomId || null });
        const timerSnapshot = getRoomTimerSnapshot(roomId);
        if (timerSnapshot) {
          targetWs.sendEvent('room:gameStart', {
            roomId: timerSnapshot.roomId,
            gameDuration: timerSnapshot.durationSec,
            startAtMs: timerSnapshot.startAtMs,
          });
        }
      }

      console.log(`[Screen] 绑定大屏 ${screenName} → 房间 ${roomId || '无'}`);
      ws.sendEvent('screen:bindRoom:ok', { screenName, roomId: roomId || null });
    } catch (err) {
      console.error('[screen:bindRoom] 错误:', err);
      ws.sendEvent('error', { message: '绑定房间失败' });
    }
  };

  // ── cleanup（ws close 时调用）──────────────────────────────────────────────
  const cleanup = () => {
    const { screenName } = ws.ctx;
    if (screenName && screenSockets.get(screenName) === ws) {
      screenSockets.delete(screenName);
      console.log(`[Screen] 大屏断开: ${screenName}`);
    }
  };

  return cleanup;
}

module.exports = { registerScreenHandlers };
