import { Server } from 'socket.io';
import http from 'node:http';
import jwt from 'jsonwebtoken';
import { env } from '../config/env.js';
import { logger } from '../utils/logger.js';
import type { JwtPayload } from '../api/middleware/auth.middleware.js';

let io: Server;

export function initSocketServer(httpServer: http.Server): Server {
  io = new Server(httpServer, {
    cors: {
      origin: env.isDev ? '*' : env.appUrl,
      methods: ['GET', 'POST'],
    },
    path: '/ws',
  });

  // Auth middleware for WebSocket
  io.use((socket, next) => {
    const token = socket.handshake.auth?.token || socket.handshake.query?.token;
    if (!token) {
      return next(new Error('Authentication required'));
    }

    try {
      const decoded = jwt.verify(token as string, env.jwt.secret) as JwtPayload;
      socket.data.tenantId = decoded.tenantId;
      socket.data.email = decoded.email;
      next();
    } catch {
      next(new Error('Invalid token'));
    }
  });

  io.on('connection', (socket) => {
    const tenantId = socket.data.tenantId;
    logger.info({ tenantId }, '[WS] Client connected');

    // Join tenant-specific room
    socket.join(`tenant:${tenantId}`);

    socket.on('disconnect', () => {
      logger.debug({ tenantId }, '[WS] Client disconnected');
    });
  });

  logger.info('[WS] Socket.io server initialized');
  return io;
}

export function getIO(): Server {
  if (!io) throw new Error('Socket.io not initialized');
  return io;
}

// Emit helpers
export function emitToTenant(tenantId: string, event: string, data: unknown) {
  if (!io) return;
  io.to(`tenant:${tenantId}`).emit(event, data);
}

export function emitNewComment(tenantId: string, comment: {
  igUsername: string;
  text: string;
  timestamp: string;
}) {
  emitToTenant(tenantId, 'comment:new', comment);
}

export function emitNewBid(tenantId: string, bid: {
  igUsername: string;
  amount: number;
  bidType: string;
  productName: string;
  status: string;
}) {
  emitToTenant(tenantId, 'bid:new', bid);
}

export function emitAuctionStarted(tenantId: string, auction: {
  id: string;
  productName: string;
  mode: string;
  startingPrice: number;
  timeLimitSeconds: number | null;
}) {
  emitToTenant(tenantId, 'auction:started', auction);
}

export function emitAuctionEnded(tenantId: string, auction: {
  id: string;
  productName: string;
  winnerIgUsername?: string;
  finalPrice: number;
}) {
  emitToTenant(tenantId, 'auction:ended', auction);
}

export function emitCartAdded(tenantId: string, data: {
  igUsername: string;
  productName: string;
  amount: number;
}) {
  emitToTenant(tenantId, 'cart:added', data);
}

export function emitStockUpdated(tenantId: string, data: {
  productId: string;
  remaining: number;
}) {
  emitToTenant(tenantId, 'stock:updated', data);
}

export function emitCountdown(tenantId: string, data: {
  auctionItemId: string;
  secondsRemaining: number;
}) {
  emitToTenant(tenantId, 'auction:countdown', data);
}
