"use client";

import { Alert, Button, Chip, Label, NumberField, Spinner } from "@heroui/react";
import Image from "next/image";
import { useEffect, useMemo, useState } from "react";
import { ShopBreadcrumbBar } from "@/components/shop/ShopBreadcrumbBar";
import { useCartUI } from "@/components/cart/CartUIContext";
import { trackAddToCart } from "@/lib/cart/analytics";
import { getAddToCartErrorMessage } from "@/lib/cart/addToCartErrors";
import { useCartMutations } from "@/lib/cart/useCartMutations";
import { useCartSessionId } from "@/lib/cart/useCartSessionId";
import { formatPrice } from "@repo/utils";
import {
  PRODUCT_DETAIL_SECTION_IDS,
  getProductDetailBreadcrumbItems,
} from "@/lib/product-detail/constants";
import type {
  ProductDetailImage,
  ProductDetailProduct,
  ProductDetailVariant,
} from "@/lib/product-detail/types";

type ProductDetailHeroSectionProps = {
  product: ProductDetailProduct;
  category: string;
  subCategory: string;
};

function CartIcon({ className }: { className?: string }) {
  return (
    <svg
      className={className}
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="2"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden
    >
      <circle cx="9" cy="21" r="1" />
      <circle cx="20" cy="21" r="1" />
      <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6" />
    </svg>
  );
}

function TruckIcon({ className }: { className?: string }) {
  return (
    <svg
      className={className}
      viewBox="0 0 24 24"
      fill="currentColor"
      aria-hidden
    >
      <path
        fillRule="evenodd"
        clipRule="evenodd"
        d="M2 6.75C2 5.23 3.23 4 4.75 4h8.5C14.51 4 15.57 4.85 15.9 6h2.05c.9 0 1.75.44 2.26 1.18l1.3 1.88c.32.46.49 1 .49 1.56v3.66c0 1.25-.85 2.31-2 2.62A3.25 3.25 0 0 1 16.75 20a3.25 3.25 0 0 1-3.24-3h-3.02a3.25 3.25 0 0 1-3.24 3 3.25 3.25 0 0 1-3.25-3.08A2.49 2.49 0 0 1 2 14.36V6.75ZM4.28 15.44A3.24 3.24 0 0 1 7.25 13.5c1.35 0 2.51.83 3 2h3.5c.17-.42.43-.79.75-1.1V6.75c0-.69-.56-1.25-1.25-1.25h-8.5c-.69 0-1.25.56-1.25 1.25v7.61c0 .5.32.93.78 1.08ZM16 7.5v6.09c.24-.06.49-.09.75-.09 1.32 0 2.46.79 2.97 1.92.46-.17.78-.62.78-1.14v-3.66c0-.25-.08-.5-.22-.71l-1.3-1.87A1.25 1.25 0 0 0 17.95 7.5H16ZM7.25 15a1.75 1.75 0 1 0 0 3.5 1.75 1.75 0 0 0 0-3.5Zm9.5 0a1.75 1.75 0 1 0 0 3.5 1.75 1.75 0 0 0 0-3.5Z"
      />
    </svg>
  );
}

function ReturnIcon({ className }: { className?: string }) {
  return (
    <svg
      className={className}
      viewBox="0 0 24 24"
      fill="currentColor"
      aria-hidden
    >
      <path
        fillRule="evenodd"
        clipRule="evenodd"
        d="M4.84 3.5a1.75 1.75 0 0 1 1.65-1h7.32c.66 0 1.28.33 1.65 1l2.27 3.4c.35.36.57.85.57 1.4v1.23a.75.75 0 0 1-1.5 0V8.3c0-.13-.05-.24-.13-.33a.58.58 0 0 0-.35-.15H3.98a.58.58 0 0 0-.35.15.46.46 0 0 0-.13.33v8.63c0 .27.22.48.48.48h4.94a.75.75 0 0 1 0 1.5H3.98A1.98 1.98 0 0 1 2 16.93V8.3c0-.54.22-1.04.57-1.4L4.84 3.5Zm-.07 2.82h4.63V4.12H6.49a.25.25 0 0 0-.2.12L4.77 6.32Zm6.13-2.2v2.2h4.63l-1.32-1.98a.25.25 0 0 0-.2-.12h-2.91v-.1Zm4.71 7.35a.75.75 0 0 1 0 1.06l-1.19 1.19h.67c3.82 0 6.92 3.1 6.92 6.92a.75.75 0 0 1-1.5 0 5.42 5.42 0 0 0-5.42-5.42h-.67l1.19 1.19a.75.75 0 0 1-1.06 1.06l-2.47-2.47a.75.75 0 0 1 0-1.06l2.47-2.47a.75.75 0 0 1 1.06 0Z"
      />
    </svg>
  );
}

function ShieldIcon({ className }: { className?: string }) {
  return (
    <svg
      className={className}
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden
    >
      <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
      <path d="m9 12 2 2 4-4" />
    </svg>
  );
}

function StarIcon({ filled }: { filled?: boolean }) {
  return (
    <svg
      className="size-4 text-[var(--warm)]"
      viewBox="0 0 24 24"
      fill={filled ? "currentColor" : "none"}
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden
    >
      <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
    </svg>
  );
}

function StarRating({ value }: { value: number }) {
  const full = Math.floor(value);
  return (
    <span
      className="inline-flex items-center gap-0.5"
      aria-label={`${value} out of 5 stars`}
    >
      {[1, 2, 3, 4, 5].map((star) => (
        <StarIcon key={star} filled={star <= full} />
      ))}
    </span>
  );
}

type AttributeDimension = "size" | "flavor" | "color";

function getAttributeDimensions(
  variants: ProductDetailVariant[],
): AttributeDimension[] {
  const dims: AttributeDimension[] = [];
  if (variants.some((v) => v.attributes?.size != null)) dims.push("size");
  if (variants.some((v) => v.attributes?.flavor != null)) dims.push("flavor");
  if (variants.some((v) => v.attributes?.color != null)) dims.push("color");
  return dims;
}

function getUniqueValues(
  variants: ProductDetailVariant[],
  dimension: AttributeDimension,
): string[] {
  const set = new Set<string>();
  for (const v of variants) {
    const val = v.attributes?.[dimension];
    if (val != null && val !== "") set.add(val);
  }
  return Array.from(set).sort();
}

function findVariantBySelection(
  variants: ProductDetailVariant[],
  selection: Partial<Record<AttributeDimension, string>>,
): ProductDetailVariant | null {
  return (
    variants.find((v) =>
      (["size", "flavor", "color"] as const).every((dim) => {
        const sel = selection[dim];
        if (sel == null) return true;
        return v.attributes?.[dim] === sel;
      }),
    ) ?? null
  );
}

function getStockMessage(variant: ProductDetailVariant): string {
  if (variant.stockQuantity <= 0) return "Out of stock";
  if (variant.stockQuantity <= 5) return `Only ${variant.stockQuantity} left`;
  return "In stock";
}

function getStockColor(
  variant: ProductDetailVariant,
): "success" | "warning" | "danger" {
  if (variant.stockQuantity <= 0) return "danger";
  if (variant.stockQuantity <= 5) return "warning";
  return "success";
}

function stripHtml(html: string): string {
  return html.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
}

function firstThreeSentences(text: string): string {
  const sentences = text.match(/[^.!?]*[.!?]+/g);
  if (!sentences) return text;
  return sentences.slice(0, 3).join("").trim();
}

export function ProductDetailHeroSection({
  product,
  category,
  subCategory,
}: ProductDetailHeroSectionProps) {
  const sessionId = useCartSessionId();
  const { addItem } = useCartMutations(sessionId);
  const { openCart } = useCartUI();
  const [selectedImageIndex, setSelectedImageIndex] = useState(0);
  const [attributeSelection, setAttributeSelection] = useState<
    Partial<Record<AttributeDimension, string>>
  >({});
  const [quantity, setQuantity] = useState(1);
  const [isAdding, setIsAdding] = useState(false);
  const [addError, setAddError] = useState<string | null>(null);

  const images: ProductDetailImage[] = product.images ?? [];
  const variants = useMemo(
    () => (product.variants ?? []) as ProductDetailVariant[],
    [product.variants],
  );
  const mainImage = images[selectedImageIndex] ?? images[0];
  const dimensions = useMemo(
    () => getAttributeDimensions(variants),
    [variants],
  );

  const selectedVariant = useMemo(() => {
    if (variants.length === 0) return null;
    if (variants.length === 1) return variants[0];
    return (
      findVariantBySelection(variants, attributeSelection) ?? variants[0]
    );
  }, [variants, attributeSelection]);

  const breadcrumbItems = useMemo(
    () =>
      getProductDetailBreadcrumbItems({
        categorySlug: category,
        subCategorySlug: subCategory,
        subCategoryName: product.category?.name ?? subCategory,
        productName: product.name,
      }),
    [category, subCategory, product.category?.name, product.name],
  );

  const shortDescriptionText = useMemo(() => {
    const raw = product.shortDescription?.trim() || (product.description?.trim() ? stripHtml(product.description) : null);
    if (!raw) return null;
    return firstThreeSentences(raw);
  }, [product.shortDescription, product.description]);

  const canAddToCart =
    selectedVariant != null &&
    selectedVariant.stockQuantity > 0 &&
    quantity > 0;

  const addToCartButtonLabel =
    quantity > 1
      ? isAdding
        ? "Adding to cart, quantity " + quantity
        : "Add to cart, quantity " + quantity
      : isAdding
        ? "Adding to cart"
        : "Add to cart";

  const addToCartErrorId = "pdp-add-to-cart-error";

  useEffect(() => {
    setAddError(null);
  }, [quantity, selectedVariant?._id]);

  function handleAddToCart() {
    if (!canAddToCart || !selectedVariant) return;
    setAddError(null);
    setIsAdding(true);
    addItem(selectedVariant._id, quantity)
      .then(() => {
        setIsAdding(false);
        trackAddToCart({
          variantId: selectedVariant._id,
          quantity,
          source: "pdp",
        });
        openCart();
      })
      .catch((err: unknown) => {
        setIsAdding(false);
        setAddError(getAddToCartErrorMessage(err));
      });
  }

  return (
    <section
      id={PRODUCT_DETAIL_SECTION_IDS.hero}
      aria-label="Product overview"
      className="flex flex-col gap-6 md:gap-8"
    >
      <ShopBreadcrumbBar items={breadcrumbItems} />

      <div className="grid grid-cols-1 gap-6 md:grid-cols-2 md:gap-10 lg:items-start">
        {/* Gallery — sticky on desktop so it stays visible alongside a tall buy box */}
        <div className="flex flex-col gap-3 lg:sticky lg:top-24">
          <div className="relative aspect-square w-full overflow-hidden rounded-xl bg-[var(--surface-secondary)] shadow-sm md:aspect-[4/3]">
            {mainImage ? (
              <Image
                src={mainImage.url}
                alt={mainImage.alt ?? product.name}
                fill
                priority
                className="object-cover"
                sizes="(max-width: 768px) 100vw, 50vw"
              />
            ) : (
              <div
                className="absolute inset-0 flex items-center justify-center text-[var(--muted)]"
                aria-hidden
              >
                No image
              </div>
            )}
          </div>

          {images.length > 1 && (
            <>
              {/* Mobile: horizontal scrollable thumbnail strip */}
              <div className="flex gap-2 overflow-x-auto scrollbar-hide py-1 md:hidden">
                {images.map((img, i) => (
                  <button
                    key={img._id}
                    type="button"
                    onClick={() => setSelectedImageIndex(i)}
                    className="relative h-16 w-16 shrink-0 overflow-hidden rounded-lg border-2 transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--accent)]"
                    style={{
                      borderColor:
                        selectedImageIndex === i
                          ? "var(--accent)"
                          : "transparent",
                    }}
                    aria-label={`View image ${i + 1}`}
                  >
                    <Image
                      src={img.url}
                      alt={img.alt ?? `${product.name} ${i + 1}`}
                      fill
                      className="object-cover"
                      sizes="64px"
                    />
                  </button>
                ))}
              </div>

              {/* Tablet+: flex wrap thumbnails */}
              <div className="hidden md:flex flex-wrap gap-2 p-2">
                {images.map((img, i) => (
                  <button
                    key={img._id}
                    type="button"
                    onClick={() => setSelectedImageIndex(i)}
                    className="relative h-16 w-16 shrink-0 overflow-hidden rounded-lg border-2 transition-colors focus:outline-none focus:ring-2 focus:ring-[var(--accent)]"
                    style={{
                      borderColor:
                        selectedImageIndex === i
                          ? "var(--accent)"
                          : "transparent",
                    }}
                    aria-label={`View image ${i + 1}`}
                  >
                    <Image
                      src={img.url}
                      alt={img.alt ?? `${product.name} ${i + 1}`}
                      fill
                      className="object-cover"
                      sizes="64px"
                    />
                  </button>
                ))}
              </div>
            </>
          )}
        </div>

        {/* Buy box */}
        <div className="flex flex-col gap-4">
          {product.brand && (
            <Chip color="accent" variant="soft" size="sm" className="w-fit">
              {product.brand}
            </Chip>
          )}

          <h1 className="font-[family-name:var(--font-fraunces)] text-2xl font-semibold tracking-tight text-[var(--foreground)] md:text-3xl">
            {product.name}
          </h1>

          {product.averageRating != null &&
            product.reviewCount != null &&
            product.reviewCount > 0 && (
              <a
                href={`#${PRODUCT_DETAIL_SECTION_IDS.reviews}`}
                className="inline-flex w-fit items-center gap-2 text-sm text-[var(--muted)] transition-colors hover:text-[var(--foreground)]"
              >
                <StarRating value={product.averageRating} />
                <span className="font-sans">
                  {product.averageRating.toFixed(1)} ({product.reviewCount}{" "}
                  {product.reviewCount === 1 ? "review" : "reviews"})
                </span>
              </a>
            )}

          {/* Short description — 3-line clamp for quick product overview */}
          {shortDescriptionText && (
            <p className="line-clamp-3 text-sm leading-relaxed text-[var(--muted)]">
              {shortDescriptionText}
            </p>
          )}

          {/* Variant selector — real <form> + <fieldset> + <legend> + <input type="radio"> per SEO rule */}
          {variants.length > 1 && dimensions.length > 0 && (
            <form
              onSubmit={(e) => e.preventDefault()}
              className="space-y-4"
              aria-label="Variant selection"
            >
              {dimensions.map((dim) => {
                const options = getUniqueValues(variants, dim);
                if (options.length <= 1) return null;
                const label = dim.charAt(0).toUpperCase() + dim.slice(1);
                const name = `pdp-variant-${dim}`;
                return (
                  <fieldset key={dim} className="space-y-2">
                    <legend className="text-sm font-medium text-[var(--foreground)]">
                      {label}
                    </legend>
                    <div className="flex flex-wrap gap-2">
                      {options.map((value) => (
                        <label
                          key={value}
                          className="flex cursor-pointer items-center rounded-full border border-[var(--border)] px-4 py-2 text-sm transition-all has-[:checked]:border-[var(--accent)] has-[:checked]:bg-[var(--brand-mist)] has-[:checked]:font-medium has-[:checked]:text-[var(--brand-dark)] hover:border-[var(--accent)]/50"
                        >
                          <input
                            type="radio"
                            name={name}
                            value={value}
                            checked={
                              (attributeSelection[dim] ?? null) === value
                            }
                            onChange={() =>
                              setAttributeSelection((prev) => ({
                                ...prev,
                                [dim]: value,
                              }))
                            }
                            className="sr-only"
                          />
                          <span>{value}</span>
                        </label>
                      ))}
                    </div>
                  </fieldset>
                );
              })}
            </form>
          )}

          {selectedVariant && (
            <>
              {/* Price block */}
              <div className="flex flex-wrap items-baseline gap-3">
                <span className="text-2xl font-bold text-[var(--brand-dark)]">
                  {formatPrice(selectedVariant.price)}
                </span>
                {selectedVariant.compareAtPrice != null &&
                  selectedVariant.compareAtPrice > selectedVariant.price && (
                    <>
                      <span className="text-sm text-[var(--muted)] line-through">
                        {formatPrice(selectedVariant.compareAtPrice)}
                      </span>
                      <Chip color="danger" variant="soft" size="sm">
                        Save{" "}
                        {Math.round(
                          ((selectedVariant.compareAtPrice -
                            selectedVariant.price) /
                            selectedVariant.compareAtPrice) *
                            100,
                        )}
                        %
                      </Chip>
                    </>
                  )}
              </div>

              {/* Stock status + SKU */}
              <div className="flex items-center gap-3">
                <Chip
                  color={getStockColor(selectedVariant)}
                  variant="soft"
                  size="sm"
                >
                  {getStockMessage(selectedVariant)}
                </Chip>
                {selectedVariant.sku && (
                  <span className="text-xs text-[var(--muted)]">
                    SKU: {selectedVariant.sku}
                  </span>
                )}
              </div>

              {/* Quantity + Add to Cart */}
              <div className="flex flex-col gap-4 md:flex-row md:items-end">
                <NumberField
                  value={quantity}
                  onChange={(val) => setQuantity(val ?? 1)}
                  minValue={1}
                  maxValue={selectedVariant.stockQuantity || 99}
                  name="pdp-quantity"
                  className="w-full md:w-auto"
                >
                  <Label className="text-sm font-medium text-[var(--foreground)]">
                    Quantity
                  </Label>
                  <NumberField.Group>
                    <NumberField.DecrementButton />
                    <NumberField.Input className="w-16 text-center" />
                    <NumberField.IncrementButton />
                  </NumberField.Group>
                </NumberField>

                <Button
                  variant="primary"
                  size="lg"
                  onPress={handleAddToCart}
                  isDisabled={!canAddToCart || isAdding}
                  isPending={isAdding}
                  className="w-full md:w-auto min-w-[180px] text-sm font-medium"
                  aria-label={addToCartButtonLabel}
                  aria-busy={isAdding}
                  aria-describedby={addError ? addToCartErrorId : undefined}
                >
                  {isAdding ? (
                    <>
                      <Spinner
                        size="sm"
                        color="current"
                        className="shrink-0"
                      />
                      Adding…
                    </>
                  ) : (
                    <>
                      <CartIcon className="size-5 shrink-0" />
                      Add to cart
                    </>
                  )}
                </Button>
              </div>

              {/* Delivery & trust info */}
              <div className="mt-1 flex flex-col gap-3 border-t border-[var(--separator)] pt-5">
                <div className="flex items-start gap-3 text-sm text-[var(--muted)]">
                  <TruckIcon className="mt-0.5 size-5 shrink-0 text-[var(--brand)]" />
                  <span>
                    Free delivery on orders over £50
                  </span>
                </div>
                <div className="flex items-start gap-3 text-sm text-[var(--muted)]">
                  <ReturnIcon className="mt-0.5 size-5 shrink-0 text-[var(--brand)]" />
                  <span>
                    Easy 30-day returns
                  </span>
                </div>
                <div className="flex items-start gap-3 text-sm text-[var(--muted)]">
                  <ShieldIcon className="mt-0.5 size-5 shrink-0 text-[var(--brand)]" />
                  <span>
                    Secure checkout
                  </span>
                </div>
              </div>

              {addError && (
                <Alert
                  id={addToCartErrorId}
                  status="danger"
                  className="w-full"
                  role="alert"
                  aria-live="polite"
                >
                  <Alert.Indicator />
                  <Alert.Content>
                    <Alert.Title>Could not add to cart</Alert.Title>
                    <Alert.Description>{addError}</Alert.Description>
                    <button
                      type="button"
                      onClick={() => setAddError(null)}
                      className="mt-2 font-medium underline focus:outline-none focus:ring-2 focus:ring-offset-2 rounded"
                    >
                      Dismiss
                    </button>
                  </Alert.Content>
                </Alert>
              )}
            </>
          )}
        </div>
      </div>
    </section>
  );
}
