export interface ProductImageItem {
  id: string;
  image_url: string;
  sort_order: number;
  is_primary: boolean;
}

type NormalizeImagesResult = {
  images: ProductImageItem[];
  error?: string;
};

const UUID_REGEX =
  /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;

function isUuid(value: string) {
  return UUID_REGEX.test(value);
}

function createId() {
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
    return crypto.randomUUID();
  }
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
    const random = Math.floor(Math.random() * 16);
    const value = char === "x" ? random : (random & 0x3) | 0x8;
    return value.toString(16);
  });
}

export function normalizeProductImagesInput(value: unknown): NormalizeImagesResult {
  if (value === undefined || value === null) return { images: [] };
  if (!Array.isArray(value)) {
    return { images: [], error: "Formato inválido para imagens do produto." };
  }

  const seenUrls = new Set<string>();
  const entries: ProductImageItem[] = [];

  value.forEach((item, index) => {
    if (!item || typeof item !== "object") return;
    const row = item as Record<string, unknown>;
    const imageUrl = typeof row.image_url === "string" ? row.image_url.trim() : "";
    if (!imageUrl) return;
    if (seenUrls.has(imageUrl)) return;

    seenUrls.add(imageUrl);

    const rawId = typeof row.id === "string" ? row.id.trim() : "";
    const id = isUuid(rawId) ? rawId : createId();
    const sortOrder =
      typeof row.sort_order === "number" && Number.isFinite(row.sort_order)
        ? Math.max(0, Math.floor(row.sort_order))
        : index;

    entries.push({
      id,
      image_url: imageUrl,
      sort_order: sortOrder,
      is_primary: Boolean(row.is_primary),
    });
  });

  if (!entries.length) return { images: [] };

  const sorted = entries
    .slice()
    .sort((a, b) => a.sort_order - b.sort_order)
    .map((item, index) => ({ ...item, sort_order: index }));

  const explicitPrimary = sorted.find((item) => item.is_primary);
  const primaryId = explicitPrimary?.id ?? sorted[0].id;

  return {
    images: sorted.map((item) => ({
      ...item,
      is_primary: item.id === primaryId,
    })),
  };
}

export function getPrimaryProductImageUrl(images: ProductImageItem[], fallback = "") {
  if (!images.length) return fallback;
  const primary = images.find((image) => image.is_primary);
  return primary?.image_url || images[0].image_url || fallback;
}
