import { NextResponse } from "next/server";

import { requireApiAccess } from "../../../../../lib/api/auth";
import { getRepositoryFromRuntime } from "../../../../../lib/db/repository";
import { LlmValidationError } from "../../../../../lib/llm/client";
import { getExportStoreFromRuntime } from "../../../../../lib/workflow/export-store";
import { runOptimizationWorkflow } from "../../../../../lib/workflow/orchestrator";
import {
  recordWorkflowProgress,
  startWorkflowProgress,
} from "../../../../../lib/workflow/progress-store";

interface RouteContext {
  params: Promise<{ jobId: string }>;
}

export async function POST(request: Request, context: RouteContext) {
  const access = requireApiAccess(request);
  if (!access.ok) {
    return access.response;
  }

  const { jobId } = await context.params;
  const repository = getRepositoryFromRuntime();
  const job = await repository.getArticleJob(jobId);
  if (!job) {
    return NextResponse.json({ error: "Job not found" }, { status: 404 });
  }

  const factCardRecord = await repository.getFactCard(jobId);
  if (!factCardRecord) {
    return NextResponse.json(
      { error: "Confirm the fact card before optimizing" },
      { status: 409 },
    );
  }

  const requestStartedAt = Date.now();
  startWorkflowProgress(jobId);
  try {
    const result = await runOptimizationWorkflow({
      input: {
        title: job.source_title,
        body: job.source_body,
        images: job.image_inputs,
        platform: job.publish_platform,
        user_instructions: job.user_instructions,
      },
      factCard: factCardRecord,
      onProgress: (event) => {
        recordWorkflowProgress(jobId, event);
      },
    });
    const optimizedArticle = await repository.saveOptimizedArticle(
      jobId,
      result.article,
    );
    const qaReport = await repository.saveQaReport(
      jobId,
      optimizedArticle.revision ?? 1,
      result.qaReport,
    );
    const exportStore = getExportStoreFromRuntime();
    const exportPaths = await exportStore.writeJobExports({
      jobId,
      article: optimizedArticle,
      qaReport,
    });
    await repository.updateArticleJob(jobId, {
      status: "optimized",
      export_paths: exportPaths,
    });

    return NextResponse.json({
      optimizedArticle,
      qaReport,
      exportPaths,
      rewriteRounds: result.rewrite_rounds,
      stoppedAfterMaxRewrites: result.stopped_after_max_rewrites,
      timing: result.timing,
    });
  } catch (error) {
    const message = error instanceof Error ? error.message : "LLM optimization failed";
    return NextResponse.json(
      {
        error: message,
        timing: {
          total_ms: Date.now() - requestStartedAt,
          steps: [],
        },
      },
      { status: getErrorStatus(error) },
    );
  }
}

function getErrorStatus(error: unknown) {
  if (error instanceof LlmValidationError) return 502;
  if (error instanceof Error && /^LLM\b|provider/i.test(error.message)) return 502;
  return 500;
}
