const STATUS = {
  available: {
    short: "Disponível",
    pt: "disponível",
    pill: "available",
    action: "Falar por WhatsApp",
    contactMode: "interest",
  },
  reserved: {
    short: "Reservado",
    pt: "reservado",
    pill: "reserved",
    action: "Entrar na fila",
    contactMode: "queue",
  },
  sold: {
    short: "Vendido",
    pt: "vendido",
    pill: "sold",
    action: "Vendido",
    contactMode: "sold",
  },
};

function getPublicItems(items) {
  return (items || []).filter((item) => !item.draft);
}

function validateStatus(status) {
  return Object.prototype.hasOwnProperty.call(STATUS, status);
}

function getStatus(item) {
  if (validateStatus(item.status)) return STATUS[item.status];
  return {
    short: "Status inválido",
    pt: "status inválido",
    pill: "invalid",
    action: "Indisponível",
    contactMode: "invalid",
  };
}

function getPrimaryPhoto(item) {
  const photos = item && Array.isArray(item.photos) ? item.photos : [];
  return photos.find((photo) => photo.primary) || photos[0] || null;
}

function getItemTotal(items) {
  return getPublicItems(items).length;
}

function getItemHash(item) {
  return item && item.id ? `#item-${item.id}` : "#catálogo";
}

function getStatusCounts(items) {
  return getPublicItems(items).reduce((acc, item) => {
    if (validateStatus(item.status)) acc[item.status] = (acc[item.status] || 0) + 1;
    else acc.invalid = (acc.invalid || 0) + 1;
    return acc;
  }, { available: 0, reserved: 0, sold: 0, invalid: 0 });
}

function normalizePhone(value) {
  return String(value || "").replace(/\D/g, "");
}

function formatBRL(value) {
  return "R$ " + Number(value || 0).toLocaleString("pt-BR");
}

function formatItemPrice(item) {
  if (item && item.priceLabel) return item.priceLabel;
  return formatBRL(item && item.price);
}

function formatDisplayDate(iso) {
  if (!iso) return "";
  const date = new Date(`${iso}T12:00:00`);
  if (Number.isNaN(date.getTime())) return "";
  return date.toLocaleDateString("pt-BR", { day: "numeric", month: "long", year: "numeric" });
}

function makeWhatsappUrl(owner, item) {
  const phone = normalizePhone(owner.whatsapp);
  const message = item && item.type === "catalogue"
    ? `Olá! Vi o catálogo Desapegos da mudança e queria conversar sobre os itens disponíveis.`
    : item && item.id
      ? `Olá! Vi o anúncio do "${item.name}" (n. ${item.id}) no catálogo Desapegos da mudança. Ainda está disponível?`
      : `Olá! Vi o catálogo Desapegos da mudança e queria conversar sobre os itens disponíveis.`;
  return `https://wa.me/${phone}?text=${encodeURIComponent(message)}`;
}

function ItemPhoto({ item, photo, className = "", variant = 0 }) {
  const selected = photo || getPrimaryPhoto(item);
  if (selected && selected.src) {
    return (
      <img
        className={`photo ${className}`}
        src={selected.src}
        alt={selected.alt || item.name}
        loading="lazy"
        onError={(event) => {
          event.currentTarget.hidden = true;
          const fallback = event.currentTarget.nextElementSibling;
          if (fallback) fallback.hidden = false;
        }}
      />
    );
  }

  return (
    <div className={`photo-fallback ${className}`} role="img" aria-label={`Foto indisponível de ${item.name}`}>
      <Placeholder swatch={item.swatch} variant={variant} seed={item.id} />
      <span>Foto indisponível</span>
    </div>
  );
}

function PhotoFrame({ item, photo, variant = 0 }) {
  return (
    <>
      <ItemPhoto item={item} photo={photo} variant={variant} />
      <div className="photo-fallback" hidden role="img" aria-label={`Foto indisponível de ${item.name}`}>
        <Placeholder swatch={item.swatch} variant={variant} seed={item.id} />
        <span>Foto indisponível</span>
      </div>
    </>
  );
}

// Draft-only fallback artwork for invalid or missing image data.
function Placeholder({ swatch, variant = 0, seed = 0 }) {
  const colors = swatch && swatch.length ? swatch : ["#d9cdb8", "#b8a888", "#8a7a65"];
  const bg = colors[0];
  const mid = colors[1] || colors[0];
  const dark = colors[2] || colors[1] || colors[0];

  if (variant % 3 === 0) {
    return (
      <svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice" style={{ width: "100%", height: "100%", display: "block" }}>
        <rect width="400" height="300" fill={bg} />
        <rect y="0" width="400" height="80" fill={mid} opacity="0.55" />
        <rect y="180" width="400" height="120" fill={dark} opacity="0.4" />
      </svg>
    );
  }
  if (variant % 3 === 1) {
    return (
      <svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice" style={{ width: "100%", height: "100%", display: "block" }}>
        <rect width="400" height="300" fill={bg} />
        <rect y="210" width="400" height="90" fill={mid} opacity="0.45" />
        <circle cx="200" cy="170" r="85" fill={dark} opacity="0.55" />
      </svg>
    );
  }
  return (
    <svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice" style={{ width: "100%", height: "100%", display: "block" }}>
      <rect width="400" height="300" fill={bg} />
      <rect x="140" y="40" width="120" height="220" fill={mid} opacity="0.55" />
      <rect y="260" width="400" height="40" fill={dark} opacity="0.25" />
    </svg>
  );
}

function useCountdown(iso) {
  const [now, setNow] = React.useState(Date.now());
  React.useEffect(() => {
    const timer = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(timer);
  }, []);
  const target = new Date(iso).getTime();
  const diff = Math.max(0, target - now);
  const d = Math.floor(diff / (1000 * 60 * 60 * 24));
  const h = Math.floor((diff / (1000 * 60 * 60)) % 24);
  const m = Math.floor((diff / (1000 * 60)) % 60);
  const s = Math.floor((diff / 1000) % 60);
  return { d, h, m, s };
}

Object.assign(window, {
  STATUS,
  Placeholder,
  PhotoFrame,
  ItemPhoto,
  getPublicItems,
  getStatus,
  getStatusCounts,
  getItemTotal,
  getItemHash,
  getPrimaryPhoto,
  validateStatus,
  normalizePhone,
  makeWhatsappUrl,
  formatBRL,
  formatItemPrice,
  formatDisplayDate,
  useCountdown,
});
