// cli/commands/uninstall.js
// clauth uninstall — full teardown: DB objects, Edge Function, secrets, skill, local config
//
// Reverses everything `clauth install` does:
//   1. Drops clauth tables, policies, triggers, functions from Supabase
//   2. Deletes auth-vault Edge Function
//   3. Removes CLAUTH_* secrets
//   4. Removes Claude skill directory
//   5. Clears local config (Conf store)

import { existsSync, rmSync } from 'fs';
import { join } from 'path';
import Conf from 'conf';
import chalk from 'chalk';
import ora from 'ora';

const MGMT = 'https://api.supabase.com/v1';
const SKILLS_DIR = process.env.CLAUTH_SKILLS_DIR ||
  (process.platform === 'win32'
    ? join(process.env.USERPROFILE || '', '.claude', 'skills')
    : join(process.env.HOME || '', '.claude', 'skills'));

// ─────────────────────────────────────────────
// Supabase Management API helper
// ─────────────────────────────────────────────
async function mgmt(pat, method, path, body) {
  const res = await fetch(`${MGMT}${path}`, {
    method,
    headers: { 'Authorization': `Bearer ${pat}`, 'Content-Type': 'application/json' },
    body: body ? JSON.stringify(body) : undefined,
  });
  if (!res.ok) {
    const text = await res.text().catch(() => res.statusText);
    throw new Error(`${method} ${path} → HTTP ${res.status}: ${text}`);
  }
  if (res.status === 204) return {};
  const text = await res.text();
  if (!text) return {};
  return JSON.parse(text);
}

// ─────────────────────────────────────────────
// Main uninstall command
// ─────────────────────────────────────────────
export async function runUninstall(opts = {}) {
  console.log(chalk.red('\n🗑️  clauth uninstall\n'));

  const config = new Conf({ projectName: 'clauth' });

  // ── Collect credentials ────────────────────
  const ref = opts.ref || config.get('supabase_url')?.match(/https:\/\/(.+)\.supabase\.co/)?.[1];
  const pat = opts.pat;

  if (!ref) {
    console.log(chalk.red('  Cannot determine Supabase project ref.'));
    console.log(chalk.gray('  Use: clauth uninstall --ref <project-ref> --pat <personal-access-token>'));
    process.exit(1);
  }
  if (!pat) {
    console.log(chalk.red('  Supabase PAT required for teardown.'));
    console.log(chalk.gray('  Use: clauth uninstall --ref <project-ref> --pat <personal-access-token>'));
    process.exit(1);
  }

  console.log(chalk.gray(`  Project: ${ref}\n`));

  // ── Step 1: Drop database objects ──────────
  const s1 = ora('Dropping clauth database objects...').start();
  const teardownSQL = `
    -- Drop triggers
    DROP TRIGGER IF EXISTS clauth_services_updated ON public.clauth_services;

    -- Drop tables (CASCADE drops policies automatically)
    DROP TABLE IF EXISTS public.clauth_audit CASCADE;
    DROP TABLE IF EXISTS public.clauth_machines CASCADE;
    DROP TABLE IF EXISTS public.clauth_services CASCADE;

    -- Drop functions
    DROP FUNCTION IF EXISTS public.clauth_touch_updated() CASCADE;
    DROP FUNCTION IF EXISTS public.clauth_upsert_vault_secret(text, text) CASCADE;
    DROP FUNCTION IF EXISTS public.clauth_get_vault_secret(text) CASCADE;
    DROP FUNCTION IF EXISTS public.clauth_delete_vault_secret(text) CASCADE;
  `;

  try {
    await mgmt(pat, 'POST', `/projects/${ref}/database/query`, { query: teardownSQL });
    s1.succeed('Database objects dropped (tables, triggers, functions, policies)');
  } catch (e) {
    s1.fail(`Database teardown failed: ${e.message}`);
    console.log(chalk.yellow('  You may need to drop objects manually via SQL editor.'));
  }

  // ── Step 2: Delete Edge Function ───────────
  const s2 = ora('Deleting auth-vault Edge Function...').start();
  try {
    const res = await fetch(`${MGMT}/projects/${ref}/functions/auth-vault`, {
      method: 'DELETE',
      headers: { 'Authorization': `Bearer ${pat}` },
    });
    if (res.ok || res.status === 404) {
      s2.succeed(res.status === 404
        ? 'Edge Function not found (already deleted)'
        : 'Edge Function deleted');
    } else {
      const text = await res.text().catch(() => res.statusText);
      throw new Error(`HTTP ${res.status}: ${text}`);
    }
  } catch (e) {
    s2.fail(`Edge Function delete failed: ${e.message}`);
    console.log(chalk.yellow('  Delete manually: Supabase Dashboard → Edge Functions → auth-vault → Delete'));
  }

  // ── Step 3: Remove secrets ─────────────────
  const s3 = ora('Removing clauth secrets...').start();
  try {
    // Supabase Management API: DELETE /projects/{ref}/secrets with body listing secret names
    const res = await fetch(`${MGMT}/projects/${ref}/secrets`, {
      method: 'DELETE',
      headers: { 'Authorization': `Bearer ${pat}`, 'Content-Type': 'application/json' },
      body: JSON.stringify(['CLAUTH_HMAC_SALT', 'CLAUTH_ADMIN_BOOTSTRAP_TOKEN']),
    });
    if (res.ok) {
      s3.succeed('Secrets removed (CLAUTH_HMAC_SALT, CLAUTH_ADMIN_BOOTSTRAP_TOKEN)');
    } else {
      const text = await res.text().catch(() => res.statusText);
      throw new Error(`HTTP ${res.status}: ${text}`);
    }
  } catch (e) {
    s3.warn(`Secret removal failed: ${e.message}`);
    console.log(chalk.yellow('  Remove manually: Supabase → Settings → Edge Functions → Secrets'));
  }

  // ── Step 4: Remove Claude skill ────────────
  const s4 = ora('Removing Claude skill...').start();
  const skillDir = join(SKILLS_DIR, 'clauth');
  if (existsSync(skillDir)) {
    try {
      rmSync(skillDir, { recursive: true, force: true });
      s4.succeed(`Skill removed: ${skillDir}`);
    } catch (e) {
      s4.warn(`Could not remove skill: ${e.message}`);
    }
  } else {
    s4.succeed('Skill directory not found (already removed)');
  }

  // ── Step 5: Clear local config ─────────────
  const s5 = ora('Clearing local config...').start();
  try {
    config.clear();
    s5.succeed('Local config cleared');
  } catch (e) {
    s5.warn(`Could not clear config: ${e.message}`);
  }

  // ── Done ───────────────────────────────────
  console.log('');
  console.log(chalk.red('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
  console.log(chalk.yellow('  ✓ clauth fully uninstalled'));
  console.log(chalk.red('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
  console.log('');
  console.log(chalk.gray('  To reinstall: npx @lifeaitools/clauth install'));
  console.log('');
}
