#!/usr/bin/env node

import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { homedir, hostname } from 'node:os';
import { createInterface } from 'node:readline';
import { spawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const haverDir = join(homedir(), '.haver');
const haverKeyFile = join(haverDir, 'api_key');
const haverSettingsFile = join(haverDir, 'settings.json');
const haverGlobalConfig = join(haverDir, '.claude.json');

// --- Ensure ~/.haver exists with minimal config ---
if (!existsSync(haverDir)) mkdirSync(haverDir, { recursive: true });

if (!existsSync(haverSettingsFile)) {
  writeFileSync(haverSettingsFile, JSON.stringify({
    permissions: {
      allow: [
        "Bash(*)", "Edit(*)", "Write(*)", "Read(*)",
        "Glob(*)", "Grep(*)", "WebFetch(*)", "WebSearch(*)",
        "Task(*)", "Skill(*)", "NotebookEdit(*)"
      ]
    }
  }, null, 2), 'utf-8');
}

// --- Use separate config dir ---
process.env.CLAUDE_CONFIG_DIR = haverDir;

// --- Route traffic through Haver proxy ---
const haverBaseUrl = process.env.HAVER_BASE_URL || 'https://api.haver.ai';
if (!process.env.ANTHROPIC_BASE_URL) {
  process.env.ANTHROPIC_BASE_URL = haverBaseUrl;
}

// --- Resolve API key ---
if (process.env.HAVER_API_KEY) {
  process.env.ANTHROPIC_API_KEY = process.env.HAVER_API_KEY;
}
if (!process.env.ANTHROPIC_API_KEY) {
  try {
    if (existsSync(haverKeyFile)) {
      const key = readFileSync(haverKeyFile, 'utf-8').trim();
      if (key) process.env.ANTHROPIC_API_KEY = key;
    }
  } catch {}
}

// --- Prompt for key (first run or invalid key) ---
async function promptForKey() {
  console.log('');
  console.log('  \x1b[1mHaver Code\x1b[0m');
  console.log('');
  console.log('  Get your API key from \x1b[36mhttps://harrison.haver.ai/api-keys\x1b[0m');
  console.log('');

  const key = await new Promise((resolve) => {
    const rl = createInterface({ input: process.stdin, output: process.stdout });
    rl.question('  \x1b[1mHaver API Key:\x1b[0m ', (answer) => {
      rl.close();
      resolve(answer.trim());
    });
  });

  if (!key) {
    console.log('\n  No key provided. Exiting.\n');
    process.exit(1);
  }

  process.env.ANTHROPIC_API_KEY = key;
  writeFileSync(haverKeyFile, key, 'utf-8');
  console.log('  \x1b[32m✓\x1b[0m Key saved\n');
}

if (!process.env.ANTHROPIC_API_KEY) {
  await promptForKey();
}

// --- Validate the key before launching ---
if (process.env.ANTHROPIC_API_KEY?.startsWith('hs-')) {
  try {
    const res = await fetch(`${haverBaseUrl}/v1/haver/config`, {
      headers: { 'x-api-key': process.env.ANTHROPIC_API_KEY },
      signal: AbortSignal.timeout(5000),
    });
    if (res.status === 401 || res.status === 403) {
      console.log('\n  \x1b[31mAPI key is invalid or revoked.\x1b[0m\n');
      // Delete the bad saved key
      try { const { unlinkSync } = await import('node:fs'); unlinkSync(haverKeyFile); } catch {}
      process.env.ANTHROPIC_API_KEY = '';
      await promptForKey();
    }
  } catch {
    // Network error — proceed anyway, will fail later if key is actually bad
  }
}

// --- Pre-approve API key ---
try {
  const keyFingerprint = process.env.ANTHROPIC_API_KEY.slice(-20);
  let config = {};
  if (existsSync(haverGlobalConfig)) {
    try { config = JSON.parse(readFileSync(haverGlobalConfig, 'utf-8')); } catch {}
  }
  const approved = config.customApiKeyResponses?.approved ?? [];
  if (!approved.includes(keyFingerprint)) {
    config.customApiKeyResponses = {
      ...config.customApiKeyResponses,
      approved: [...approved, keyFingerprint],
      rejected: config.customApiKeyResponses?.rejected ?? [],
    };
    writeFileSync(haverGlobalConfig, JSON.stringify(config, null, 2), 'utf-8');
  }
} catch {}

// --- Determine mode ---
const args = process.argv.slice(2);
const connectOnly = args.includes('--connect');
const noConnect = args.includes('--no-connect');
// Strip our custom flags from process.argv so cli.js doesn't reject them
if (noConnect) {
  args.splice(args.indexOf('--no-connect'), 1);
  const idx = process.argv.indexOf('--no-connect');
  if (idx !== -1) process.argv.splice(idx, 1);
}
if (connectOnly) {
  const idx = process.argv.indexOf('--connect');
  if (idx !== -1) process.argv.splice(idx, 1);
}

if (connectOnly) {
  // --connect: SDK mode only, no interactive CLI
  args.splice(args.indexOf('--connect'), 1);

  const wsBase = haverBaseUrl.replace('https://', 'wss://').replace('http://', 'ws://');
  const device = hostname();
  const sdkUrl = `${wsBase}/v1/haver/sessions/connect?token=${encodeURIComponent(process.env.ANTHROPIC_API_KEY)}&device=${encodeURIComponent(device)}`;

  console.log('  \x1b[36mConnecting to Harrison...\x1b[0m');
  console.log(`  \x1b[2mDevice: ${device}\x1b[0m`);
  console.log('  \x1b[2mWaiting for prompts from dashboard...\x1b[0m\n');

  const cliPath = join(__dirname, 'cli.js');
  const child = spawn(process.execPath, [
    cliPath, '-p',
    '--sdk-url', sdkUrl,
    '--output-format', 'stream-json',
    '--input-format', 'stream-json',
    ...args,
  ], { stdio: ['pipe', 'inherit', 'inherit'], env: process.env });

  child.on('exit', (code) => process.exit(code ?? 0));
  process.on('SIGINT', () => child.kill('SIGINT'));
  process.on('SIGTERM', () => child.kill('SIGTERM'));

} else {
  // Normal interactive mode
  // Background SDK connection disabled by default — causes 500 errors from concurrent requests.
  // Use `haver --connect` for remote-controllable mode instead.
  if (false && !noConnect && process.env.ANTHROPIC_API_KEY?.startsWith('hs-')) {
    try {
      const wsBase = haverBaseUrl.replace('https://', 'wss://').replace('http://', 'ws://');
      const device = hostname();
      const sdkUrl = `${wsBase}/v1/haver/sessions/connect?token=${encodeURIComponent(process.env.ANTHROPIC_API_KEY)}&device=${encodeURIComponent(device)}`;

      const cliPath = join(__dirname, 'cli.js');
      const bgChild = spawn(process.execPath, [
        cliPath, '-p',
        '--sdk-url', sdkUrl,
        '--output-format', 'stream-json',
        '--input-format', 'stream-json',
      ], {
        stdio: ['pipe', 'ignore', 'ignore'],
        env: process.env,
        detached: true,
      });

      // Don't let the background process prevent exit
      bgChild.unref();

      // Kill background process on exit
      process.on('exit', () => { try { bgChild.kill(); } catch {} });
      process.on('SIGINT', () => { try { bgChild.kill(); } catch {} });
      process.on('SIGTERM', () => { try { bgChild.kill(); } catch {} });
    } catch {}
  }

  // Load the interactive CLI
  import('./cli.js');
}
