import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { json, urlencoded } from 'express';
import { spawn, ChildProcess } from 'child_process';
import * as path from 'path';
import * as fs from 'fs';

let pythonProcess: ChildProcess | null = null;

function startPythonAI() {
  // Resolve path to python-ai directory (relative to backend root)
  const backendRoot = path.resolve(__dirname, '..');
  const pythonDir = path.join(backendRoot, 'python-ai');

  // Determine the venv python executable (Windows vs Linux/Mac)
  const isWindows = process.platform === 'win32';
  const pythonExe = isWindows
    ? path.join(pythonDir, 'venv', 'Scripts', 'python.exe')
    : path.join(pythonDir, 'venv', 'bin', 'python');

  if (!fs.existsSync(pythonExe)) {
    console.warn('[Python AI] ⚠️  Venv not found at', pythonExe, '— skipping AI engine auto-start.');
    return;
  }

  console.log('[Python AI] 🚀 Starting AI Engine...');

  pythonProcess = spawn(
    pythonExe,
    ['-m', 'uvicorn', 'main:app', '--host', '0.0.0.0', '--port', '8000'],
    {
      cwd: pythonDir,
      stdio: ['ignore', 'pipe', 'pipe'],
      env: { ...process.env, PYTHONUNBUFFERED: '1' },
    },
  );

  pythonProcess.stdout?.on('data', (data: Buffer) => {
    const lines = data.toString().trim().split('\n');
    lines.forEach((line) => console.log(`[Python AI] ${line}`));
  });

  pythonProcess.stderr?.on('data', (data: Buffer) => {
    const lines = data.toString().trim().split('\n');
    lines.forEach((line) => console.log(`[Python AI] ${line}`));
  });

  pythonProcess.on('error', (err) => {
    console.error('[Python AI] ❌ Failed to start:', err.message);
  });

  pythonProcess.on('exit', (code, signal) => {
    if (code !== null) {
      console.log(`[Python AI] Process exited with code ${code}`);
    } else {
      console.log(`[Python AI] Process killed by signal ${signal}`);
    }
    pythonProcess = null;
  });
}

function stopPythonAI() {
  if (pythonProcess) {
    console.log('[Python AI] 🛑 Shutting down AI Engine...');
    pythonProcess.kill('SIGTERM');
    pythonProcess = null;
  }
}

async function bootstrap() {
  // Start Python AI engine first (non-blocking)
  startPythonAI();

  const app = await NestFactory.create(AppModule);
  app.enableCors({
    origin: true,
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
    credentials: true,
  });
  
  // Increase payload size limit for Video pitches (Base64 is large)
  app.use(json({ limit: '50mb' }));
  app.use(urlencoded({ extended: true, limit: '50mb' }));

  // Clean up Python process on exit
  const shutdown = () => { stopPythonAI(); process.exit(0); };
  process.on('SIGINT', shutdown);
  process.on('SIGTERM', shutdown);

  const preferredPort = Number(process.env.PORT ?? 3001);
  try {
    await app.listen(preferredPort, '0.0.0.0');
  } catch (e: any) {
    if (e?.code === 'EADDRINUSE' && preferredPort === 3001) {
      const fallbackPort = 3002;
      // eslint-disable-next-line no-console
      console.warn(`[Nest] Port 3001 in use. Falling back to ${fallbackPort}. Set PORT env to override.`);
      await app.listen(fallbackPort, '0.0.0.0');
    } else {
      throw e;
    }
  }
}
bootstrap();
