#!/usr/bin/env bun
/**
 * Copies super-admin 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 \
 *     --janus-url=<url> \
 *     --client-id=<id> \
 *     [--force]
 */
import { copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { readdirSync } 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 janusUrl  = args['janus-url']  ?? '';
const clientId  = args['client-id']  ?? '';

if (!janusUrl || !clientId) {
  console.error('ERROR: --janus-url and --client-id are required.');
  process.exit(1);
}

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

const AUTH_MARKERS: 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_MARKERS.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: 'AuthContext.tsx',       dest: 'src/providers/AuthContext.tsx' },
  { src: 'Login/constants.ts',    dest: 'src/pages/Auth/Login/constants.ts' },
  { src: 'Login/index.tsx',       dest: 'src/pages/Auth/Login/index.tsx' },
  { src: 'Callback/index.tsx',    dest: 'src/pages/Auth/Callback/index.tsx' },
];

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

// ── Env vars ──────────────────────────────────────────────────────────────────

const PLACEHOLDER_JANUS_URL = 'https://api.humand.co/api/v1/janus';
const PLACEHOLDER_CLIENT_ID = 'your-janus-client-id';
const VAR_MARKER = 'VITE_JANUS_URL';

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`;
}

function applyEnvVars(path: string, janus: string, client: string): void {
  const content = existsSync(path) ? readFileSync(path, 'utf-8') : '';
  let updated = upsertVar(content, 'VITE_JANUS_URL', janus);
  updated = upsertVar(updated, 'VITE_CLIENT_ID', client);
  writeFileSync(path, updated, 'utf-8');
  console.log(`  ✓ ${path}`);
}

// Find all .env* files at the repo root
const envFiles = readdirSync('.').filter(f => /^\.env(\.local|\.example|\.development|\.production|\.test)?$/.test(f));

if (envFiles.length === 0) {
  applyEnvVars('.env.example', PLACEHOLDER_JANUS_URL, PLACEHOLDER_CLIENT_ID);
  applyEnvVars('.env.local', janusUrl, clientId);
  console.log('  (created .env.example and .env.local — none existed)');
} else {
  for (const file of envFiles) {
    if (file === '.env.example') {
      applyEnvVars(file, PLACEHOLDER_JANUS_URL, PLACEHOLDER_CLIENT_ID);
    } else {
      applyEnvVars(file, janusUrl, clientId);
    }
  }
}

// ── .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(', ')}`);
}
