import type { ArticleInput, ConfirmedFactCard } from "../domain/types";

import { optimizeArticle } from "./article-optimizer";
import { inspectQualityWithLlm } from "./quality-inspector";
import { rewriteFailedSections } from "./targeted-rewriter";

export interface RunOptimizationWorkflowInput {
  input: ArticleInput;
  factCard: ConfirmedFactCard;
}

export interface WorkflowTimingStep {
  label: string;
  duration_ms: number;
}

export interface WorkflowTimingSummary {
  total_ms: number;
  steps: WorkflowTimingStep[];
}

async function timedStep<T>(
  label: string,
  steps: WorkflowTimingStep[],
  action: () => Promise<T>,
): Promise<T> {
  const startedAt = Date.now();
  try {
    return await action();
  } finally {
    steps.push({
      label,
      duration_ms: Date.now() - startedAt,
    });
  }
}

export async function runOptimizationWorkflow({
  input,
  factCard,
}: RunOptimizationWorkflowInput) {
  const startedAt = Date.now();
  const timingSteps: WorkflowTimingStep[] = [];
  let article = await timedStep("生成优化稿", timingSteps, () =>
    optimizeArticle({ input, factCard }),
  );
  let qaReport = await timedStep("质量检查", timingSteps, () =>
    inspectQualityWithLlm({
      article,
      factCard,
      platform: input.platform,
      sourceImages: input.images,
    }),
  );
  let rewriteRounds = 0;

  while (qaReport.overall_status === "fail" && rewriteRounds < 2) {
    const nextRound = rewriteRounds + 1;
    const failedChecks = qaReport.checks.filter((check) => check.status === "fail");
    article = await timedStep(`定向修复第 ${nextRound} 轮`, timingSteps, () =>
      rewriteFailedSections({ article, factCard, failedChecks }),
    );
    rewriteRounds = nextRound;
    qaReport = await timedStep(`质量复检第 ${nextRound} 轮`, timingSteps, () =>
      inspectQualityWithLlm({
        article,
        factCard,
        platform: input.platform,
        sourceImages: input.images,
      }),
    );
  }

  return {
    article,
    qaReport,
    rewrite_rounds: rewriteRounds,
    stopped_after_max_rewrites:
      qaReport.overall_status === "fail" && rewriteRounds >= 2,
    timing: {
      total_ms: Date.now() - startedAt,
      steps: timingSteps,
    } satisfies WorkflowTimingSummary,
  };
}
