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;
  onProgress?: (event: WorkflowProgressEvent) => void | Promise<void>;
}

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

export type WorkflowProgressStatus = "running" | "completed" | "failed";

export interface WorkflowProgressEvent {
  label: string;
  status: WorkflowProgressStatus;
  duration_ms?: number;
}

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

async function timedStep<T>(
  label: string,
  steps: WorkflowTimingStep[],
  action: () => Promise<T>,
  onProgress?: (event: WorkflowProgressEvent) => void | Promise<void>,
): Promise<T> {
  const startedAt = Date.now();
  await onProgress?.({ label, status: "running" });
  try {
    const result = await action();
    const duration = Date.now() - startedAt;
    steps.push({
      label,
      duration_ms: duration,
    });
    await onProgress?.({ label, status: "completed", duration_ms: duration });
    return result;
  } catch (error) {
    const duration = Date.now() - startedAt;
    steps.push({
      label,
      duration_ms: duration,
    });
    await onProgress?.({ label, status: "failed", duration_ms: duration });
    throw error;
  }
}

async function completeStep(
  label: string,
  steps: WorkflowTimingStep[],
  onProgress?: (event: WorkflowProgressEvent) => void | Promise<void>,
) {
  await timedStep(label, steps, async () => undefined, onProgress);
}

export async function runOptimizationWorkflow({
  input,
  factCard,
  onProgress,
}: RunOptimizationWorkflowInput) {
  const startedAt = Date.now();
  const timingSteps: WorkflowTimingStep[] = [];
  let article = await timedStep(
    "生成优化稿",
    timingSteps,
    () => optimizeArticle({ input, factCard }),
    onProgress,
  );
  let qaReport = await timedStep(
    "质量检查",
    timingSteps,
    () =>
      inspectQualityWithLlm({
        article,
        factCard,
        platform: input.platform,
        sourceImages: input.images,
      }),
    onProgress,
  );
  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 }),
      onProgress,
    );
    rewriteRounds = nextRound;
    qaReport = await timedStep(
      `质量复检第 ${nextRound} 轮`,
      timingSteps,
      () =>
        inspectQualityWithLlm({
          article,
          factCard,
          platform: input.platform,
          sourceImages: input.images,
        }),
      onProgress,
    );
  }

  await completeStep("整理结果", timingSteps, onProgress);

  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,
  };
}
