import { getDb, nowIso, newId } from '@/lib/db.js';
import {
  PRINTING_PRESS_MODES,
  PRINTING_PRESS_MODE_DEFAULT,
  PRINTING_PRESS_ENV_VAR,
  resolveMode,
  capabilitiesFor,
  invalidateModeCache,
} from '@/lib/printing-press-security.js';
import { appendAudit } from '@/lib/runtime.js';
import { requireSession } from '@/lib/auth.js';

export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

const CONFIG_KEY = 'printing_press_security_mode_override';

function getOverride() {
  const db = getDb();
  const row = db.prepare('SELECT value FROM config WHERE key = ?').get(CONFIG_KEY);
  return row?.value || null;
}

function setOverride(mode) {
  const db = getDb();
  const existing = db.prepare('SELECT key FROM config WHERE key = ?').get(CONFIG_KEY);
  if (existing) {
    db.prepare('UPDATE config SET value = ? WHERE key = ?').run(mode, CONFIG_KEY);
  } else {
    db.prepare('INSERT INTO config (key, value) VALUES (?, ?)').run(CONFIG_KEY, mode);
  }
}

function recordSecurityEvent({ previous, next, source, actor_user_id, reason }) {
  const db = getDb();
  db.prepare(`
    INSERT INTO printing_press_security_events
      (id, at, previous_mode, next_mode, source, actor_user_id, reason)
    VALUES (?, ?, ?, ?, ?, ?, ?)
  `).run(newId('pp_sec'), nowIso(), previous, next, source, actor_user_id || null, reason || null);
}

function snapshot() {
  const override = getOverride();
  const mode = override || resolveMode();
  const caps = capabilitiesFor(mode);
  return {
    mode,
    default: PRINTING_PRESS_MODE_DEFAULT,
    env_var: PRINTING_PRESS_ENV_VAR,
    env_value: process.env[PRINTING_PRESS_ENV_VAR] || null,
    override,
    allowed_modes: PRINTING_PRESS_MODES,
    capabilities: caps,
  };
}

function requireAdmin(session) {
  if (session.role !== 'admin' && session.role !== 'owner') {
    throw { status: 403, error: 'forbidden' };
  }
}

export async function GET(req) {
  try {
    await requireSession(req);
    return Response.json({ ok: true, ...snapshot() });
  } catch (err) {
    if (err && typeof err === 'object' && err.status) {
      return Response.json({ error: err.error || 'unauthorized' }, { status: err.status });
    }
    throw err;
  }
}

export async function PATCH(req) {
  let body;
  try {
    body = await req.json();
  } catch {
    return new Response('Invalid JSON', { status: 400 });
  }
  const next = String(body?.mode || '').trim();
  if (!PRINTING_PRESS_MODES.includes(next)) {
    return Response.json({
      ok: false,
      error: `mode must be one of: ${PRINTING_PRESS_MODES.join(', ')}`,
    }, { status: 400 });
  }
  let session;
  try {
    session = await requireSession(req);
    requireAdmin(session);
  } catch (err) {
    if (err && typeof err === 'object' && err.status) {
      return Response.json({ error: err.error || 'unauthorized' }, { status: err.status });
    }
    throw err;
  }
  if ((next === 'balanced' || next === 'permissive') && !body?.confirm) {
    return Response.json({
      ok: false,
      error: `Flipping to ${next} mode requires confirm:true in the body`,
      previous: getOverride() || resolveMode(),
    }, { status: 400 });
  }
  if (next === 'permissive' && process.env.NODE_ENV === 'production') {
    return Response.json({
      ok: false,
      error: 'permissive mode is not allowed in production',
    }, { status: 400 });
  }

  const previous = getOverride() || resolveMode();
  setOverride(next);
  invalidateModeCache();
  recordSecurityEvent({
    previous,
    next,
    source: 'api',
    actor_user_id: session.user_id,
    reason: body?.reason || null,
  });
  appendAudit({
    type: 'printing_press.security_mode.changed',
    summary: `Printing Press security mode set to ${next}`,
    status: 'success',
    meta: { previous, next, actor: session.user_id || 'owner', source: 'api' },
  });
  return Response.json({ ok: true, previous, ...snapshot() });
}
