import { NextResponse } from "next/server";
import { z } from "zod";

import { requireApiAccess } from "../../../../lib/api/auth";
import {
  HUMAN_COPY_RUBRIC_V1,
  scoreHumanCopyResult,
} from "../../../../lib/calibration/scoring";
import { buildHumanCopyCaseSummary, createProcessStep, excerpt } from "../../../../lib/cases/summaries";
import { getRepositoryFromRuntime } from "../../../../lib/db/repository";
import { copyOptimizationRequestSchema } from "../../../../lib/domain/validation";
import type { LlmAuditSummary } from "../../../../lib/llm/audit";
import { LlmValidationError } from "../../../../lib/llm/client";
import { optimizeRenweiCopy } from "../../../../lib/workflow/renwei-copy-optimizer";

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

  try {
    const payload = copyOptimizationRequestSchema.parse(await request.json());
    const repository = getRepositoryFromRuntime();
    const caseSummary = buildHumanCopyCaseSummary(payload);
    const optimizationCase = await repository.createOptimizationCase({
      case_type: "human_copy",
      ...caseSummary,
    });
    await repository.saveCaseInput({
      case_id: optimizationCase.id,
      case_type: "human_copy",
      article_job_id: null,
      payload,
    });

    const startedAt = Date.now();
    const llmAuditSummary: LlmAuditSummary[] = [];
    try {
      const result = await optimizeRenweiCopy(payload, {
        onAuditSummary: (summary) => {
          llmAuditSummary.push(summary);
        },
      });
      const resultVersion = await repository.createOptimizationResultVersion({
        case_id: optimizationCase.id,
        case_type: "human_copy",
        status: "optimized",
        article_job_id: null,
        article_revision: null,
        result_summary: excerpt(result.optimized_text),
        payload: result,
        process_summary: [
          createProcessStep({
            stage: "human_copy_optimize",
            startedAt,
            endedAt: Date.now(),
            status: "success",
            producedResultVersion: true,
          }),
        ],
        llm_audit_summary: llmAuditSummary,
        error_stage: null,
        error_summary: null,
      });
      await repository.saveRubricVersion(HUMAN_COPY_RUBRIC_V1);
      await repository.saveScoringRun(
        scoreHumanCopyResult({
          resultVersionId: resultVersion.id,
          result,
        }),
      );

      return NextResponse.json({
        case: { id: optimizationCase.id, case_type: "human_copy" },
        result_version: { id: resultVersion.id, version: resultVersion.version },
        result,
      });
    } catch (error) {
      const message = errorMessage(error);
      const resultVersion = await repository.createOptimizationResultVersion({
        case_id: optimizationCase.id,
        case_type: "human_copy",
        status: "failed",
        article_job_id: null,
        article_revision: null,
        result_summary: "",
        payload: null,
        process_summary: [
          createProcessStep({
            stage: "human_copy_optimize",
            startedAt,
            endedAt: Date.now(),
            status: "failed",
            errorSummary: message,
            producedResultVersion: false,
          }),
        ],
        llm_audit_summary: llmAuditSummary,
        error_stage: "human_copy_optimize",
        error_summary: message,
      });

      return NextResponse.json(
        {
          error: message,
          case: { id: optimizationCase.id, case_type: "human_copy" },
          result_version: { id: resultVersion.id, version: resultVersion.version },
        },
        { status: getErrorStatus(error) },
      );
    }
  } catch (error) {
    return jsonError(error, getErrorStatus(error));
  }
}

function errorMessage(error: unknown) {
  return error instanceof z.ZodError
    ? "请输入需要优化的文案"
    : error instanceof Error
      ? error.message
      : "文案优化失败";
}

function jsonError(error: unknown, status: number) {
  return NextResponse.json({ error: errorMessage(error) }, { 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;
}
