import type { Server as SocketServer } from 'socket.io';
import jwt from 'jsonwebtoken';
import type { JwtPayload } from '../middleware/auth.js';
import { userCanAccessTicket } from '../services/ticketAccessService.js';

const JWT_SECRET = process.env.JWT_SECRET!;

export function setupWebSocket(io: SocketServer) {
  // Authenticate WS connections via JWT in handshake auth or query
  io.use((socket, next) => {
    const token =
      socket.handshake.auth?.token ||
      socket.handshake.query?.token;

    if (!token) {
      return next(new Error('Unauthorized'));
    }

    try {
      const payload = jwt.verify(token as string, JWT_SECRET) as JwtPayload;
      socket.data.user = { ...payload, company_id: payload.company_id ?? null };
      next();
    } catch {
      next(new Error('Invalid token'));
    }
  });

  io.on('connection', (socket) => {
    const user = socket.data.user as JwtPayload;
    console.log(`[WS] connected: ${user.email} (${socket.id})`);

    // Client subscribes to specific ticket rooms
    socket.on('tickets:subscribe', async ({ ticketIds }: { ticketIds: string[] }) => {
      for (const id of ticketIds) {
        if (user.role === 'company_user') {
          const ok = await userCanAccessTicket(user, id);
          if (!ok) continue;
        }
        socket.join(`ticket:${id}`);
      }
    });

    socket.on('tickets:unsubscribe', ({ ticketIds }: { ticketIds: string[] }) => {
      for (const id of ticketIds) {
        socket.leave(`ticket:${id}`);
      }
    });

    socket.on('disconnect', () => {
      console.log(`[WS] disconnected: ${user.email} (${socket.id})`);
    });
  });
}
