import Fastify from 'fastify';
import cors from '@fastify/cors';
import helmet from '@fastify/helmet';
import rateLimit from '@fastify/rate-limit';
import formbody from '@fastify/formbody';
import http from 'node:http';

import { env } from './config/env.js';
import { connectDatabase, disconnectDatabase } from './config/database.js';
import { logger } from './utils/logger.js';
import { initSocketServer } from './websocket/socket.server.js';
import { clearAllTimers } from './services/auction/timer.service.js';

// Routes
import { authRoutes } from './api/routes/auth.routes.js';
import { tenantRoutes } from './api/routes/tenant.routes.js';
import { productRoutes } from './api/routes/product.routes.js';
import { sessionRoutes } from './api/routes/session.routes.js';
import { auctionRoutes } from './api/routes/auction.routes.js';
import { userRoutes } from './api/routes/user.routes.js';
import { webhookRoutes } from './api/routes/webhook.routes.js';
import { integrationRoutes } from './api/routes/integration.routes.js';
import { instagramAuthRoutes } from './services/instagram/auth.service.js';

async function bootstrap() {
  // Create HTTP server for both Fastify + Socket.io
  const httpServer = http.createServer();

  const app = Fastify({
    logger: {
      level: env.logLevel,
      transport: env.isDev
        ? { target: 'pino-pretty', options: { colorize: true, translateTime: 'HH:MM:ss' } }
        : undefined,
    },
    serverFactory: (handler) => {
      httpServer.on('request', handler);
      return httpServer;
    },
  });

  // Plugins
  await app.register(cors, {
    origin: env.isDev ? true : env.appUrl,
    credentials: true,
  });

  await app.register(helmet, {
    contentSecurityPolicy: false, // We'll handle CSP ourselves
  });

  await app.register(rateLimit, {
    max: env.rateLimit.max,
    timeWindow: env.rateLimit.windowMs,
  });

  await app.register(formbody);

  // Health check
  app.get('/health', async () => ({
    status: 'ok',
    timestamp: new Date().toISOString(),
    version: '1.0.0',
  }));

  // API Routes
  const prefix = '/api/v1';
  await app.register(authRoutes, { prefix: `${prefix}/auth` });
  await app.register(instagramAuthRoutes, { prefix: `${prefix}/auth` });
  await app.register(tenantRoutes, { prefix: `${prefix}/tenant` });
  await app.register(productRoutes, { prefix: `${prefix}/products` });
  await app.register(sessionRoutes, { prefix: `${prefix}/sessions` });
  await app.register(auctionRoutes, { prefix: `${prefix}/auctions` });
  await app.register(userRoutes, { prefix: `${prefix}/users` });
  await app.register(webhookRoutes, { prefix: `${prefix}/webhooks` });
  await app.register(integrationRoutes, { prefix: `${prefix}/integration` });

  // Connect services
  await connectDatabase();
  logger.info('[DB] MySQL connected');

  // Init WebSocket
  initSocketServer(httpServer);

  // Start server
  await app.ready();
  httpServer.listen(env.port, env.host, () => {
    logger.info(`🚀 BidCast server running on http://${env.host}:${env.port}`);
    logger.info(`📡 WebSocket available at ws://${env.host}:${env.port}/ws`);
    logger.info(`📋 API: http://${env.host}:${env.port}/api/v1`);
  });

  // Graceful shutdown
  const shutdown = async (signal: string) => {
    logger.info(`${signal} received, shutting down...`);
    clearAllTimers();
    await app.close();
    await disconnectDatabase();
    process.exit(0);
  };

  process.on('SIGTERM', () => shutdown('SIGTERM'));
  process.on('SIGINT', () => shutdown('SIGINT'));
}

bootstrap().catch((err) => {
  console.error('Fatal error during startup:', err);
  process.exit(1);
});
