import { gatewayUrl } from "@/lib/api/gateway";
import type { RenderRequest } from "@/lib/render-schemas";

// ── V2 render service types ──────────────────────────────────────────────────

type V2RenderStep =
  | "Queued"
  | "Preparing"
  | "TemplateCache"
  | "JsxGen"
  | "Music"
  | "Rendering"
  | "Validating"
  | "Repairing"
  | "Optimisation"
  | "Video"
  | "Mixing"
  | "Final"
  | "Uploading"
  | "Done"
  | "Failed"
  | "Cancelled";

export type RenderJobStatus = "queued" | "processing" | "completed" | "failed";

export interface RenderJobRow {
  id: string;
  project_id: string;
  status: RenderJobStatus;
  progress: number;
  progress_message: string | null;
  output_url: string | null;
  error_message: string | null;
  /** Base64-encoded PNG preview frame pushed by the node agent. Null until first frame arrives. */
  preview_b64: string | null;
}

// ── Helpers ──────────────────────────────────────────────────────────────────

/** Map frontend resolution string to V2 render_quality enum (Low/Medium/High/Full/Lossless). */
function mapQuality(resolution: string): string {
  switch (resolution) {
    case "360p": return "Low";
    case "540p": return "Medium";
    case "720p": return "Medium";
    case "1080p": return "High";
    case "4K": return "Full";
    default: return "High";
  }
}

/** Map V2 step → legacy status for frontend compatibility. */
function stepToStatus(step: V2RenderStep): RenderJobStatus {
  if (step === "Done") return "completed";
  if (step === "Failed" || step === "Cancelled") return "failed";
  if (step === "Queued") return "queued";
  return "processing";
}

function authHeaders(token: string): Record<string, string> {
  return {
    Accept: "application/json",
    "Content-Type": "application/json",
    Authorization: `Bearer ${token}`,
  };
}

// ── Public API ───────────────────────────────────────────────────────────────

/**
 * Create a render job in the V2 render orchestrator.
 * `payload.projectId` must be the UUID of a V2 saved project.
 */
export async function createRenderJob(
  payload: RenderRequest,
  token: string
): Promise<{ jobId: string } | { error: string }> {
  const res = await fetch(gatewayUrl("/v1/renders"), {
    method: "POST",
    cache: "no-store",
    headers: authHeaders(token),
    body: JSON.stringify({
      saved_project_id: payload.projectId,
      quality: mapQuality(payload.settings.resolution),
      resolution: payload.settings.resolution,
      frame_rate: payload.settings.fps,
    }),
  });

  if (!res.ok) {
    const err = (await res.json().catch(() => null)) as {
      message?: string;
    } | null;
    return { error: err?.message ?? "Failed to create render job" };
  }

  const data = (await res.json().catch(() => null)) as { id?: string } | null;
  if (!data?.id) return { error: "No job ID returned from render service" };
  return { jobId: data.id };
}

/**
 * Fetch the current render job status from V2.
 * If the job is completed, also resolves the presigned export download URL.
 */
export async function getRenderJob(
  jobId: string,
  token: string
): Promise<RenderJobRow | null> {
  // 1. Poll progress endpoint
  const progressRes = await fetch(gatewayUrl(`/v1/renders/${jobId}/progress`), {
    cache: "no-store",
    headers: authHeaders(token),
  });
  if (!progressRes.ok) return null;

  const progress = (await progressRes.json().catch(() => null)) as {
    step?: V2RenderStep;
    progress?: number;
    message?: string;
    preview_b64?: string | null;
  } | null;
  if (!progress) return null;

  const step = progress.step ?? "Queued";
  const status = stepToStatus(step);

  // 2. If done, resolve the export download URL via MinIO presigned link
  let outputUrl: string | null = null;
  if (status === "completed") {
    const jobRes = await fetch(gatewayUrl(`/v1/renders/${jobId}`), {
      cache: "no-store",
      headers: authHeaders(token),
    });
    if (jobRes.ok) {
      const job = (await jobRes.json().catch(() => null)) as {
        export_id?: string | null;
      } | null;
      if (job?.export_id) {
        const urlRes = await fetch(
          gatewayUrl(`/v1/exports/${job.export_id}/download-url`),
          { cache: "no-store", headers: authHeaders(token) }
        );
        if (urlRes.ok) {
          const urlData = (await urlRes.json().catch(() => null)) as {
            url?: string;
          } | null;
          outputUrl = urlData?.url ?? null;
        }
      }
    }
  }

  return {
    id: jobId,
    project_id: "",
    status,
    progress: progress.progress ?? 0,
    progress_message: step,
    output_url: outputUrl,
    error_message:
      status === "failed" ? (progress.message ?? "Render failed") : null,
    preview_b64: progress.preview_b64 ?? null,
  };
}

/**
 * No-op in V2 — the render orchestrator dispatches jobs to node agents
 * automatically. Kept for API compatibility.
 */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function triggerRenderWorker(_jobId: string): Promise<void> {
  // V2 render service handles dispatch internally.
}
