import { Server } from 'socket.io';
import { ExamService } from '../services/exam.service';
import { AuthenticatedSocket } from '../middleware/auth.middleware';
import debug from 'debug';

const log = debug('socket:handler:exam');

export class ExamHandler {
  private examService: ExamService;

  constructor(io: Server) {
    this.examService = new ExamService(io);
  }

  register(socket: AuthenticatedSocket) {
    // 加入考试房间
    socket.on('exam:join', async (data) => {
      try {
        await this.examService.joinRoom(socket, data.roomId);
      } catch (error) {
        log('处理加入房间事件失败:', error);
        socket.emit('error', '加入考试房间失败');
      }
    });

    // 离开考试房间
    socket.on('exam:leave', async (data) => {
      try {
        await this.examService.leaveRoom(socket, data.roomId);
      } catch (error) {
        log('处理离开房间事件失败:', error);
        socket.emit('error', '离开考试房间失败');
      }
    });

    // 推送题目
    socket.on('exam:question', async (data) => {
      try {
        await this.examService.pushQuestion(socket, data.roomId, data.question);
      } catch (error) {
        log('处理推送题目事件失败:', error);
        socket.emit('error', '推送题目失败');
      }
    });

    // 存储答案
    socket.on('exam:storeAnswer', async (data, callback) => {
      try {
        const success = await this.examService.storeAnswer(socket, data.roomId, data.questionId, data.answer);
        if (callback) callback(success);
      } catch (error) {
        log('处理存储答案事件失败:', error);
        socket.emit('error', '存储答案失败');
        if (callback) callback(false);
      }
    });

    // 获取答案
    socket.on('exam:getAnswers', async (data, callback) => {
      try {
        const answers = await this.examService.getAnswers(data.roomId, data.questionId);
        if (callback) callback(answers);
      } catch (error) {
        log('处理获取答案事件失败:', error);
        socket.emit('error', '获取答案失败');
        if (callback) callback([]);
      }
    });

    // 存储价格
    socket.on('exam:storePrice', async (data) => {
      try {
        await this.examService.storePrice(socket, data.roomId, data.date, data.price);
      } catch (error) {
        log('处理存储价格事件失败:', error);
        socket.emit('error', '存储价格失败');
      }
    });

    // 获取价格
    socket.on('exam:getPrice', async (data, callback) => {
      try {
        const price = await this.examService.getPrice(data.roomId, data.date);
        if (callback) callback(price || '0');
      } catch (error) {
        log('处理获取价格事件失败:', error);
        socket.emit('error', '获取价格失败');
        if (callback) callback('0');
      }
    });

    // 获取所有价格
    socket.on('exam:getPrices', async (data, callback) => {
      try {
        const prices = await this.examService.getAllPrices(data.roomId);
        if (callback) callback(prices);
      } catch (error) {
        log('处理获取所有价格事件失败:', error);
        socket.emit('error', '获取价格失败');
        if (callback) callback({});
      }
    });

    // 获取用户答案
    socket.on('exam:getUserAnswers', async (data, callback) => {
      try {
        const answers = await this.examService.getUserAnswers(data.roomId, data.userId);
        if (callback) callback(answers);
      } catch (error) {
        log('处理获取用户答案事件失败:', error);
        socket.emit('error', '获取用户答案失败');
        if (callback) callback([]);
      }
    });

    // 获取当前题目
    socket.on('exam:currentQuestion', async (data, callback) => {
      try {
        const question = await this.examService.getCurrentQuestion(data.roomId);
        if (callback) callback(question);
      } catch (error) {
        log('处理获取当前题目事件失败:', error);
        socket.emit('error', '获取当前题目失败');
        if (callback) callback(null);
      }
    });

    // 结算
    socket.on('exam:settle', async (data) => {
      try {
        await this.examService.broadcastSettle(socket, data.roomId);
      } catch (error) {
        log('处理结算事件失败:', error);
        socket.emit('error', '结算失败');
      }
    });

    // 清理数据
    socket.on('exam:cleanup', async (data) => {
      try {
        await this.examService.cleanupRoomData(socket, data.roomId, data.questionId);
      } catch (error) {
        log('处理清理数据事件失败:', error);
        socket.emit('error', '清理数据失败');
      }
    });
  }
}