import type { CreatePreviewTaskInput } from "../../api/webGenerationGateway";
import type { WebCanvasWorkflow, WebCanvasWorkflowNode, WebCanvasWorkflowTaskRef } from "../../types";
import { toHappyHorseDisplayModel } from "../../utils/happyHorseRouting";
import { resolveVideoRequestModel } from "../../utils/resolveVideoModel";
import { normalizeCanvasWorkflowSchema } from "./canvasWorkflowSchema";

export interface CanvasExecutionImageReference {
  nodeId: string;
  title: string;
  url: string;
  ossKey?: string | null;
}

export interface CanvasNodeExecutionContext {
  node: WebCanvasWorkflowNode;
  prompt: string;
  imageReferences: CanvasExecutionImageReference[];
  upstreamTaskRefs: WebCanvasWorkflowTaskRef[];
}

function getNodeText(node: WebCanvasWorkflowNode | undefined): string {
  if (!node) return "";
  return String(node.detail || node.params?.prompt || "").trim();
}

function getNodeAssetUrl(node: WebCanvasWorkflowNode | undefined): string {
  return String(node?.assetRef?.url || node?.previewUrl || "").trim();
}

function incomingEdges(workflow: WebCanvasWorkflow, nodeId: string) {
  return workflow.edges.filter((edge) => edge.target === nodeId);
}

export function resolveCanvasNodeExecutionContext(
  workflowInput: WebCanvasWorkflow,
  nodeId: string,
): CanvasNodeExecutionContext {
  const workflow = normalizeCanvasWorkflowSchema(workflowInput);
  const nodeById = new Map(workflow.nodes.map((node) => [node.id, node]));
  const node = nodeById.get(nodeId);
  if (!node) throw new Error(`Canvas node not found: ${nodeId}`);

  const imageReferences: CanvasExecutionImageReference[] = [];
  const upstreamPrompts: string[] = [];
  const upstreamTaskRefs: WebCanvasWorkflowTaskRef[] = [];
  const seenImages = new Set<string>();

  incomingEdges(workflow, nodeId).forEach((edge) => {
    const sourceNode = nodeById.get(edge.source);
    if (!sourceNode) return;
    if (sourceNode.taskRef) upstreamTaskRefs.push(sourceNode.taskRef);
    const sourceKind = sourceNode.kind;
    if (sourceKind === "image") {
      const url = getNodeAssetUrl(sourceNode);
      if (url && !seenImages.has(`${sourceNode.id}:${url}`)) {
        seenImages.add(`${sourceNode.id}:${url}`);
        imageReferences.push({
          nodeId: sourceNode.id,
          title: sourceNode.label,
          url,
          ossKey: sourceNode.assetRef?.ossKey || null,
        });
      }
      return;
    }
    const text = getNodeText(sourceNode);
    if (text) upstreamPrompts.push(text);
  });

  return {
    node,
    prompt: getNodeText(node) || upstreamPrompts.join("\n"),
    imageReferences,
    upstreamTaskRefs,
  };
}

function normalizeDuration(value: unknown, fallback = 5): number {
  const parsed = Number(String(value || "").replace(/s$/i, ""));
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
}

export function hasRunningCanvasTaskRef(node: WebCanvasWorkflowNode): boolean {
  const status = node.taskRef?.status;
  return status === "queued" || status === "pending" || status === "running";
}

export function buildCanvasVideoTaskInput(workflow: WebCanvasWorkflow, nodeId: string): CreatePreviewTaskInput {
  const context = resolveCanvasNodeExecutionContext(workflow, nodeId);
  const params = context.node.params || {};
  const referenceUrls = context.imageReferences.map((item) => item.url);
  const displayModel = toHappyHorseDisplayModel(String(params.model || workflow.settings.model || "happyhorse-1.0"));
  const model = resolveVideoRequestModel({ model: displayModel, referenceUrls });
  return {
    title: context.node.label || "视频节点生成",
    type: "video",
    prompt: context.prompt || (referenceUrls.length ? "根据参考图片生成视频" : ""),
    params: {
      model,
      ratio: String(params.aspectRatio || params.ratio || workflow.settings.ratio || "16:9"),
      quality: String(params.resolution || workflow.settings.resolution || "720P"),
      resolution: String(params.resolution || workflow.settings.resolution || "720P"),
      duration: normalizeDuration(params.duration || workflow.settings.duration),
      frameMode: params.videoMode === "firstlast" ? "start-end" : "omni",
      referenceUrls: referenceUrls.length ? referenceUrls : undefined,
      muted: false,
      hasReferenceVideo: false,
    },
  };
}

export function buildCanvasImageTaskInput(workflow: WebCanvasWorkflow, nodeId: string): CreatePreviewTaskInput {
  const context = resolveCanvasNodeExecutionContext(workflow, nodeId);
  const params = context.node.params || {};
  const referenceUrls = context.imageReferences.map((item) => item.url);
  return {
    title: context.node.label || "图片节点生成",
    type: "image",
    prompt: context.prompt || (referenceUrls.length ? "根据参考图片生成图片" : ""),
    params: {
      model: String(params.model || workflow.settings.model || "nano-banana-pro"),
      ratio: String(params.aspectRatio || params.ratio || workflow.settings.ratio || "16:9"),
      quality: String(params.imageSize || params.resolution || workflow.settings.resolution || "1K"),
      gridMode: "single",
      referenceUrls: referenceUrls.length ? referenceUrls : undefined,
    },
  };
}
