import fs from "fs/promises";
import path from "path";
import { defaultAdminState } from "./default-admin-state";
import type { AdminState, ImageSlot } from "./mpc-types";
import { uploadedPublicFilePath as runtimeUploadedFilePath } from "./runtime-storage";

export const uploadedImagePrefixes = ["/uploads/admin/", "/uploads/accommodation/", "/uploads/local-listings/"] as const;

export function isUploadedPublicPath(value?: string | null) {
  const text = String(value || "");
  return uploadedImagePrefixes.some((prefix) => text.startsWith(prefix)) && !text.includes("..") && !text.startsWith("//");
}

export function isRemoteUrl(value?: string | null) {
  return /^https?:\/\//i.test(String(value || ""));
}

export function uploadedPublicFilePath(publicPath: string) {
  return runtimeUploadedFilePath(publicPath);
}

export function defaultImageSlotForKey(slotKey: string): ImageSlot | null {
  return defaultAdminState.imageSlots.find((slot) => slot.key === slotKey) || null;
}

export function defaultFallbackForImageSlot(slot: ImageSlot) {
  const defaultSlot = defaultImageSlotForKey(slot.key);
  const staticDefault = defaultSlot?.fallbackUrl || defaultSlot?.url;
  if (staticDefault && !isUploadedPublicPath(staticDefault)) return staticDefault;
  if (slot.fallbackUrl && !isUploadedPublicPath(slot.fallbackUrl)) return slot.fallbackUrl;
  if (slot.url && !isUploadedPublicPath(slot.url)) return slot.url;
  return "/images/slots/supplier-default.webp";
}

function stateImageUrls(state: AdminState) {
  const urls: string[] = [];
  for (const slot of state.imageSlots || []) {
    if (slot.url) urls.push(slot.url);
    if (slot.fallbackUrl) urls.push(slot.fallbackUrl);
  }
  for (const listing of state.accommodationListings || []) {
    for (const image of listing.images || []) if (image.url) urls.push(image.url);
  }
  for (const supplier of state.suppliers || []) if (supplier.imageSrc) urls.push(supplier.imageSrc);
  for (const product of state.productCatalogue || []) {
    if (product.imageSrc) urls.push(product.imageSrc);
    if (product.coverSrc) urls.push(product.coverSrc);
  }
  return urls;
}

export function isUploadedImageReferenced(state: AdminState, publicPath: string) {
  if (!isUploadedPublicPath(publicPath)) return true;
  return stateImageUrls(state).some((url) => url === publicPath);
}

export async function deleteUploadedImageIfUnreferenced(state: AdminState, publicPath?: string | null) {
  if (!publicPath || !isUploadedPublicPath(publicPath)) return { attempted: false, deleted: false, reason: "not-uploaded-path" };
  if (isUploadedImageReferenced(state, publicPath)) return { attempted: true, deleted: false, reason: "still-referenced" };
  const filePath = uploadedPublicFilePath(publicPath);
  if (!filePath) return { attempted: true, deleted: false, reason: "unsafe-path" };
  try {
    await fs.unlink(filePath);
    return { attempted: true, deleted: true, reason: "deleted" };
  } catch (error) {
    const code = (error as NodeJS.ErrnoException).code;
    if (code === "ENOENT") return { attempted: true, deleted: false, reason: "already-missing" };
    return { attempted: true, deleted: false, reason: "delete-failed" };
  }
}
