#!/usr/bin/env node
import './config/env';
import { login } from './commands/login';
import { logout } from './commands/logout';
import { status } from './commands/status';
import { setEnabled } from './commands/toggle';
import { install, uninstall } from './commands/hooksCommand';
import { doctor } from './commands/doctor';
import { sync } from './commands/sync';
import { backfill } from './commands/backfill';
import { handleUserPromptSubmit, handleSessionStart, handleSessionEnd } from './hooks/handlers';
import { AGENT_VERSION } from './version';
import { close } from './storage/queue';

// SQLite is still marked experimental in this Node version; the CLI output
// (and hook stdout, which Claude Code may inspect) should stay clean.
process.removeAllListeners('warning');

function parseFlags(args: string[]): Record<string, string> {
  const flags: Record<string, string> = {};

  for (let i = 0; i < args.length; i++) {
    const arg = args[i];

    if (arg.startsWith('--')) {
      const key = arg.slice(2);
      const next = args[i + 1];

      if (next && !next.startsWith('--')) {
        flags[key] = next;
        i++;
      } else {
        flags[key] = 'true';
      }
    }
  }

  return flags;
}

async function main(): Promise<void> {
  const args = process.argv.slice(2);
  const command = args[0];
  const flags = parseFlags(args.slice(1));

  switch (command) {
    case 'login':
      await login({
        apiBaseUrl: flags['api-url'],
        organizationSlug: flags.org,
        activationToken: flags.token,
        deviceName: flags['device-name'],
      });
      break;

    case 'logout':
      await logout();
      break;

    case 'status':
      await status();
      break;

    case 'enable':
      setEnabled(true);
      break;

    case 'disable':
      setEnabled(false);
      break;

    case 'install':
      install();
      break;

    case 'uninstall':
      uninstall();
      break;

    case 'doctor':
      await doctor();
      break;

    case 'sync':
      await sync(flags.background === 'true');
      break;

    case 'backfill':
      await backfill(flags.days ? parseInt(flags.days, 10) : 30, flags['dry-run'] === 'true');
      break;

    case 'update':
      console.log('Reinstall the agent with your package manager to update (e.g. `npm install -g prompt-tracker-agent@latest`).');
      break;

    case 'version':
    case '--version':
    case '-v':
      console.log(AGENT_VERSION);
      break;

    case 'hook':
      await runHook(args[1]);
      break;

    default:
      printHelp();
      break;
  }
}

async function runHook(event: string | undefined): Promise<void> {
  switch (event) {
    case 'user-prompt-submit':
      await handleUserPromptSubmit();
      break;
    case 'session-start':
      await handleSessionStart();
      break;
    case 'session-end':
      await handleSessionEnd();
      break;
    default:
      // Unknown hook event: exit silently and successfully so Claude Code is never blocked.
      break;
  }
}

function printHelp(): void {
  console.log(`Buzy Prompt Tracker Agent (${AGENT_VERSION})

Usage: prompt-agent <command>

  login [--org <slug>] [--token <token>] [--api-url <url>]
  logout
  status
  enable
  disable
  install         Register Claude Code hooks
  uninstall       Remove hooks and local credentials
  doctor          Run diagnostics
  sync            Flush the offline queue now
  backfill [--days <n>] [--dry-run]
                  Import past prompts from Claude Code's own session
                  history (default: last 30 days)
  version
`);
}

main()
  .catch((error) => {
    console.error(error instanceof Error ? error.message : error);
    process.exitCode = 1;
  })
  .finally(() => close());
