import 'dotenv/config';
import Fastify from 'fastify';
import cors from '@fastify/cors';
import cookie from '@fastify/cookie';
import rateLimit from '@fastify/rate-limit';
import socketio from 'fastify-socket.io';
import { sql } from './db.js';
import { setupWebSocket } from './ws/index.js';

// Routes
import { authRoutes } from './routes/auth.js';
import { ticketRoutes } from './routes/tickets.js';
import { contactRoutes } from './routes/contacts.js';
import { channelRoutes } from './routes/channels.js';
import { userRoutes } from './routes/users.js';
import { auditRoutes } from './routes/audit.js';
import { internalRoutes } from './routes/internal.js';
import { settingsRoutes } from './routes/settings.js';
import { companyRoutes } from './routes/companies.js';
import { portalRoutes } from './routes/portal.js';
import { inboundEmailRoutes } from './routes/inboundEmail.js';
import { signupRoutes } from './routes/signup.js';

const PORT = Number(process.env.PORT ?? 3001);
const HOST = '0.0.0.0';

async function start() {
  const fastify = Fastify({
    logger: {
      transport:
        process.env.NODE_ENV !== 'production'
          ? { target: 'pino-pretty', options: { colorize: true } }
          : undefined,
    },
  });

  const corsOrigins = process.env.CORS_ORIGIN?.trim();
  await fastify.register(cors, {
    origin: corsOrigins
      ? corsOrigins.split(',').map((s) => s.trim()).filter(Boolean)
      : true,
    credentials: true,
  });

  await fastify.register(cookie);

  // Register Socket.IO via fastify-socket.io so it shares Fastify's http.Server
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  await fastify.register(socketio as any, { cors: { origin: '*' } });

  // Health check
  fastify.get('/health', async () => ({ status: 'ok' }));

  // API routes
  await fastify.register(authRoutes, { prefix: '/api/v1/auth' });

  await fastify.register(
    async (scope) => {
      await scope.register(rateLimit, { max: 40, timeWindow: '1 minute' });
      await scope.register(signupRoutes);
    },
    { prefix: '/api/v1/signup' },
  );
  await fastify.register(ticketRoutes,  { prefix: '/api/v1/tickets' });
  await fastify.register(contactRoutes, { prefix: '/api/v1/contacts' });
  await fastify.register(channelRoutes, { prefix: '/api/v1/channels' });
  await fastify.register(userRoutes,    { prefix: '/api/v1/users' });
  await fastify.register(auditRoutes,   { prefix: '/api/v1/audit-logs' });
  await fastify.register(settingsRoutes, { prefix: '/api/v1/settings' });
  await fastify.register(companyRoutes, { prefix: '/api/v1/companies' });
  await fastify.register(portalRoutes, { prefix: '/api/v1/portal' });
  await fastify.register(inboundEmailRoutes, { prefix: '/api/v1' });
  await fastify.register(internalRoutes, { prefix: '/internal' });

  try {
    await fastify.listen({ port: PORT, host: HOST });
    fastify.log.info(`API listening on ${HOST}:${PORT}`);
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }

  // Wire up Socket.IO handlers after server is ready
  setupWebSocket(fastify.io);

  // Restore WhatsApp sessions — non-fatal: server stays up even if DB unreachable
  try {
    const { channelService } = await import('./services/channelService.js');
    await channelService.restoreAllSessions(fastify.io);
  } catch (err) {
    fastify.log.warn({ err }, 'Could not restore WhatsApp sessions on startup (DB may not be ready yet)');
  }

  // Graceful shutdown
  const shutdown = async (signal: string) => {
    fastify.log.info(`Received ${signal} — shutting down gracefully`);
    await fastify.close();
    await sql.end();
    process.exit(0);
  };

  process.on('SIGTERM', () => shutdown('SIGTERM'));
  process.on('SIGINT',  () => shutdown('SIGINT'));
}

start();
