#!/usr/bin/env bun
/**
 * Copies Janus auth templates to their destinations and writes env vars.
 * If existing auth is detected, requires --force to replace it.
 * Safe to run multiple times — env blocks are not duplicated.
 *
 * Usage:
 *   bun install-files.ts \
 *     --client-id=<id> \
 *     --client-secret=<secret> \
 *     --redirect-uri=<uri> \
 *     --humand-app-url=<url> \
 *     [--force]
 */
import { copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';

// ── Args ──────────────────────────────────────────────────────────────────────

const args = Object.fromEntries(
  process.argv.slice(2)
    .filter(a => a.startsWith('--'))
    .map(a => {
      const [key, ...rest] = a.slice(2).split('=');
      return [key, rest.join('=')];
    }),
);

const force        = '--force' in args || 'force' in args;
const clientId     = args['client-id']      ?? '';
const clientSecret = args['client-secret']  ?? '';
const redirectUri  = args['redirect-uri']   ?? 'https://your-app.vercel.app/api/auth/callback';
const humandAppUrl = args['humand-app-url'] ?? 'https://app.humand.co';
const janusUrl     = 'https://api.humand.co/api/v1/janus';

// ── Conflict detection ────────────────────────────────────────────────────────

const AUTH_TYPES: Array<{ marker: string; label: string; files: string[] }> = [
  {
    marker: '@humand-auth: janus-oauth2',
    label: 'janus-oauth2 (add-login)',
    files: [
      'api/auth/_lib.ts',
      'api/auth/[...path].ts',
      'src/providers/AuthProvider.tsx',
      'src/providers/ProtectedRoute.tsx',
      'src/pages/Unauthenticated/index.tsx',
      'src/pages/AuthError/index.tsx',
    ],
  },
  {
    marker: '@humand-auth: super-admin',
    label: 'super-admin (add-super-admin-login)',
    files: [
      'src/providers/AuthContext.tsx',
      'src/pages/Auth/Login/constants.ts',
      'src/pages/Auth/Login/index.tsx',
      'src/pages/Auth/Callback/index.tsx',
    ],
  },
];

const appTsx = existsSync('src/App.tsx') ? readFileSync('src/App.tsx', 'utf-8') : '';
const existing = AUTH_TYPES.find(t => appTsx.includes(t.marker));

if (existing) {
  if (!force) {
    console.error(`EXISTING_AUTH:${existing.label}`);
    process.exit(1);
  }

  for (const f of existing.files) {
    if (existsSync(f)) {
      rmSync(f);
      console.log(`  removed ${f}`);
    }
  }
}

// ── Copy templates ────────────────────────────────────────────────────────────

const SKILL_DIR = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const TEMPLATES = join(SKILL_DIR, 'templates');

const FILES: Array<{ src: string; dest: string }> = [
  { src: '_lib.ts',             dest: 'api/auth/_lib.ts' },
  { src: '[...path].ts',        dest: 'api/auth/[...path].ts' },
  { src: 'AuthProvider.tsx',    dest: 'src/providers/AuthProvider.tsx' },
  { src: 'ProtectedRoute.tsx',  dest: 'src/providers/ProtectedRoute.tsx' },
  { src: 'Unauthenticated.tsx', dest: 'src/pages/Unauthenticated/index.tsx' },
  { src: 'AuthError.tsx',       dest: 'src/pages/AuthError/index.tsx' },
];

for (const { src, dest } of FILES) {
  mkdirSync(dirname(dest), { recursive: true });
  copyFileSync(join(TEMPLATES, src), dest);
  console.log(`  ✓ ${dest}`);
}

// ── Env var upsert helper ─────────────────────────────────────────────────────

function upsertVar(content: string, key: string, value: string): string {
  const regex = new RegExp(`^${key}=.*$`, 'm');
  return regex.test(content)
    ? content.replace(regex, `${key}=${value}`)
    : content + (content.endsWith('\n') ? '' : '\n') + `${key}=${value}\n`;
}

// ── .env.local (real values, never committed) ─────────────────────────────────

const envLocalPath = '.env.local';
let envLocalContent = existsSync(envLocalPath) ? readFileSync(envLocalPath, 'utf-8') : '';

envLocalContent = upsertVar(envLocalContent, 'HUMAND_CLIENT_ID', clientId);
envLocalContent = upsertVar(envLocalContent, 'HUMAND_CLIENT_SECRET', clientSecret);
envLocalContent = upsertVar(envLocalContent, 'JANUS_URL', janusUrl);
envLocalContent = upsertVar(envLocalContent, 'REDIRECT_URI', redirectUri);
envLocalContent = upsertVar(envLocalContent, 'VITE_HUMAND_APP_URL', humandAppUrl);
writeFileSync(envLocalPath, envLocalContent, 'utf-8');
console.log('.env.local — Janus vars upserted.');

// ── .env.example (reference, committed) ──────────────────────────────────────

const envExamplePath = '.env.example';
const envExampleContent = existsSync(envExamplePath) ? readFileSync(envExamplePath, 'utf-8') : '';

if (envExampleContent.includes('HUMAND_CLIENT_ID')) {
  console.log('.env.example already has Janus vars — skipping.');
} else {
  const block = [
    '',
    '# Janus OAuth server',
    `HUMAND_CLIENT_ID=your-client-id`,
    `HUMAND_CLIENT_SECRET=your-client-secret`,
    `JANUS_URL=${janusUrl}`,
    `REDIRECT_URI=${redirectUri}`,
    '',
    '# Humand app URL (shown on unauthenticated screen)',
    `VITE_HUMAND_APP_URL=${humandAppUrl}`,
    '',
  ].join('\n');

  writeFileSync(envExamplePath, envExampleContent + block, 'utf-8');
  console.log('.env.example — Janus vars added.');
}

// ── .gitignore check ──────────────────────────────────────────────────────────

const gitignorePath = '.gitignore';
const gitignore = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf-8') : '';
const lines = gitignore.split('\n');
const missing = ['.env.local', '.env'].filter(
  p => !lines.some(l => l.trim() === p),
);

if (missing.length > 0) {
  const addition = '\n# Local env files\n' + missing.join('\n') + '\n';
  writeFileSync(gitignorePath, gitignore + addition, 'utf-8');
  console.log(`  ✓ .gitignore — added: ${missing.join(', ')}`);
}
