import { getLogger } from '@stock-bot/logger';
import { initializeStockConfig } from '@stock-bot/stock-config';
import { createRoutes } from './routes/create-routes';
import { createWebSocketRoute, handleWebSocketConnection } from './routes/websocket.routes';
import type { IServiceContainer } from '@stock-bot/handlers';

// Initialize configuration with service-specific overrides
const config = initializeStockConfig('webApi');

// Override queue settings for web-api (no workers needed)
if (config.queue) {
  config.queue.workers = 0;
  config.queue.concurrency = 0;
  config.queue.enableScheduledJobs = false;
}

// Log the full configuration
const logger = getLogger('web-api');
logger.info('Service configuration:', config);

// Container factory function
async function createContainer(config: any) {
  const { ServiceContainerBuilder } = await import('@stock-bot/di');

  const container = await new ServiceContainerBuilder()
    .withConfig(config)
    .withOptions({
      enableQuestDB: false,
      enableMongoDB: true,
      enablePostgres: true,
      enableCache: true,
      enableQueue: true,
      enableBrowser: false,
      enableProxy: false,
    })
    .build();

  // Run database migrations
  if (container.postgres) {
    const { runMigrations } = await import('./migrations/migration-runner');
    await runMigrations(container);
  }

  return container;
}

// Custom server start function with WebSocket support
export async function startServerWithWebSocket() {
  let container: IServiceContainer | null = null;
  
  try {
    // Create container
    const diContainer = await createContainer(config);
    container = diContainer.resolve('serviceContainer');
    
    // Create HTTP routes
    const routes = createRoutes(container);
    
    // Create WebSocket route handler
    const wsRoute = createWebSocketRoute(container);
    
    // Start server with WebSocket support
    const port = config.service.port || 2003;
    
    logger.info(`Starting server on port ${port}...`);
    
    let server;
    try {
      server = Bun.serve({
        port,
        
        // Handle HTTP requests
        async fetch(req, server) {
          const url = new URL(req.url);
          
          // Check if this is a WebSocket upgrade request
          if (url.pathname === '/ws' && req.headers.get('upgrade') === 'websocket') {
            return wsRoute(req, server);
          }
          
          // Otherwise handle as normal HTTP request
          return routes.fetch(req);
        },
        
        // WebSocket handlers
        websocket: {
          open(ws) {
            handleWebSocketConnection(ws);
          },
          
          message(ws, message) {
            // Message handling is done in the WebSocket handler
            // No need to echo messages back
          },
          
          close(ws, code, reason) {
            logger.info('WebSocket closed', { code, reason });
          },
          
          error(ws, error) {
            logger.error('WebSocket error', error);
          }
        },
        
        development: config.environment === 'development',
      });
    } catch (error) {
      if (error instanceof Error && error.message.includes('port')) {
        logger.error(`Port ${port} is already in use. Please stop any other servers running on this port.`);
        throw new Error(`Port ${port} is already in use`);
      }
      throw error;
    }
    
    logger.info(`Web API service with WebSocket support started on port ${server.port}`);
    logger.info(`WebSocket endpoint available at ws://localhost:${server.port}/ws`);
    
    // Handle shutdown
    process.on('SIGINT', async () => {
      logger.info('Shutting down server...');
      server.stop();
      process.exit(0);
    });
    
  } catch (error) {
    logger.fatal('Failed to start web API service', { error });
    process.exit(1);
  }
}

// Export the function - don't start automatically