/**
 * GET /api/phishing/reports/{report_id}
 *   Standalone report evidence lookup for the D-08 "ungrouped report" state
 *   on the ticket-scoped review page (Phase 22 plan 06): a `reports` row
 *   that hasn't been linked to a campaign yet (`campaign_id IS NULL`, the
 *   narrow race window before Phase 18's grouping runs). Returns just
 *   enough — the report's own linked message evidence + a fresh
 *   blast-radius lookup — to render <EvidenceCard> standalone, without a
 *   campaign wrapper. Mirrors the bulk-fetch idiom in
 *   app/api/phishing/campaigns/[id]/route.ts, scoped to a single report_id
 *   instead of a campaign_id.
 */

import { NextRequest, NextResponse } from 'next/server';
import { requirePermission } from '@/lib/auth-utils';
import postgresClient from '@/lib/services/postgres-client';
import { getBlastRadius, type BlastRadiusResult } from '@/lib/services/mimecast-blast-radius';

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

interface ReportRow {
  id: string;
  ticket_id: string;
  ticket_number: string | null;
  company_name: string | null;
  title: string | null;
  created_at: string;
  requester_email: string | null;
}

interface MessageRow {
  id: string;
  message_id: string | null;
  headers: unknown;
  urls: unknown;
  attachments: unknown;
  body_preview: string | null;
}

interface IndicatorRow {
  id: string;
  message_id: string;
  indicator_type: string;
  value: string;
}

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ report_id: string }> }
) {
  const { error } = await requirePermission('phishing', 'read');
  if (error) return error;

  const { report_id } = await params;
  if (!UUID_RE.test(report_id)) {
    return NextResponse.json({ error: 'Invalid report id' }, { status: 400 });
  }

  try {
    const reportRes = await postgresClient.query<ReportRow>(
      `SELECT r.id::text, r.ticket_id::text, r.ticket_number, r.company_name,
              r.title, r.created_at::text,
              c.email_address AS requester_email
         FROM reports r
         LEFT JOIN contacts c ON c.id = r.requester_contact_id
        WHERE r.id = $1`,
      [report_id]
    );
    const report = reportRes.rows[0];
    if (!report) {
      return NextResponse.json({ error: 'Report not found' }, { status: 404 });
    }

    const messagesRes = await postgresClient.query<MessageRow>(
      `SELECT id::text, message_id, headers, urls, attachments, body_preview
         FROM messages WHERE report_id = $1 ORDER BY created_at ASC`,
      [report_id]
    );
    const messageIds = messagesRes.rows.map((m) => m.id);

    const indicatorsRes = messageIds.length
      ? await postgresClient.query<IndicatorRow>(
          `SELECT id::text, message_id::text, indicator_type, value
             FROM indicators WHERE message_id = ANY($1::uuid[])`,
          [messageIds]
        )
      : { rows: [] as IndicatorRow[] };

    // Evidence shape matches EvidenceMessage (components/phishing/evidence-card.tsx):
    // a single ungrouped report has at most one linked message today, but this
    // returns an array for shape-compatibility with EvidenceCard's multi-message Select.
    const messages = messagesRes.rows.map((m) => ({
      id: m.id,
      ticketNumber: report.ticket_number,
      reportCreatedAt: report.created_at,
      headers: m.headers,
      urls: m.urls,
      attachments: m.attachments,
      bodyPreview: m.body_preview ?? '',
    }));

    // Fresh blast-radius lookup (D-03: never persisted here), same derivation
    // as app/api/phishing/campaigns/[id]/route.ts — sender/recipient/subject/
    // dateWindow sourced from this report's primary (first) message.
    const primaryMessage = messagesRes.rows[0] ?? null;
    let blastRadius: BlastRadiusResult;
    if (primaryMessage) {
      const senderIndicator = indicatorsRes.rows.find(
        (i) => i.message_id === primaryMessage.id && i.indicator_type === 'sender'
      );
      const messageHeaders = (primaryMessage.headers ?? null) as
        | { from?: { email?: string | null } | null; subject?: string | null }
        | null;
      const createdAt = new Date(report.created_at);
      blastRadius = await getBlastRadius({
        sender: senderIndicator?.value ?? messageHeaders?.from?.email ?? '',
        recipient: report.requester_email ?? '',
        subject: messageHeaders?.subject ?? report.title ?? '',
        dateWindow: {
          start: new Date(createdAt.getTime() - 24 * 60 * 60 * 1000),
          end: new Date(createdAt.getTime() + 24 * 60 * 60 * 1000),
        },
      });
    } else {
      blastRadius = { status: 'unavailable', reason: 'not_configured' };
    }

    return NextResponse.json({
      id: report.id,
      ticketId: report.ticket_id,
      ticketNumber: report.ticket_number,
      companyName: report.company_name,
      title: report.title,
      createdAt: report.created_at,
      requesterEmail: report.requester_email,
      messages,
      blastRadius,
    });
  } catch (err) {
    console.error('[PHISHING-REPORT-DETAIL] Failed to load report', report_id, err);
    return NextResponse.json(
      { error: 'Failed to load report', message: err instanceof Error ? err.message : 'Unknown error' },
      { status: 500 }
    );
  }
}
