#!/usr/bin/env node
/**
 * ═══════════════════════════════════════════════════════════════════════════════
 * INSTALL-DEPENDENCIES SCRIPT (SIMPLIFIÉ)
 * ═══════════════════════════════════════════════════════════════════════════════
 * Script cross-platform qui détecte et installe uniquement ce qui manque :
 * - Docker Desktop / Docker Engine
 * - PostgreSQL + pgvector (uniquement)
 *
 * Supporte: Windows (Docker Desktop), Linux (Docker Engine), macOS (Docker Desktop)
 * ═══════════════════════════════════════════════════════════════════════════════
 */

import { execSync, spawn } from 'child_process';
import { existsSync } from 'fs';
import { join } from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import { createInterface } from 'readline';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// ═══════════════════════════════════════════════════════════════════════════════
// UTILS
// ═══════════════════════════════════════════════════════════════════════════════

function logSection(title) {
  console.log('\n╔══════════════════════════════════════════════════════════════════╗');
  console.log(`║  ${title.padEnd(64)} ║`);
  console.log('╚══════════════════════════════════════════════════════════════════╝');
}

function runCommand(cmd, options = {}) {
  try {
    return execSync(cmd, { stdio: 'pipe', encoding: 'utf8', ...options });
  } catch {
    return null;
  }
}

function runCommandAsync(cmd, description) {
  return new Promise((resolve, reject) => {
    console.log(`🔧 ${description}`);
    console.log(`   $ ${cmd}`);

    const child = spawn(cmd, { shell: true, stdio: 'inherit' });

    child.on('close', (code) => {
      if (code === 0) {
        console.log(`✅ ${description} terminé`);
        resolve(true);
      } else {
        console.error(`❌ Erreur (code ${code})`);
        reject(new Error(`Command failed with code ${code}`));
      }
    });

    child.on('error', (err) => {
      console.error('❌ Erreur:', err.message);
      reject(err);
    });
  });
}

function promptYesNo(question) {
  const rl = createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  return new Promise((resolve) => {
    rl.question(`${question} (y/N): `, (answer) => {
      rl.close();
      resolve(answer.toLowerCase().startsWith('y'));
    });
  });
}

function openUrl(url) {
  const platform = process.platform;

  if (platform === 'win32') {
    runCommand(`start ${url}`, { stdio: 'ignore' });
  } else if (platform === 'darwin') {
    runCommand(`open ${url}`, { stdio: 'ignore' });
  } else {
    runCommand(`xdg-open ${url}`, { stdio: 'ignore' });
  }
}

// ═══════════════════════════════════════════════════════════════════════════════
// DOCKER DETECTION
// ═══════════════════════════════════════════════════════════════════════════════

async function checkDocker() {
  logSection('VÉRIFICATION DOCKER');

  // Check if Docker is installed
  const version = runCommand('docker --version');
  if (!version) {
    console.log('❌ Docker non trouvé');
    return null;
  }

  console.log('✅ Docker détecté:', version.trim());

  // Detect Docker Desktop vs Docker Engine
  const platform = process.platform;

  if (platform === 'win32' || platform === 'darwin') {
    // Windows/macOS: Check Docker Desktop
    const desktopStatus = runCommand('docker info --format "{{.OperatingSystem}}"');
    if (desktopStatus?.includes('Docker Desktop')) {
      console.log('✅ Docker Desktop détecté');
      return { type: 'desktop', platform };
    }
  } else if (platform === 'linux') {
    // Linux: Docker Engine
    console.log('✅ Docker Engine (Linux) détecté');
    return { type: 'engine', platform };
  }

  return { type: 'unknown', platform };
}

async function installDockerIfNeeded() {
  const dockerInfo = await checkDocker();

  if (dockerInfo) {
    return dockerInfo;
  }

  console.log('');
  console.log('📥 Installation Docker requise:');
  console.log('   • Windows: Docker Desktop for Windows');
  console.log('   • macOS: Docker Desktop for Mac');
  console.log('   • Linux: Docker Engine (apt/yum/dnf)');
  console.log('');

  const answer = await promptYesNo('Voulez-vous ouvrir le site de téléchargement ?');
  if (answer) {
    const url = 'https://www.docker.com/products/docker-desktop/';
    openUrl(url);
    console.log('✅ Navigateur ouvert. Installez Docker, puis relancez ce script.');
  }

  return null;
}

// ═══════════════════════════════════════════════════════════════════════════════
// POSTGRESQL + PGVECTOR DETECTION & INSTALLATION
// ═══════════════════════════════════════════════════════════════════════════════

async function detectExistingPostgreSQL() {
  logSection('DÉTECTION POSTGRESQL EXISTANT');

  // 1. Check native PostgreSQL (psql command)
  const nativePg = runCommand('psql --version');
  if (nativePg) {
    console.log('✅ PostgreSQL natif détecté:', nativePg.trim());

    // Check if pgvector is installed
    const pgvectorCheck = runCommand('psql -U postgres -t -c "SELECT extname FROM pg_extension WHERE extname = \'vector\';"');
    if (pgvectorCheck?.includes('vector')) {
      console.log('✅ pgvector est installé');
      return { type: 'native', hasPgvector: true };
    } else {
      console.log('⚠️  pgvector NON installé (installation manuelle requise)');
      return { type: 'native', hasPgvector: false };
    }
  }

  // 2. Check Docker containers with pgvector (multiple detection methods)
  console.log('🔍 Recherche containers PostgreSQL avec pgvector...');

  // Method A: Check by image name (pgvector/pgvector)
  let containers = runCommand('docker ps --filter "ancestor=pgvector/pgvector" --format "{{.Names}}"', {
    stdio: 'pipe'
  });

  // Method B: Check all containers with "pgvector" or "postgres" in name
  if (!containers) {
    containers = runCommand('docker ps --format "{{.Names}}" | grep -E "(pgvector|postgres)"', {
      stdio: 'pipe',
      shell: true
    });
  }

  if (containers) {
    const containerList = containers.trim().split('\n').filter(Boolean);
    console.log(`✅ ${containerList.length} container(s) PostgreSQL détecté(s):`);
    containerList.forEach(name => console.log(`   • ${name}`));

    // Check each container for pgvector
    for (const container of containerList) {
      try {
        const pgvectorCheck = runCommand(
          `docker exec ${container} psql -U postgres -t -c "SELECT extname FROM pg_extension WHERE extname = 'vector';" 2>&1`,
          { stdio: 'pipe' }
        );

        if (pgvectorCheck?.includes('vector')) {
          console.log(`✅ pgvector actif dans ${container}`);
          return { type: 'docker', container, hasPgvector: true };
        }
      } catch {
        // Container might not be accessible, try next
      }
    }

    console.log('⚠️  Containers trouvés mais SANS pgvector installé');
  }

  // 3. Check for any PostgreSQL container (might not have pgvector)
  const allContainers = runCommand('docker ps --format "{{.Names}}"', {
    stdio: 'pipe'
  });

  if (allContainers) {
    const pgContainers = allContainers
      .trim()
      .split('\n')
      .filter(name => name.toLowerCase().includes('postgres') || name.toLowerCase().includes('pgvector'));

    if (pgContainers.length > 0) {
      console.log(`⚠️  ${pgContainers.length} container(s) PostgreSQL détecté(s) SANS pgvector:`);
      pgContainers.forEach(name => console.log(`   • ${name}`));
      console.log('');
      console.log('💡 Le script va créer un nouveau container dédié.');
    }
  }

  if (genericContainers) {
    const containerList = genericContainers.trim().split('\n').filter(Boolean);
    console.log(`⚠️  ${containerList.length} container(s) PostgreSQL détecté(s) SANS pgvector:`);
    containerList.forEach(name => console.log(`   • ${name}`));
    console.log('');
    console.log('💡 Ces containers n\'ont PAS pgvector. Le script va créer un nouveau container dédié.');
  }

  return null;
}

async function waitForPostgreSQL(containerName, maxWait = 60) {
  console.log(`⏳ Attente démarrage PostgreSQL (max ${maxWait}s)...`);

  for (let i = 0; i < maxWait; i++) {
    try {
      execSync(
        `docker exec ${containerName} pg_isready -U postgres`,
        { stdio: 'pipe', encoding: 'utf8' }
      );
      console.log('✅ PostgreSQL prêt !');
      return true;
    } catch {
      process.stdout.write('.');
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }

  console.log('');
  console.log('❌ Timeout: PostgreSQL n\'a pas démarré à temps');
  return false;
}

async function installPostgreSQLDocker() {
  logSection('INSTALLATION POSTGRESQL + PGVECTOR (DOCKER)');

  const containerName = 'overmind-postgres-pgvector';

  try {
    // Pull image
    console.log('📥 Téléchargement image pgvector/pgvector:pg16...');
    await runCommandAsync(
      'docker pull pgvector/pgvector:pg16',
      'Téléchargement image'
    );

    // Remove existing container if present
    try {
      execSync(`docker inspect ${containerName}`, { stdio: 'pipe' });
      console.log(`⚠️  Container ${containerName} existe déjà. Suppression...`);
      execSync(`docker rm -f ${containerName}`, { stdio: 'pipe' });
    } catch {
      // Container doesn't exist, that's fine
    }

    // Create volume if doesn't exist
    try {
      execSync('docker volume create overmind_postgres_data', { stdio: 'pipe' });
    } catch {
      // Volume might already exist
    }

    // Run container
    console.log('🚀 Démarrage container PostgreSQL...');
    const runCommand = [
      'docker', 'run', '-d',
      '--name', containerName,
      '-p', '5432:5432',
      '-e', 'POSTGRES_PASSWORD=overmind_temp_password_change_me',
      '-e', 'POSTGRES_USER=postgres',
      '-v', 'overmind_postgres_data:/var/lib/postgresql/data',
      '--restart', 'unless-stopped',
      'pgvector/pgvector:pg16'
    ].join(' ');

    await runCommandAsync(runCommand, 'Démarrage PostgreSQL');

    // Wait for PostgreSQL to be ready
    const ready = await waitForPostgreSQL(containerName);
    if (!ready) {
      throw new Error('PostgreSQL n\'a pas démarré');
    }

    // Test connection
    console.log('🔍 Test connexion PostgreSQL...');
    await runCommandAsync(
      `docker exec ${containerName} psql -U postgres -c "SELECT version();"`,
      'Test connexion'
    );

    // Enable pgvector
    console.log('🔧 Activation extension pgvector...');
    await runCommandAsync(
      `docker exec ${containerName} psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS vector;"`,
      'Activation pgvector'
    );

    // Verify pgvector
    console.log('✅ Vérification pgvector...');
    const result = runCommand(
      `docker exec ${containerName} psql -U postgres -t -c "SELECT extname FROM pg_extension WHERE extname = 'vector';"`,
      { encoding: 'utf8', stdio: 'pipe' }
    ).trim();

    if (result.includes('vector')) {
      console.log('✅ pgvector installé avec succès !');
    } else {
      throw new Error('pgvector non trouvé');
    }

    console.log('');
    console.log('🎉 PostgreSQL + pgvector installés !');
    console.log('');
    console.log('📋 Détails:');
    console.log(`   Container: ${containerName}`);
    console.log('   Port: 5432');
    console.log('   User: postgres');
    console.log('   Password: overmind_temp_password_change_me (À CHANGER !)');
    console.log('   Extension: vector (pgvector)');

    return { type: 'docker', container: containerName, hasPgvector: true };

  } catch (error) {
    console.error('❌ Erreur installation PostgreSQL:', error.message);
    console.error('');
    console.log('💡 Solution manuelle:');
    console.log(`   docker run -d --name ${containerName} \\`);
    console.log('     -p 5432:5432 \\');
    console.log('     -e POSTGRES_PASSWORD=votre_pass \\');
    console.log('     -e POSTGRES_USER=postgres \\');
    console.log('     -v overmind_postgres_data:/var/lib/postgresql/data \\');
    console.log('     --restart unless-stopped \\');
    console.log('     pgvector/pgvector:pg16');
    console.log('');
    console.log('Ou en une ligne (Windows):');
    console.log(`   docker run -d --name ${containerName} -p 5432:5432 -e POSTGRES_PASSWORD=votre_pass -e POSTGRES_USER=postgres -v overmind_postgres_data:/var/lib/postgresql/data --restart unless-stopped pgvector/pgvector:pg16`);
    return null;
  }
}

// ═══════════════════════════════════════════════════════════════════════════════
// MAIN
// ═══════════════════════════════════════════════════════════════════════════════

async function main() {
  console.log('╔══════════════════════════════════════════════════════════════════╗');
  console.log('║                                                                ║');
  console.log('║     🗄️️  INSTALLATION POSTGRESQL + PGVECTOR                          ║');
  console.log('║     Détection & Installation Automatique                          ║');
  console.log('║                                                                ║');
  console.log('╚══════════════════════════════════════════════════════════════════╝');
  console.log('');

  // Step 1: Check/Install Docker
  const dockerInfo = await installDockerIfNeeded();
  if (!dockerInfo) {
    console.log('\n⚠️  Relancez ce script après avoir installé Docker.');
    process.exit(1);
  }

  console.log('');
  console.log(`📊 Plateforme: ${dockerInfo.type} (${dockerInfo.platform})`);
  console.log('');

  // Step 2: Detect existing PostgreSQL
  const existingPg = await detectExistingPostgreSQL();

  if (existingPg && existingPg.hasPgvector) {
    console.log('');
    console.log('✅ PostgreSQL + pgvector sont déjà installés !');

    if (existingPg.type === 'docker') {
      console.log(`   Container: ${existingPg.container}`);
      console.log('   Port: 5432');
      console.log('   User: postgres');
      console.log('   Extension: vector (pgvector)');
    } else if (existingPg.type === 'native') {
      console.log('   Installation native détectée');
      console.log('   Extension: vector (pgvector)');
    }

    console.log('');
    console.log('🎉 Rien à installer !');

    return;
  }

  // Step 3: Install PostgreSQL + pgvector
  console.log('');
  console.log('📦 Installation de PostgreSQL + pgvector requise...');

  const installResult = await installPostgreSQLDocker();
  if (!installResult) {
    console.log('\n⚠️  Installation échouée. Vérifiez les erreurs ci-dessus.');
    process.exit(1);
  }

  // Success
  logSection('✅ INSTALLATION TERMINÉE');

  console.log(`
🎉 PostgreSQL + pgvector sont prêts !

📋 PROCHAINE ÉTAPE:
   → Relancez: overmind-setup
   Ou manuellement: npm install -g overmind-mcp

💡 RAPPEL:
   • Container: ${installResult.container}
   • Port: 5432
   • User: postgres
   • Password: overmind_temp_password_change_me (CHANGEZ-LE !)
   • Extension: vector (pgvector)

═════════════════════════════════════════════════════════════════════
`);
}

// Run main
// Check if this file is being run directly (not imported)
const modulePath = fileURLToPath(import.meta.url);
const isMainModule = process.argv[1] === modulePath;

if (isMainModule) {
  main().catch((error) => {
    console.error('\n❌ ERREUR FATALE:', error.message);
    process.exit(1);
  });
}
