/**
 * POST /api/phishing/campaigns/[id]/mark-false-positive
 *
 * Marks a campaign as a false positive. Gated by phishing/approve (D-04 —
 * same elevated tier as approve; no separate action key). Validates the
 * campaign id as a UUID (V5), optionally accepts a JSON body with a `reason`
 * string, and delegates to `markCampaignFalsePositive` (Plan 01), which
 * guards against marking a campaign that already has approved/completed
 * remediation (RemediationConflictError -> 409).
 */

import { NextRequest, NextResponse } from 'next/server';
import { requirePermission } from '@/lib/auth-utils';
import postgresClient from '@/lib/services/postgres-client';
import {
  markCampaignFalsePositive,
  RemediationValidationError,
  RemediationConflictError,
} from '@/lib/services/remediation-service';

const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  const { session, error } = await requirePermission('phishing', 'approve');
  if (error) return error;

  const { id } = await params;
  // V5: validate UUID shape before querying — a malformed id would otherwise
  // surface as an unhandled Postgres error -> uncaught 500.
  if (!UUID_RE.test(id)) {
    return NextResponse.json({ error: 'Invalid campaign id' }, { status: 400 });
  }

  // Body is optional — tolerate an empty/absent body (default reason undefined).
  let reason: string | undefined;
  const rawBody = await request.text();
  if (rawBody.trim().length > 0) {
    try {
      const parsed = JSON.parse(rawBody) as { reason?: unknown };
      reason = typeof parsed.reason === 'string' ? parsed.reason : undefined;
    } catch {
      return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 });
    }
  }

  const actor = (session?.user as { email?: string } | undefined)?.email ?? null;

  try {
    const campaignRes = await postgresClient.query<{ id: string }>(
      `SELECT id FROM campaigns WHERE id = $1`,
      [id]
    );
    if (!campaignRes.rows[0]) {
      return NextResponse.json({ error: 'Campaign not found' }, { status: 404 });
    }

    const result = await markCampaignFalsePositive(id, actor, reason);
    return NextResponse.json(result);
  } catch (err) {
    if (err instanceof RemediationConflictError) {
      return NextResponse.json({ error: err.message }, { status: 409 });
    }
    if (err instanceof RemediationValidationError) {
      return NextResponse.json({ error: err.message }, { status: 400 });
    }
    console.error('[PHISHING-MARK-FP] Failed to mark campaign false positive', id, err);
    return NextResponse.json(
      { error: 'Failed to mark campaign false positive', message: err instanceof Error ? err.message : 'Unknown error' },
      { status: 500 }
    );
  }
}
