#!/usr/bin/env node
// ─────────────────────────────────────────────────────────────
// bin/invite.js — add / remove / list invites, plus grant/revoke
// admin on existing invites.
//
// Usage:
//   node bin/invite.js add <email> [FirstName]
//   node bin/invite.js remove <email>
//   node bin/invite.js list
//   node bin/invite.js admin add    <email>   # grant admin
//   node bin/invite.js admin remove <email>   # revoke admin
//   node bin/invite.js admin list             # show all admins
//
// The first name is optional. When present it's used on the welcome
// screen ("Thank you for your interest, Erik."). When absent the
// welcome screen falls back to anonymous copy. Re-running `add` on
// an existing email updates the first name only; invited_at and
// invited_by are preserved.
//
// Admin flag gates the hidden /admin surface (see server.js). Admin
// grant/revoke operates on existing invite rows only — a non-invited
// email must be invited first, then promoted.
// ─────────────────────────────────────────────────────────────
import { q } from '../src/db.js';

const [, , cmd, sub, arg3, arg4] = process.argv;
const EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;

function help() {
  console.log('Usage:');
  console.log('  invite add <email> [FirstName]');
  console.log('  invite remove <email>');
  console.log('  invite list');
  console.log('  invite admin add    <email>');
  console.log('  invite admin remove <email>');
  console.log('  invite admin list');
  process.exit(1);
}

switch (cmd) {
  case 'add': {
    const emailArg = sub;
    const nameArg = arg3;
    if (!emailArg || !EMAIL_RE.test(emailArg)) help();
    const email = emailArg.trim().toLowerCase();
    const firstName = nameArg ? nameArg.trim() : null;
    q.upsertInvite.run(email, firstName, Date.now(), 'cli');
    if (firstName) {
      console.log(`Invited ${email} (${firstName})`);
    } else {
      console.log(`Invited ${email}`);
    }
    break;
  }
  case 'remove': {
    const emailArg = sub;
    if (!emailArg || !EMAIL_RE.test(emailArg)) help();
    const email = emailArg.trim().toLowerCase();
    const result = q.deleteInvite.run(email);
    console.log(result.changes > 0 ? `Removed ${email}` : `No invite for ${email}`);
    break;
  }
  case 'list': {
    const rows = q.listInvites.all();
    if (rows.length === 0) {
      console.log('(no invites)');
    } else {
      for (const r of rows) {
        const d = new Date(r.invited_at).toISOString().slice(0, 10);
        const name = r.first_name ? `  [${r.first_name}]` : '';
        const by = r.invited_by ? `  (by ${r.invited_by})` : '';
        const admin = r.is_admin ? '  *ADMIN*' : '';
        console.log(`  ${d}  ${r.email}${name}${by}${admin}`);
      }
      console.log(`\n${rows.length} invite${rows.length === 1 ? '' : 's'} total.`);
    }
    break;
  }
  case 'admin': {
    if (sub === 'add' || sub === 'remove') {
      const emailArg = arg3;
      if (!emailArg || !EMAIL_RE.test(emailArg)) help();
      const email = emailArg.trim().toLowerCase();
      const invite = q.getInvite.get(email);
      if (!invite) {
        console.log(`No invite for ${email} — invite them first with: invite add ${email}`);
        process.exit(1);
      }
      q.setInviteAdmin.run(sub === 'add' ? 1 : 0, email);
      console.log(sub === 'add' ? `Granted admin to ${email}` : `Revoked admin from ${email}`);
    } else if (sub === 'list') {
      const rows = q.listInvites.all().filter((r) => r.is_admin);
      if (rows.length === 0) {
        console.log('(no admins)');
      } else {
        for (const r of rows) {
          const name = r.first_name ? `  [${r.first_name}]` : '';
          console.log(`  ${r.email}${name}`);
        }
        console.log(`\n${rows.length} admin${rows.length === 1 ? '' : 's'} total.`);
      }
    } else {
      help();
    }
    break;
  }
  default:
    help();
}
