import { promises as fs } from "fs";
import path from "path";

const MEDIA_DIR = path.join(process.cwd(), "data", "media");

async function ensureMediaDir() {
  await fs.mkdir(MEDIA_DIR, { recursive: true });
}

export function getLocalMediaPath(filename: string): string {
  return path.join(MEDIA_DIR, path.basename(filename));
}

/** Map /api/media/foo.png → absolute path on disk. */
export function resolveLocalMediaPath(apiUrl: string | null | undefined): string | null {
  if (!apiUrl) return null;
  const match = apiUrl.match(/\/api\/media\/([^/?#]+)/);
  if (!match?.[1]) return null;
  return getLocalMediaPath(match[1]);
}

export function mediaApiUrl(filename: string): string {
  return `/api/media/${path.basename(filename)}`;
}

function extensionForMime(mime: string): string {
  if (mime.includes("svg")) return "svg";
  if (mime.includes("png")) return "png";
  if (mime.includes("jpeg") || mime.includes("jpg")) return "jpg";
  if (mime.includes("webp")) return "webp";
  if (mime.includes("mp4")) return "mp4";
  return "bin";
}

/** Persist generated image under a unique asset id (never reuse prior regenerate paths). */
export async function persistGeneratedImage(
  assetId: string,
  imageUrl: string | null,
): Promise<string | null> {
  if (!imageUrl) return null;

  await ensureMediaDir();
  const id = path.basename(assetId);

  if (imageUrl.startsWith("data:")) {
    const match = imageUrl.match(/^data:([^;]+);base64,(.+)$/);
    if (match) {
      const [, mime, b64] = match;
      const ext = extensionForMime(mime);
      const filename = `${id}.${ext}`;
      await fs.writeFile(path.join(MEDIA_DIR, filename), Buffer.from(b64, "base64"));
      return `/api/media/${filename}`;
    }

    if (imageUrl.startsWith("data:image/svg+xml")) {
      const decoded = imageUrl.includes(";charset=utf-8,")
        ? decodeURIComponent(imageUrl.split(";charset=utf-8,")[1] ?? "")
        : decodeURIComponent(imageUrl.split(",")[1] ?? "");
      const filename = `${id}.svg`;
      await fs.writeFile(path.join(MEDIA_DIR, filename), decoded, "utf-8");
      return `/api/media/${filename}`;
    }
  }

  if (imageUrl.startsWith("http://") || imageUrl.startsWith("https://")) {
    try {
      const res = await fetch(imageUrl);
      if (!res.ok) return imageUrl;
      const buffer = Buffer.from(await res.arrayBuffer());
      const contentType = res.headers.get("content-type") ?? "image/png";
      const ext = extensionForMime(contentType);
      const filename = `${id}.${ext}`;
      await fs.writeFile(path.join(MEDIA_DIR, filename), buffer);
      return `/api/media/${filename}`;
    } catch {
      return imageUrl;
    }
  }

  return imageUrl;
}

/** Video already written to disk — return stable API URL (basename may include asset id). */
export async function persistGeneratedVideo(
  _assetId: string,
  videoUrl: string | null,
): Promise<string | null> {
  if (!videoUrl) return null;
  const local = resolveLocalMediaPath(videoUrl);
  if (local) {
    try {
      await fs.access(local);
      return mediaApiUrl(path.basename(local));
    } catch {
      return videoUrl;
    }
  }
  return videoUrl;
}
