import { NextResponse } from "next/server";

import { requireApiAccess } from "../../../lib/api/auth";
import { getRepositoryFromRuntime } from "../../../lib/db/repository";
import { LlmValidationError } from "../../../lib/llm/client";
import { extractCandidateFactCard } from "../../../lib/workflow/fact-extractor";
import { normalizeInput, type RawArticleInput } from "../../../lib/workflow/input-normalizer";

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

  try {
    const payload = (await request.json()) as RawArticleInput;
    const normalized = normalizeInput(payload);
    const repository = getRepositoryFromRuntime();
    const job = await repository.createArticleJob({
      source_title: normalized.articleInput.title,
      source_body: normalized.articleInput.body,
      image_inputs: normalized.articleInput.images,
      publish_platform: normalized.articleInput.platform,
      user_instructions: normalized.articleInput.user_instructions,
    });
    const factStartedAt = Date.now();
    const timing = {
      total_ms: 0,
      steps: [] as Array<{ label: string; duration_ms: number }>,
    };
    try {
      const candidateFactCard = await extractCandidateFactCard(normalized.articleInput);
      const duration = Date.now() - factStartedAt;
      timing.total_ms = duration;
      timing.steps.push({ label: "事实卡提取", duration_ms: duration });

      return NextResponse.json({ job, candidateFactCard, timing }, { status: 201 });
    } catch (error) {
      const duration = Date.now() - factStartedAt;
      timing.total_ms = duration;
      timing.steps.push({ label: "事实卡提取", duration_ms: duration });
      return jsonError(error, getErrorStatus(error), timing);
    }
  } catch (error) {
    return jsonError(error, getErrorStatus(error));
  }
}

function jsonError(
  error: unknown,
  status: number,
  timing?: { total_ms: number; steps: Array<{ label: string; duration_ms: number }> },
) {
  const message = error instanceof Error ? error.message : "Request failed";
  return NextResponse.json(
    timing ? { error: message, timing } : { error: message },
    { status },
  );
}

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