"use client";

import { useState } from "react";
import Link from "next/link";
import type { StoreProduct } from "@/lib/api";
import { resolveMediaUrl } from "@/lib/api";

const SIZE_ORDER = ["XXS", "XS", "S", "M", "L", "XL", "XXL", "XXXL", "ONE SIZE"];

function sortSizes(sizes: string[]): string[] {
  return [...sizes].sort((a, b) => {
    const ia = SIZE_ORDER.indexOf(a.toUpperCase());
    const ib = SIZE_ORDER.indexOf(b.toUpperCase());
    if (ia === -1 && ib === -1) return a.localeCompare(b);
    if (ia === -1) return 1;
    if (ib === -1) return -1;
    return ia - ib;
  });
}

/** Total available stock across a product's variants — used to derive a "Low stock" badge
 *  when the admin hasn't set an explicit product.badge. */
function totalStock(product: StoreProduct): number {
  return product.variants.reduce((sum, v) => sum + Math.max(0, v.stockQty), 0);
}

function deriveBadge(product: StoreProduct): { label: string; key: "new" | "restock" | "low" } | null {
  if (product.badge) {
    const normalized = product.badge.toLowerCase();
    if (normalized === "new") return { label: "New", key: "new" };
    if (normalized === "restock") return { label: "Restock", key: "restock" };
    if (normalized === "low stock") return { label: "Low stock", key: "low" };
    return { label: product.badge, key: "restock" };
  }
  const stock = totalStock(product);
  if (stock > 0 && stock <= 5) return { label: "Low stock", key: "low" };
  return null;
}

/** Grid card for the "ALL GOODS" listing: numbered index badge, status badge (New/Restock/
 *  Low stock), image (hover swaps to a second image when available), name, price, colour
 *  swatches, fabric/gender caption, and the available size run — matches the reference's
 *  sharp-cornered, hairline-divided product cells. */
export default function ProductCard({ product, index }: { product: StoreProduct; index?: number }) {
  const [hovered, setHovered] = useState(false);
  const primaryImage = product.images[0] ? resolveMediaUrl(product.images[0]) : undefined;
  const secondaryImage = product.images[1] ? resolveMediaUrl(product.images[1]) : undefined;

  const colors = Array.from(new Set(product.variants.map((v) => v.color).filter((c): c is string => !!c)));
  const sizes = sortSizes(
    Array.from(new Set(product.variants.map((v) => v.size).filter((s): s is string => !!s)))
  );
  const badge = deriveBadge(product);
  const captionParts = [product.fabric, product.gender].filter(Boolean);

  return (
    <Link
      href={`/shop/${product.slug}`}
      className="group block bg-white"
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
    >
      <div className="relative aspect-[4/5] bg-[#f0f2f5] overflow-hidden">
        {index != null ? (
          <span className="absolute top-3 left-3 z-10 text-[11px] font-bold text-[#1d2739] tabular-nums">
            {String(index).padStart(2, "0")}
          </span>
        ) : null}
        {badge ? (
          <span className="absolute top-3 right-3 z-10 bg-[#1d2739] text-white text-[10px] font-bold uppercase tracking-wide px-2.5 py-1">
            {badge.label}
          </span>
        ) : null}
        {primaryImage ? (
          <div
            className="absolute inset-0 bg-cover bg-center transition-opacity duration-200"
            style={{ backgroundImage: `url(${primaryImage})`, opacity: hovered && secondaryImage ? 0 : 1 }}
          />
        ) : null}
        {secondaryImage ? (
          <div
            className="absolute inset-0 bg-cover bg-center transition-opacity duration-200"
            style={{ backgroundImage: `url(${secondaryImage})`, opacity: hovered ? 1 : 0 }}
          />
        ) : null}
      </div>

      <div className="border-t border-[rgba(29,39,57,0.18)] px-1 py-4 flex flex-col gap-2">
        <div className="flex items-start justify-between gap-3">
          <h3 className="font-black uppercase leading-tight text-[15px] text-[#1d2739]">{product.name}</h3>
          <p className="shrink-0 text-[15px] font-bold text-[#b08968]">${product.basePrice.toFixed(2)}</p>
        </div>

        {colors.length > 0 ? (
          <div className="flex items-center gap-1.5">
            {colors.slice(0, 8).map((c) => (
              <span
                key={c}
                title={c}
                className="h-3.5 w-3.5 border border-[rgba(29,39,57,0.25)]"
                style={{ backgroundColor: swatchColor(c) }}
              />
            ))}
          </div>
        ) : null}

        {captionParts.length > 0 ? (
          <p className="text-[10px] font-semibold uppercase tracking-wide text-[#6f7885]">
            {captionParts.join(" / ")}
          </p>
        ) : null}

        {sizes.length > 0 ? (
          <p className="text-[10px] font-semibold uppercase tracking-wide text-[#949daa]">{sizes.join(" ")}</p>
        ) : null}
      </div>
    </Link>
  );
}

/** Best-effort CSS color from a color name so swatches render something reasonable without a
 *  dedicated hex field on the product/variant DTO. Falls back to a neutral grey for anything
 *  the browser doesn't recognize as a named CSS color. */
function swatchColor(name: string): string {
  return name.trim() || "#ccc";
}
