/**
 * Stock Bot Orchestrator Service
 * Coordinates between Rust core, data feeds, and analytics
 */

import { getLogger } from '@stock-bot/logger';
import { initializeStockConfig } from '@stock-bot/stock-config';
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { createRoutes } from './routes/create-routes';
import { createContainer } from './simple-container';

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

// Get service-specific config
const serviceConfig = config.services?.orchestrator || {
  port: 2004,
  defaultMode: 'paper',
  paperTradingCapital: 100000,
  enableWebSocket: true
};

const PORT = serviceConfig.port;

// Log the configuration
logger.info('Service configuration:', {
  port: PORT,
  defaultMode: serviceConfig.defaultMode,
  enableWebSocket: serviceConfig.enableWebSocket,
  backtesting: serviceConfig.backtesting,
  strategies: serviceConfig.strategies
});

async function main() {
  let server: any; // Declare server in outer scope for shutdown
  
  try {
    // Initialize container with all services using configuration
    const services = await createContainer(config);
    
    // Initialize Hono app
    const app = new Hono();
    
    // CORS middleware - use config for origins
    app.use('*', cors({
      origin: config.services?.webApi?.cors?.origins || ['http://localhost:4200', 'http://localhost:3000', 'http://localhost:5173', 'http://localhost:5174'],
      allowMethods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
      allowHeaders: ['Content-Type', 'Authorization'],
      credentials: config.services?.webApi?.cors?.credentials ?? true,
    }));
    
    // Logging middleware
    app.use('*', async (c, next) => {
      const start = Date.now();
      await next();
      const ms = Date.now() - start;
      services.logger.debug(`${c.req.method} ${c.req.url} - ${ms}ms`);
    });

    // Create and mount routes (without Socket.IO for now)
    const routes = createRoutes(services);
    app.route('/', routes);

    // Start Bun server
    try {
      server = Bun.serve({
        port: PORT,
        hostname: '0.0.0.0', // Explicitly bind to all interfaces
        fetch: async (req) => {
          services.logger.debug(`Incoming request: ${req.method} ${req.url}`);
          try {
            const response = await app.fetch(req);
            return response;
          } catch (error) {
            services.logger.error('Request handling error:', error);
            return new Response('Internal Server Error', { status: 500 });
          }
        },
        error: (error) => {
          services.logger.error('Server error:', error);
          return new Response('Internal Server Error', { status: 500 });
        },
      });

      services.logger.info(`Orchestrator service started on port ${server.port}`);
      services.logger.info(`Server hostname: ${server.hostname}`);
      services.logger.info(`Server URL: http://${server.hostname}:${server.port}`);
      
      // Test that server is actually listening
      setTimeout(async () => {
        try {
          const testResponse = await fetch(`http://localhost:${server.port}/health`);
          services.logger.info(`Server self-test: ${testResponse.status} ${testResponse.statusText}`);
        } catch (error) {
          services.logger.error('Server self-test failed:', error);
        }
      }, 1000);
    } catch (error) {
      services.logger.error('Failed to start Bun server:', error);
      throw error;
    }
    services.logger.info('Service metadata:', {
      version: '1.0.0',
      description: 'Trading System Orchestrator',
      defaultMode: serviceConfig.defaultMode,
      enableWebSocket: serviceConfig.enableWebSocket,
      endpoints: {
        health: '/health',
        orders: '/api/orders',
        positions: '/api/positions',
        analytics: '/api/analytics',
        backtest: '/api/backtest',
      }
    });
    
    // Note: Socket.IO with Bun requires a different setup
    // For now, we'll disable Socket.IO to avoid the CORS error
    if (serviceConfig.enableWebSocket) {
      services.logger.info('WebSocket support is enabled but Socket.IO integration with Bun requires additional setup');
    }

    // Graceful shutdown
    process.on('SIGINT', async () => {
      services.logger.info('Orchestrator service shutting down...');
      
      // Cleanup any active trading sessions
      const modeManager = services.custom?.ModeManager;
      if (modeManager) {
        await modeManager.shutdown();
      }
      
      if (server) {
        server.stop();
      }
      process.exit(0);
    });

  } catch (error) {
    logger.error('Failed to start orchestrator service:', error);
    process.exit(1);
  }
}

// Start the service
main().catch(error => {
  logger.error('Unhandled error:', error);
  process.exit(1);
});