#!/usr/bin/env node

/**
 * VDS Skill Pack — dependency installer
 *
 * Cross-platform (Windows, Linux, macOS).
 *
 * Usage:
 *   node install-deps.mjs <projectPath> <packDir> [--force]
 *
 * What it does:
 *   1. Checks Python >= 3.12
 *   2. Ensures uv is installed
 *   3. Copies runtime to ~/.claude/vds-scripts/
 *   4. Runs uv sync
 *   5. Provisions .env template at ~/.vds/.env
 */

import { execSync } from 'child_process';
import { existsSync, cpSync, mkdirSync, writeFileSync, rmSync, readFileSync } from 'fs';
import { join } from 'path';
import { homedir } from 'os';

const IS_WIN = process.platform === 'win32';
const IS_MAC = process.platform === 'darwin';

let _resolvedPython;

function resolvePython() {
  if (_resolvedPython) return _resolvedPython;
  const candidates = IS_WIN
    ? ['python3', 'python', 'py']
    : ['python3', 'python'];
  for (const cmd of candidates) {
    try {
      const out = execSync(`${cmd} --version`, { encoding: 'utf-8', stdio: 'pipe' });
      if (out.includes('Python')) { _resolvedPython = cmd; return cmd; }
    } catch { /* not available */ }
  }
  _resolvedPython = IS_WIN ? 'python' : 'python3';
  return _resolvedPython;
}

const PYTHON = resolvePython();
const VDS_DIR = join(homedir(), '.claude', 'vds-scripts');
const ENV_DIR = join(homedir(), '.vds');
const ENV_FILE = join(ENV_DIR, '.env');

const [, , projectPath, packDir] = process.argv;
const force = process.argv.includes('--force');

// ── Helpers ──

function log(icon, msg) {
  console.log(`  ${icon} ${msg}`);
}

// ── 1. Check Python >= 3.12 ──

function checkPython() {
  try {
    const output = execSync(`${PYTHON} --version`, { encoding: 'utf-8', stdio: 'pipe' });
    const match = output.match(/Python (\d+)\.(\d+)/);
    if (!match) {
      printPythonGuide();
      process.exit(1);
    }
    const major = Number(match[1]);
    const minor = Number(match[2]);
    if (major < 3 || (major === 3 && minor < 12)) {
      printPythonGuide(major, minor);
      process.exit(1);
    }
    return `${major}.${minor}`;
  } catch {
    printPythonGuide();
    process.exit(1);
  }
}

function printPythonGuide(major, minor) {
  const current = major ? `${major}.${minor}` : 'not found';
  console.error(`\n  ✗ Python >= 3.12 required (current: ${current})\n`);
  if (IS_WIN) {
    console.error('    Install: winget install Python.Python.3.12');
    console.error('    Or download from: https://www.python.org/downloads/\n');
  } else if (IS_MAC) {
    console.error('    Install: brew install python@3.12\n');
  } else {
    console.error('    Install: sudo apt install python3');
    console.error('    Or use pyenv: pyenv install 3.12\n');
  }
}

// ── 2. Ensure uv ──

function resolveUv() {
  // 1. On PATH?
  try {
    execSync('uv --version', { stdio: 'pipe' });
    return 'uv';
  } catch { /* not on PATH */ }

  // 2. Check common install locations
  const fallbacks = IS_WIN
    ? [
        join(homedir(), '.local', 'bin', 'uv.exe'),
        join(process.env.LOCALAPPDATA || '', 'uv', 'uv.exe'),
      ]
    : [
        join(homedir(), '.local', 'bin', 'uv'),
        join(homedir(), '.cargo', 'bin', 'uv'),
      ];

  for (const p of fallbacks) {
    try {
      execSync(`"${p}" --version`, { stdio: 'pipe' });
      return `"${p}"`;
    } catch { /* not here */ }
  }

  return null;
}

function ensureUv() {
  let uv = resolveUv();
  if (uv) return uv;

  log('⬇️', 'uv not found — installing...');

  if (IS_WIN) {
    try {
      execSync(
        'powershell -ExecutionPolicy Bypass -c "irm https://astral.sh/uv/install.ps1 | iex"',
        { stdio: 'inherit' },
      );
    } catch {
      console.error('  ✗ uv install via PowerShell failed');
      process.exit(1);
    }
  } else if (IS_MAC) {
    try {
      execSync('HOMEBREW_NO_AUTO_UPDATE=1 brew install uv', { stdio: 'inherit' });
    } catch {
      // Fallback to curl
      try {
        execSync('curl -LsSf https://astral.sh/uv/install.sh | sh', { stdio: 'inherit' });
      } catch {
        console.error('  ✗ uv install failed (tried brew and curl)');
        process.exit(1);
      }
    }
  } else {
    try {
      execSync('curl -LsSf https://astral.sh/uv/install.sh | sh', { stdio: 'inherit' });
    } catch {
      console.error('  ✗ uv install via curl failed');
      process.exit(1);
    }
  }

  uv = resolveUv();
  if (!uv) {
    console.error('  ✗ uv not found after install — restart terminal or add to PATH');
    process.exit(1);
  }
  return uv;
}

// ── 3. Copy runtime ──

function copyRuntime() {
  const runtimeSrc = join(packDir, 'runtime');
  if (existsSync(VDS_DIR) && !force) {
    log('⊘', `vds-scripts already exists at ${VDS_DIR}`);
    return;
  }
  if (existsSync(VDS_DIR) && force) {
    rmSync(VDS_DIR, { recursive: true, force: true });
  }
  mkdirSync(VDS_DIR, { recursive: true });
  cpSync(runtimeSrc, VDS_DIR, { recursive: true });
  log('✓', `vds-scripts copied to ${VDS_DIR}`);
}

// ── 4. uv sync ──

function uvSync(uvCmd) {
  execSync(`${uvCmd} sync`, { cwd: VDS_DIR, stdio: 'inherit' });
  log('✓', 'uv sync completed');
}

// ── 5. Provision .env ──

const ENV_TEMPLATE = `# VDS Environment Configuration
# Fill in your credentials below
# Location: ~/.vds/.env

# ── Authentication ──
VDS_USERNAME=
VDS_PASSWORD=

# ── Jira ──
JIRA_BASE_URL=
# JIRA_TOKEN=

# ── Jira ViettelMoney ──
JIRA_VIETTELMONEY_BASE_URL=
# JIRA_VIETTELMONEY_USERNAME=
# JIRA_VIETTELMONEY_PASSWORD=
# JIRA_VIETTELMONEY_PROXY=

# ── Bitbucket ──
VDS_BITBUCKET_URL=
BITBUCKET_ACCESS_TOKEN=
# BITBUCKET_TOKEN=
# BITBUCKET_MODE=server
# BITBUCKET_CLOUD_WORKSPACE=

# ── Confluence ──
CONFLUENCE_INTERNAL_URL=
CONFLUENCE_EXTERNAL_URL=
INTERNAL_CONFLUENCE_TOKEN=
EXTERNAL_CONFLUENCE_TOKEN=

# ── Git ──
VDS_GIT_PROJECTS=
VDS_GIT_CONCURRENCY_DEFAULT=8

# ── Optional ──
# VDS_GIT_HTTP_TIMEOUT=300
# VDS_GIT_RETRIES=2
# VDS_GIT_BACKOFF=1.5
# VDS_GIT_HTTP_POST_BUFFER=524288000
# VDS_GIT_HTTP_LOW_SPEED_LIMIT=1000
# VDS_GIT_HTTP_LOW_SPEED_TIME=300
# VDS_GIT_AUTO_REGENERATE_MANIFEST=
`;

function provisionEnv() {
  mkdirSync(ENV_DIR, { recursive: true });

  if (!existsSync(ENV_FILE)) {
    writeFileSync(ENV_FILE, ENV_TEMPLATE, 'utf-8');
    log('✓', `.env template created at ${ENV_FILE}`);
    log('⚠', `Fill in your credentials: ${ENV_FILE}`);
    return;
  }

  if (force) {
    writeFileSync(ENV_FILE, ENV_TEMPLATE, 'utf-8');
    log('✓', `.env overwritten at ${ENV_FILE}`);
    log('⚠', `Fill in your credentials: ${ENV_FILE}`);
    return;
  }

  // Merge: add missing variables from template into existing .env
  const existing = readFileSync(ENV_FILE, 'utf-8');
  const existingKeys = new Set(
    existing.split('\n')
      .map(line => line.trim())
      .filter(line => line && !line.startsWith('#'))
      .map(line => line.split('=')[0].trim()),
  );

  const newLines = [];
  for (const line of ENV_TEMPLATE.split('\n')) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith('#')) continue;
    const key = trimmed.split('=')[0].trim();
    if (!existingKeys.has(key)) {
      newLines.push(line);
    }
  }

  if (newLines.length > 0) {
    const append = '\n# ── Added by vds-skill installer ──\n' + newLines.join('\n') + '\n';
    writeFileSync(ENV_FILE, existing.trimEnd() + '\n' + append, 'utf-8');
    log('✓', `${newLines.length} new variable(s) added to ${ENV_FILE}`);
    for (const line of newLines) {
      log('  +', line.split('=')[0]);
    }
  } else {
    log('⊘', `.env already up-to-date at ${ENV_FILE}`);
  }
}

// ── Main ──

console.log('\n[vds-skill] Checking Python...');
const pyVer = checkPython();
log('✓', `Python ${pyVer}`);

console.log('[vds-skill] Ensuring uv...');
const uvCmd = ensureUv();
log('✓', 'uv ready');

console.log('[vds-skill] Setting up vds-scripts runtime...');
copyRuntime();

console.log('[vds-skill] Running uv sync...');
uvSync(uvCmd);

console.log('[vds-skill] Provisioning .env...');
provisionEnv();

console.log('\n[vds-skill] Setup complete ✅\n');
