import { Router, IRouter } from 'express';
import { scanLoginService } from '../services/scan-login.service';
import { getIO } from '../socket';
import { SOCKET_EVENTS } from '@gala/shared/constants';
import type { ScanStatusUpdatePayload } from '@gala/shared/types';

const router: IRouter = Router();

/**
 * POST /api/scan/generate
 * Generate a new scan token and QR code URL
 */
router.post('/generate', async (req, res, next) => {
  try {
    const { pcSocketId } = req.body;

    if (!pcSocketId) {
      return res.status(400).json({
        success: false,
        error: 'pcSocketId is required',
      });
    }

    const result = await scanLoginService.generateScanToken(pcSocketId);

    return res.json(result);
  } catch (error) {
    next(error);
  }
});

/**
 * GET /api/scan/validate/:token
 * Validate a scan token
 */
router.get('/validate/:token', async (req, res, next) => {
  try {
    const { token } = req.params;

    if (!token) {
      return res.status(400).json({
        success: false,
        error: 'Token is required',
      });
    }

    const result = await scanLoginService.validateToken(token);

    return res.json(result);
  } catch (error) {
    next(error);
  }
});

/**
 * POST /api/scan/scanned
 * Mark token as scanned (called by mobile client after scanning QR code)
 */
router.post('/scanned', async (req, res, next) => {
  try {
    const { scanToken } = req.body;

    if (!scanToken) {
      return res.status(400).json({
        success: false,
        error: 'scanToken is required',
      });
    }

    const result = await scanLoginService.markScanned(scanToken);

    if (result.success && result.pcSocketId) {
      // Notify PC client that QR code has been scanned
      const io = getIO();
      const statusUpdate: ScanStatusUpdatePayload = {
        scanToken,
        status: 'scanned',
      };
      io.to(result.pcSocketId).emit(
        SOCKET_EVENTS.SCAN_STATUS_UPDATE as any,
        statusUpdate
      );
    }

    return res.json({
      success: result.success,
      error: result.error,
    });
  } catch (error) {
    next(error);
  }
});

/**
 * POST /api/scan/confirm
 * Confirm login with user info
 */
router.post('/confirm', async (req, res, next) => {
  try {
    const { scanToken, userName, department } = req.body;

    if (!scanToken || !userName || !department) {
      return res.status(400).json({
        success: false,
        error: 'scanToken, userName, and department are required',
      });
    }

    const result = await scanLoginService.confirmLogin(
      scanToken,
      userName,
      department
    );

    if (result.success && result.data) {
      // Notify PC client that login is confirmed
      const io = getIO();
      const statusUpdate: ScanStatusUpdatePayload = {
        scanToken,
        status: 'confirmed',
        userInfo: {
          userId: result.data.userId,
          userName,
          department,
          sessionToken: result.data.sessionToken,
        },
      };
      io.to(result.data.pcSocketId).emit(
        SOCKET_EVENTS.SCAN_STATUS_UPDATE as any,
        statusUpdate
      );

      return res.json({
        success: true,
        data: {
          sessionToken: result.data.sessionToken,
          userId: result.data.userId,
        },
      });
    }

    return res.json({
      success: false,
      error: result.error,
    });
  } catch (error) {
    next(error);
  }
});

export default router;
