"use client";

import { useMemo, useState } from "react";
import Link from "next/link";
import type { StoreProduct, StoreProductVariant } from "@/lib/api";
import { resolveMediaUrl } from "@/lib/api";
import { useCart } from "@/context/CartContext";

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;
  });
}

// The backend's public variant DTO already nets reservations out of stockQty
// (PublicWebService.toPublicProduct passes availableQty(v), not raw on-hand stock),
// so stockQty here IS the available-to-sell quantity — no client-side subtraction.
function availableQty(v: StoreProductVariant): number {
  return v.stockQty;
}

export default function ProductDetail({ product }: { product: StoreProduct }) {
  const { addItem } = useCart();
  const [activeImage, setActiveImage] = useState(0);
  const [status, setStatus] = useState<"idle" | "adding" | "error">("idle");

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

  const [selectedColor, setSelectedColor] = useState<string | null>(colors[0] ?? null);
  const [selectedSize, setSelectedSize] = useState<string | null>(null);

  const selectedVariant = useMemo(
    () =>
      product.variants.find(
        (v) => (colors.length === 0 || v.color === selectedColor) && (sizes.length === 0 || v.size === selectedSize)
      ) ?? null,
    [product.variants, selectedColor, selectedSize, colors.length, sizes.length]
  );

  function sizeAvailable(size: string): boolean {
    const variant = product.variants.find(
      (v) => v.size === size && (colors.length === 0 || v.color === selectedColor)
    );
    return !!variant && availableQty(variant) > 0;
  }

  async function handleAddToCart() {
    if (!selectedVariant) return;
    setStatus("adding");
    try {
      await addItem(selectedVariant.id, 1);
      setStatus("idle");
    } catch {
      setStatus("error");
    }
  }

  const images = product.images.length > 0 ? product.images : [""];
  const price = selectedVariant?.price ?? product.basePrice;
  const canAdd = !!selectedVariant && availableQty(selectedVariant) > 0 && (sizes.length === 0 || !!selectedSize);

  const ctaLabel = !selectedVariant
    ? sizes.length > 0 && !selectedSize
      ? "Select a size"
      : "Unavailable"
    : availableQty(selectedVariant) <= 0
      ? "Out of stock"
      : `Add ${[selectedColor, selectedSize].filter(Boolean).join(" / ") || product.name} — $${price.toFixed(2)}`;

  return (
    <div className="grid grid-cols-1 lg:grid-cols-2 gap-0 lg:gap-16 border-t border-[rgba(29,39,57,0.18)]">
      <div className="py-8 lg:pr-8">
        <div
          className="aspect-square bg-[#f0f2f5] bg-cover bg-center"
          style={{ backgroundImage: images[activeImage] ? `url(${resolveMediaUrl(images[activeImage])})` : undefined }}
        />
        {images.length > 1 ? (
          <div className="mt-1 grid grid-cols-2 gap-1">
            {images.slice(0, 2).map((img, i) => (
              <button
                key={img + i}
                onClick={() => setActiveImage(i)}
                className={`aspect-square bg-[#f0f2f5] bg-cover bg-center border-2 ${
                  activeImage === i ? "border-[#b08968]" : "border-transparent"
                }`}
                style={{ backgroundImage: img ? `url(${resolveMediaUrl(img)})` : undefined }}
                aria-label={`View image ${i + 1}`}
              />
            ))}
          </div>
        ) : null}
      </div>

      <div className="py-8 lg:pl-8 lg:border-l border-[rgba(29,39,57,0.18)]">
        {product.category ? (
          <p className="text-[11px] font-bold uppercase tracking-[0.15em] text-[#6f7885]">{product.category}</p>
        ) : null}
        <h1 className="mt-2 font-black uppercase leading-[0.95] tracking-tight text-[#1d2739] text-3xl sm:text-4xl">
          {product.name}
        </h1>
        <p className="mt-3 text-xl font-bold text-[#1d2739]">${price.toFixed(2)}</p>
        <p className="mt-4 text-sm text-[#515a68] max-w-md">{product.description}</p>

        {colors.length > 0 ? (
          <div className="mt-8">
            <div className="flex items-center justify-between">
              <p className="text-[11px] font-bold uppercase tracking-[0.15em] text-[#1d2739]">Colour</p>
              {selectedColor ? (
                <p className="text-[11px] font-semibold uppercase tracking-wide text-[#6f7885]">{selectedColor}</p>
              ) : null}
            </div>
            <div className="mt-3 flex flex-wrap gap-2">
              {colors.map((c) => (
                <button
                  key={c}
                  onClick={() => setSelectedColor(c)}
                  className={`h-9 w-9 border-2 ${
                    selectedColor === c ? "border-[#1d2739]" : "border-transparent ring-1 ring-[rgba(29,39,57,0.18)]"
                  }`}
                  style={{ backgroundColor: c }}
                  title={c}
                  aria-label={c}
                />
              ))}
            </div>
          </div>
        ) : null}

        {sizes.length > 0 ? (
          <div className="mt-8">
            <div className="flex items-center justify-between">
              <p className="text-[11px] font-bold uppercase tracking-[0.15em] text-[#1d2739]">Size</p>
              <button
                type="button"
                className="text-[11px] font-semibold uppercase tracking-wide text-[#b08968] hover:underline"
              >
                Size guide
              </button>
            </div>
            <div className="mt-3 flex flex-wrap gap-2">
              {sizes.map((s) => {
                const disabled = !sizeAvailable(s);
                const selected = selectedSize === s;
                return (
                  <button
                    key={s}
                    disabled={disabled}
                    onClick={() => setSelectedSize(s)}
                    className={`min-w-11 h-11 px-3 text-sm font-bold border ${
                      disabled
                        ? "border-[rgba(29,39,57,0.15)] text-[#bcc3ce] line-through cursor-not-allowed"
                        : selected
                          ? "bg-[#1d2739] border-[#1d2739] text-white"
                          : "border-[rgba(29,39,57,0.35)] text-[#1d2739] hover:border-[#1d2739]"
                    }`}
                  >
                    {s}
                  </button>
                );
              })}
            </div>
          </div>
        ) : null}

        <button
          onClick={handleAddToCart}
          disabled={!canAdd || status === "adding"}
          className="mt-8 w-full bg-[#b08968] hover:bg-[#8f6d51] disabled:opacity-50 disabled:cursor-not-allowed text-white text-sm font-bold uppercase tracking-wide py-4 transition-colors"
        >
          {status === "adding" ? "Adding…" : ctaLabel}
        </button>
        {status === "error" ? <p className="mt-2 text-xs text-red-600">Couldn&apos;t add to cart — please try again.</p> : null}

        <div className="mt-10 grid grid-cols-2 gap-x-8 gap-y-5 border-t border-[rgba(29,39,57,0.18)] pt-6">
          <SpecRow label="Colour" value={selectedColor || colors.join(", ")} />
          <SpecRow label="Fabric" value={product.fabric} />
          <SpecRow label="Fit for" value={product.fitFor} />
          <SpecRow label="Fit" value={product.fit} />
          <SpecRow label="Run size" value={product.runSize || (sizes.length ? sizes.join(", ") : null)} />
          <SpecRow label="Made in" value={product.madeIn} />
        </div>

        <Link
          href="/shop"
          className="mt-8 inline-block text-[11px] font-bold uppercase tracking-[0.1em] text-[#b08968] hover:underline"
        >
          ← Back to the index
        </Link>
      </div>
    </div>
  );
}

function SpecRow({ label, value }: { label: string; value: string | null | undefined }) {
  if (!value) return null;
  return (
    <div>
      <p className="text-[10px] font-bold uppercase tracking-[0.12em] text-[#6f7885]">{label}</p>
      <p className="mt-1 text-sm font-semibold text-[#1d2739]">{value}</p>
    </div>
  );
}
