// File upload helpers for z-image.ai
// Handles image, video, and audio uploads via FormData

import { readFileSync } from "node:fs";
import { basename } from "node:path";
import { getClient } from "./client.js";

interface UploadResponse {
  code: number;
  data?: {
    url?: string;
    urls?: string[];
    [key: string]: unknown;
  };
  url?: string;
  message?: string;
}

/**
 * Upload a local file to z-image.ai storage.
 * Returns the remote URL to use in generate calls.
 */
async function uploadFile(filePath: string, endpoint: string): Promise<string> {
  const client = getClient();
  const fileContent = readFileSync(filePath);
  const fileName = basename(filePath);

  // Detect MIME type from extension
  const ext = fileName.split(".").pop()?.toLowerCase() || "";
  const mimeMap: Record<string, string> = {
    jpg: "image/jpeg",
    jpeg: "image/jpeg",
    png: "image/png",
    webp: "image/webp",
    gif: "image/gif",
    mp4: "video/mp4",
    mov: "video/quicktime",
    avi: "video/x-msvideo",
    webm: "video/webm",
    mp3: "audio/mpeg",
    wav: "audio/wav",
    ogg: "audio/ogg",
    m4a: "audio/mp4",
    flac: "audio/flac",
  };
  const mimeType = mimeMap[ext] || "application/octet-stream";

  const blob = new Blob([fileContent], { type: mimeType });
  const formData = new FormData();
  formData.append("files", blob, fileName);

  const response = await client.postForm<UploadResponse>(endpoint, formData);

  // Extract URL from various response shapes
  const url = response.data?.url || response.data?.urls?.[0] || response.url;
  if (!url) {
    throw new Error(`Upload failed — no URL in response: ${JSON.stringify(response).slice(0, 500)}`);
  }
  return url;
}

/** Upload an image file, returns remote URL */
export async function uploadImage(filePath: string): Promise<string> {
  return uploadFile(filePath, "/api/storage/upload-image");
}

/** Upload a video file, returns remote URL */
export async function uploadVideo(filePath: string): Promise<string> {
  return uploadFile(filePath, "/api/storage/upload-video");
}

/** Upload an audio file, returns remote URL */
export async function uploadAudio(filePath: string): Promise<string> {
  return uploadFile(filePath, "/api/storage/upload-audio");
}

/**
 * Resolve an image input — accepts a URL (pass-through) or local path (upload).
 */
export async function resolveImageInput(imageInput: string): Promise<string> {
  if (imageInput.startsWith("http://") || imageInput.startsWith("https://")) {
    return imageInput;
  }
  return uploadImage(imageInput);
}

/** Resolve a video input — URL or local path */
export async function resolveVideoInput(videoInput: string): Promise<string> {
  if (videoInput.startsWith("http://") || videoInput.startsWith("https://")) {
    return videoInput;
  }
  return uploadVideo(videoInput);
}

/** Resolve an audio input — URL or local path */
export async function resolveAudioInput(audioInput: string): Promise<string> {
  if (audioInput.startsWith("http://") || audioInput.startsWith("https://")) {
    return audioInput;
  }
  return uploadAudio(audioInput);
}
