/**
 * POST /api/phishing/tickets/{ticket_id}/analyze
 *
 * On-demand trigger for one ticket: detect -> parse EML -> group into
 * campaign. Unlike the automatic webhook/cron paths, this always re-runs
 * groupReportIntoCampaign (no skipIfAlreadyGrouped) since parseAndStoreMessage
 * may have just written new messages/indicators rows that allow a Tier-3
 * grouping to upgrade to Tier-1/Tier-2 (D-08).
 */

import { NextRequest, NextResponse } from 'next/server';
import { requirePermission } from '@/lib/auth-utils';
import postgresClient from '@/lib/services/postgres-client';
import { detectPhishingTicket, type DetectableTicket } from '@/lib/services/phishing-detector';
import { parseAndStoreMessage } from '@/lib/services/phishing-eml-service';
import { groupReportIntoCampaign } from '@/lib/services/campaign-grouping-service';

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

  const { ticket_id } = await params;
  const ticketId = Number(ticket_id);
  if (!Number.isFinite(ticketId)) {
    return NextResponse.json({ error: 'Invalid ticket_id' }, { status: 400 });
  }

  try {
    const row = await postgresClient.query<{
      id: string;
      ticket_number: string | null;
      title: string | null;
      description: string | null;
      company_id: number | null;
      contact_id: number | null;
      created_by_contact_id: number | null;
    }>(
      `SELECT id, ticket_number, title, description, company_id, contact_id, created_by_contact_id
         FROM tickets WHERE id = $1`,
      [ticketId]
    );
    const r = row.rows[0];
    if (!r) {
      return NextResponse.json({ error: 'Ticket not found' }, { status: 404 });
    }

    const ticket: DetectableTicket = {
      id: Number(r.id),
      ticket_number: r.ticket_number,
      title: r.title,
      description: r.description,
      company_id: r.company_id,
      contact_id: r.contact_id,
      created_by_contact_id: r.created_by_contact_id,
    };

    const detection = await detectPhishingTicket(ticket);
    if (!detection.flagged || !detection.reportId) {
      return NextResponse.json(
        { error: 'Ticket does not match known phishing patterns' },
        { status: 400 }
      );
    }

    // parseAndStoreMessage never throws for expected no-op cases (returns
    // { stored: false, reason }) — grouping still proceeds regardless.
    await parseAndStoreMessage({ reportId: detection.reportId, ticketId });

    // D-08: /analyze always re-runs grouping unconditionally (no
    // skipIfAlreadyGrouped) — allows a Tier-3 grouping to upgrade to Tier-1
    // now that messages/indicators rows may exist.
    const grouped = await groupReportIntoCampaign(detection.reportId);

    return NextResponse.json({
      reportId: detection.reportId,
      campaignId: grouped?.campaignId ?? null,
      groupMethod: grouped?.groupMethod ?? null,
      created: grouped?.created ?? false,
    });
  } catch (err) {
    console.error('[PHISHING-ANALYZE] Failed to analyze ticket', ticketId, err);
    return NextResponse.json(
      { error: 'Failed to analyze ticket', message: err instanceof Error ? err.message : 'Unknown error' },
      { status: 500 }
    );
  }
}
