/**
 * GitLab SSH 2FA verify API.
 *
 *   GET  /api/auth/gitlab-2fa
 *     → { host, verifiedAt: string | null, seconds_left: number }
 *
 *   POST /api/auth/gitlab-2fa
 *     body: { otp: "123456" }
 *     → { ok: true, verifiedAt, seconds_left, host } |
 *       { ok: false, error, transcript? }
 *
 * verifiedAt is persisted in settings.gitlab2fa so dropdown survives a
 * page refresh.
 */

import { NextResponse } from 'next/server';
import { loadSettings, saveSettings } from '@/lib/settings';
import {
  verifyGitlab2FA,
  verifyGitlab2FAViaKeystroke,
  getGitlabSshHost,
  secondsLeft,
  GITLAB_2FA_VALID_MS,
} from '@/lib/auth/gitlab-2fa';

export async function GET() {
  const settings = loadSettings();
  const host = getGitlabSshHost();
  const recorded = settings.gitlab2fa;
  // Drop the stamp if host changed (user pointed gitlab elsewhere)
  const valid = recorded && (!host || recorded.host === host);
  const verifiedAt = valid ? recorded?.verifiedAt ?? null : null;
  return NextResponse.json({
    host,
    verifiedAt,
    seconds_left: secondsLeft(verifiedAt ?? undefined),
    validity_seconds: Math.floor(GITLAB_2FA_VALID_MS / 1000),
  });
}

export async function POST(req: Request) {
  let body: any = {};
  try { body = await req.json(); } catch {}

  // Manual mode: caller already ran `ssh git@host 2fa_verify` in their
  // own terminal (necessary when corp VPN like FortiClient does per-
  // process tunnel filtering — node-spawned ssh can't reach the host).
  // Forge just stamps verifiedAt so the 55-minute clock starts.
  if (body?.manual === true) {
    const host = getGitlabSshHost();
    if (!host) {
      return NextResponse.json({ ok: false, error: 'GitLab connector not configured' }, { status: 400 });
    }
    const verifiedAt = new Date().toISOString();
    const settings = loadSettings();
    settings.gitlab2fa = { verifiedAt, host };
    saveSettings(settings);
    return NextResponse.json({
      ok: true,
      verifiedAt,
      host,
      seconds_left: Math.floor(GITLAB_2FA_VALID_MS / 1000),
      mode: 'manual',
    });
  }

  const otp = String(body?.otp || '').trim();
  if (!otp) {
    return NextResponse.json({ ok: false, error: 'otp is required' }, { status: 400 });
  }

  // Mode selector: 'keystroke' uses osascript+System Events to type
  // into the user's frontmost Terminal — required in environments
  // where the corp VPN blocks Forge-spawned ssh (FortiClient).
  // Default is the direct node-pty path (works for non-filtered envs).
  const mode = String(body?.mode || 'direct');
  const r = mode === 'keystroke'
    ? await verifyGitlab2FAViaKeystroke(otp)
    : await verifyGitlab2FA(otp);
  if (!r.ok) {
    return NextResponse.json(
      { ok: false, error: r.error || 'verify failed', transcript: r.transcript },
      { status: 400 },
    );
  }

  // Persist for the dropdown's "X min left" rendering.
  const settings = loadSettings();
  settings.gitlab2fa = { verifiedAt: r.verifiedAt!, host: r.host! };
  saveSettings(settings);

  return NextResponse.json({
    ok: true,
    verifiedAt: r.verifiedAt,
    host: r.host,
    seconds_left: Math.floor(GITLAB_2FA_VALID_MS / 1000),
  });
}
