/**
 * POST /api/analyzer/tickets/:ticketNumber/analyze
 *
 * Body: { force?: boolean }
 * Response on existing match (force=false):
 *   { status: "complete", existingAnalysisId, existingAnalysisVersion }
 * Response when queued:
 *   { status: "queued", jobId }
 *
 * The worker (lib/services/analyzer/worker.ts) picks up queued jobs and runs
 * the full pipeline. Frontend should poll GET /api/analyzer/jobs/:jobId.
 */

import { NextRequest, NextResponse } from 'next/server';
import { requireAuth } from '@/lib/auth-utils';
import { AnalyzeTicketRequest } from '@/lib/types/analyzer';
import {
  loadTicketBundle,
  TicketNotFoundError,
} from '@/lib/services/analyzer/data-access';
import { preprocessTicket } from '@/lib/services/analyzer/preprocessor';
import {
  findExistingAnalysisByContentHash,
  queueJob,
} from '@/lib/services/analyzer/persistence';
// Side-effect import: triggers the worker's auto-start at server boot. Next.js
// eagerly loads route handler modules to build the routing manifest, so this
// import runs once per server process — same trick sync-scheduler relies on.
import '@/lib/services/analyzer/worker';

export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ ticketNumber: string }> }
) {
  const { session, error } = await requireAuth();
  if (error) return error;

  const { ticketNumber } = await params;

  let parsedBody: { force?: boolean; provider?: 'anthropic' | 'openrouter' };
  try {
    const body = await request.json().catch(() => ({}));
    const result = AnalyzeTicketRequest.safeParse(body);
    if (!result.success) {
      return NextResponse.json(
        { error: 'Invalid request body', details: result.error.issues },
        { status: 400 }
      );
    }
    parsedBody = result.data;
  } catch {
    parsedBody = {};
  }
  const provider = parsedBody.provider ?? 'anthropic';

  // Verify the ticket exists and load its data for the idempotency check.
  let bundle;
  try {
    bundle = await loadTicketBundle(ticketNumber);
  } catch (err) {
    if (err instanceof TicketNotFoundError) {
      return NextResponse.json(
        { error: `Ticket ${ticketNumber} not found in local mirror` },
        { status: 404 }
      );
    }
    console.error('[analyze] data-access error:', err);
    return NextResponse.json(
      {
        error: 'Failed to load ticket',
        message: err instanceof Error ? err.message : 'unknown',
      },
      { status: 500 }
    );
  }

  // Idempotency short-circuit: when force=false, return the existing analysis
  // without queueing a job if the source data hasn't changed since. Provider-
  // scoped so a Claude run never short-circuits a DeepSeek request.
  if (!parsedBody.force) {
    const pre = preprocessTicket(bundle);
    const existing = await findExistingAnalysisByContentHash(
      ticketNumber,
      pre.content_hash,
      provider
    );
    if (existing) {
      return NextResponse.json({
        status: 'complete',
        existingAnalysisId: existing.id,
        existingAnalysisVersion: existing.analysis_version,
      });
    }
  }

  // Queue a new job. The worker self-init at server-start (production) will
  // pick it up; in dev set ANALYZER_WORKER_AUTOSTART=1.
  const userId = (session?.user as { id: string }).id;
  const job = await queueJob({
    ticket_number: ticketNumber,
    queued_by_user_id: userId,
    provider,
  });

  return NextResponse.json({
    status: 'queued',
    jobId: job.id,
  });
}
