"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { ChevronLeft, ChevronRight, Heart, Minus, Plus, ShoppingCart } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { makeCartLineKey, useCart } from "@/components/shop/cart-context";
import { useAuthModal } from "@/components/shop/auth-modal-context";
import { usePublicSession } from "@/components/shop/public-session-context";
import type { Product } from "@/lib/public-product";
import { resolvePublicMediaUrl } from "@/lib/public-product";
import {
  computeCompareAtPrice,
  computeUnitPrice,
  getAvailableStock,
  getDefaultVariantSelections,
} from "@/lib/product-price";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import DataService from "@/config/axios";
import { getApiErrorMessage } from "@/lib/api-error";
import { stableVariantSelectionsKey } from "@/lib/wishlist-variant-key";
import { saveBuyNowLine } from "@/lib/buy-now";
import { cn } from "@/lib/utils";
import { toast } from "sonner";
import {
  WHATSAPP_STORE_NAME,
  WhatsAppIcon,
  buildWhatsAppApiHref,
} from "@/components/shop/whatsapp-shared";
import ProductShippingBadges from "@/components/shop/product-shipping-badges";

type WishlistApiRow = {
  _id: string;
  variantKey?: string;
  product?: { _id: string } | null;
};

function escapeHtmlForDescription(text: string) {
  return text
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#39;");
}

/** For storefront description tab: Quill/saved HTML, or legacy plain text (escaped). */
function toProductDescriptionHtml(raw: string): string {
  const t = String(raw);
  if (!t.trim()) return "";
  if (/<\s*\/?[a-z][\s\S]*?>/i.test(t)) {
    return t;
  }
  return `<p class="whitespace-pre-wrap">${escapeHtmlForDescription(t).replace(/\n/g, "<br />")}</p>`;
}

export default function ProductDetail({ slug }: { slug: string }) {
  const router = useRouter();
  const [product, setProduct] = useState<Product | null>(null);
  const [loading, setLoading] = useState(true);
  const [activeImageIndex, setActiveImageIndex] = useState(0);
  const [selections, setSelections] = useState<Record<string, string>>({});
  const [qty, setQty] = useState(1);
  const [wishlistRowId, setWishlistRowId] = useState<string | null>(null);
  const [pageUrl, setPageUrl] = useState("");
  const { addLine, lines } = useCart();
  const { openAuthModal } = useAuthModal();
  const { isAuthenticated, refresh } = usePublicSession();

  useEffect(() => {
    if (typeof window !== "undefined") {
      setPageUrl(window.location.href);
    }
  }, [slug]);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await DataService.get(`/public/products/${encodeURIComponent(slug)}`);
      const p = res.data?.data as Product | undefined;
      setProduct(p || null);
      if (p?.variants?.length) {
        setSelections(getDefaultVariantSelections(p));
      } else {
        setSelections({});
      }
    } catch {
      setProduct(null);
    } finally {
      setLoading(false);
    }
  }, [slug]);

  useEffect(() => {
    load();
  }, [load]);

  useEffect(() => {
    setActiveImageIndex(0);
  }, [product?._id]);

  const unitPrice = useMemo(() => {
    if (!product) return 0;
    return computeUnitPrice(product, product.variants, selections);
  }, [product, selections]);

  const compareAt = useMemo(() => {
    if (!product) return 0;
    return computeCompareAtPrice(product, product.variants, selections);
  }, [product, selections]);

  const availableStock = useMemo(() => {
    if (!product) return 0;
    return getAvailableStock(product, product.variants, selections);
  }, [product, selections]);

  useEffect(() => {
    if (availableStock <= 0) return;
    setQty((q) => Math.min(q, availableStock));
  }, [availableStock]);

  const syncWishlistRow = useCallback(async () => {
    if (!isAuthenticated || !product) {
      setWishlistRowId(null);
      return;
    }
    try {
      const res = await DataService.get("/user/shop/wishlist");
      const rows = (res.data?.data || []) as WishlistApiRow[];
      const vKey = stableVariantSelectionsKey(selections);
      const hit = rows.find(
        (r) => r.product?._id === product._id && String(r.variantKey ?? "") === vKey,
      );
      setWishlistRowId(hit?._id ?? null);
    } catch {
      setWishlistRowId(null);
    }
  }, [isAuthenticated, product, selections]);

  useEffect(() => {
    void syncWishlistRow();
  }, [syncWishlistRow]);

  const galleryImages = product?.images || [];
  const mainImage = galleryImages[activeImageIndex] ?? galleryImages[0];
  const imgUrl = resolvePublicMediaUrl(mainImage);
  const canSlideImages = galleryImages.length > 1;

  const showPreviousImage = () => {
    if (!galleryImages.length) return;
    setActiveImageIndex((current) =>
      current === 0 ? galleryImages.length - 1 : current - 1,
    );
  };

  const showNextImage = () => {
    if (!galleryImages.length) return;
    setActiveImageIndex((current) =>
      current === galleryImages.length - 1 ? 0 : current + 1,
    );
  };

  const addToCart = () => {
    if (!product) return;
    for (const g of product.variants || []) {
      if (!selections[g.name]?.trim()) {
        toast.error(`Please select ${g.name}`);
        return;
      }
    }
    if (availableStock <= 0) {
      toast.error("This option is out of stock");
      return;
    }
    const key = makeCartLineKey(product._id, selections);
    const existing = lines.find((l) => l.key === key);
    const inCart = existing?.quantity ?? 0;
    const room = Math.max(0, availableStock - inCart);
    const addQty = Math.min(qty, room);
    if (addQty <= 0) {
      toast.error(
        `Only ${availableStock} in stock — you already have ${inCart} of this option in your cart`,
      );
      return;
    }
    addLine({
      productId: product._id,
      slug: product.slug,
      title: product.title,
      image: mainImage,
      quantity: addQty,
      unitPrice,
      variantSelections: selections,
      shippingPerUnit: Number(product.shippingCost) || 0,
      availableStock,
    });
    if (addQty < qty) {
      toast.success(
        `Added ${addQty} to cart (max ${availableStock} for this option; ${inCart} were already in cart)`,
      );
    } else {
      toast.success("Added to cart");
    }
  };

  const toggleWishlist = async () => {
    if (!product) return;
    if (!isAuthenticated) {
      openAuthModal("login");
      return;
    }
    if (wishlistRowId) {
      try {
        await DataService.delete(`/user/shop/wishlist/${wishlistRowId}`);
        setWishlistRowId(null);
        await refresh();
        toast.success("Removed from wishlist");
      } catch (e: unknown) {
        toast.error(getApiErrorMessage(e, "Could not remove from wishlist"));
      }
      return;
    }
    for (const g of product.variants || []) {
      if (!selections[g.name]?.trim()) {
        toast.error(`Please select ${g.name}`);
        return;
      }
    }
    if (availableStock <= 0) {
      toast.error("This option is out of stock");
      return;
    }
    try {
      const res = await DataService.post("/user/shop/wishlist", {
        productId: product._id,
        variantSelections: selections,
      });
      const row = res.data?.data as WishlistApiRow | undefined;
      if (row?._id) setWishlistRowId(row._id);
      await refresh();
      toast.success("Saved to wishlist");
    } catch (e: unknown) {
      toast.error(getApiErrorMessage(e, "Could not save wishlist"));
    }
  };

  const buyNow = () => {
    if (!product) return;
    for (const g of product.variants || []) {
      if (!selections[g.name]?.trim()) {
        toast.error(`Please select ${g.name}`);
        return;
      }
    }
    if (availableStock <= 0) {
      toast.error("This option is out of stock");
      return;
    }
    saveBuyNowLine({
      productId: product._id,
      slug: product.slug,
      title: product.title,
      image: mainImage,
      quantity: qty,
      unitPrice,
      variantSelections: selections,
      shippingPerUnit: Number(product.shippingCost) || 0,
      availableStock,
    });
    router.push("/checkout/pay?source=buy-now");
  };

  if (loading) {
    return (
      <div className="mx-auto min-w-0 w-full max-w-[1400px] px-4 py-16 text-center text-gray-500 sm:px-6 lg:px-8">
        Loading…
      </div>
    );
  }

  if (!product) {
    return (
      <div className="mx-auto min-w-0 w-full max-w-[1400px] px-4 py-16 text-center sm:px-6 lg:px-8">
        <p className="text-gray-600">Product not found.</p>
        <Button asChild className="mt-4">
          <Link href="/product">Back to products</Link>
        </Button>
      </div>
    );
  }

  const showListStrike = compareAt > unitPrice + 0.005;

  const whatsappMessage = `Hi, I want to purchase this product ${product.title} for Rs${unitPrice.toFixed(0)}${pageUrl ? ` ${pageUrl}` : ""} ${WHATSAPP_STORE_NAME}`;
  const whatsappHref = buildWhatsAppApiHref(whatsappMessage);

  const primaryCategory = product.categories?.[0] ?? null;

  return (
    <div className="mx-auto min-w-0 w-full max-w-[1400px] px-4 pb-10 pt-3 sm:px-6 lg:px-8">
      <div className="mb-2">
        <Breadcrumb>
          <BreadcrumbList className="gap-0 text-xs text-slate-600 sm:text-sm [&_a]:text-slate-600 [&_a]:hover:text-primary">
            <BreadcrumbItem className="gap-0">
              <BreadcrumbLink asChild>
                <Link href="/">Home</Link>
              </BreadcrumbLink>
            </BreadcrumbItem>
            {primaryCategory ? (
              <>
                <BreadcrumbSeparator className="px-1 text-slate-400 [&>svg]:hidden">
                  <span aria-hidden="true">»</span>
                </BreadcrumbSeparator>
                <BreadcrumbItem className="gap-0">
                  <BreadcrumbLink asChild>
                    <Link href={`/product?category=${encodeURIComponent(primaryCategory.slug)}`}>
                      {primaryCategory.name}
                    </Link>
                  </BreadcrumbLink>
                </BreadcrumbItem>
                <BreadcrumbSeparator className="px-1 text-slate-400 [&>svg]:hidden">
                  <span aria-hidden="true">»</span>
                </BreadcrumbSeparator>
              </>
            ) : (
              <BreadcrumbSeparator className="px-1 text-slate-400 [&>svg]:hidden">
                <span aria-hidden="true">»</span>
              </BreadcrumbSeparator>
            )}
            <BreadcrumbItem className="min-w-0 gap-0">
              <BreadcrumbPage className="line-clamp-1 max-w-[min(100%,28rem)] font-medium text-slate-700">
                {product.title}
              </BreadcrumbPage>
            </BreadcrumbItem>
          </BreadcrumbList>
        </Breadcrumb>
      </div>
      <div className="grid min-w-0 gap-6 lg:grid-cols-2 lg:gap-10">
        <div className="min-w-0 space-y-3">
          <div className="relative aspect-square max-h-[480px] overflow-hidden rounded-lg border bg-gray-50">
            {imgUrl ? (
              <Image
                src={imgUrl}
                alt={product.title}
                fill
                className="object-contain"
                sizes="(max-width: 1024px) 100vw, 50vw"
              />
            ) : (
              <div className="flex h-full items-center justify-center text-gray-400">No image</div>
            )}
            {canSlideImages ? (
              <>
                <Button
                  type="button"
                  variant="outline"
                  size="icon"
                  className="absolute left-3 top-1/2 h-8 w-8 -translate-y-1/2 rounded-full bg-white/90"
                  onClick={showPreviousImage}
                  aria-label="Previous image"
                >
                  <ChevronLeft className="size-4" />
                </Button>
                <Button
                  type="button"
                  variant="outline"
                  size="icon"
                  className="absolute right-3 top-1/2 h-8 w-8 -translate-y-1/2 rounded-full bg-white/90"
                  onClick={showNextImage}
                  aria-label="Next image"
                >
                  <ChevronRight className="size-4" />
                </Button>
              </>
            ) : null}
          </div>
          {canSlideImages ? (
            <div className="flex flex-wrap gap-2">
              {galleryImages.map((image, index) => {
                const thumbUrl = resolvePublicMediaUrl(image);
                if (!thumbUrl) return null;
                return (
                  <button
                    key={`${thumbUrl}-${index}`}
                    type="button"
                    onClick={() => setActiveImageIndex(index)}
                    className={cn(
                      "relative h-16 w-16 overflow-hidden rounded-md border bg-gray-100 transition",
                      index === activeImageIndex
                        ? "border-primary ring-2 ring-primary/40"
                        : "border-gray-200 hover:border-gray-400",
                    )}
                    aria-label={`Open image ${index + 1}`}
                    aria-current={index === activeImageIndex}
                  >
                    <Image
                      src={thumbUrl}
                      alt={`${product.title} thumbnail ${index + 1}`}
                      fill
                      className="object-cover"
                      sizes="64px"
                    />
                  </button>
                );
              })}
            </div>
          ) : null}
        </div>
        <div className="min-w-0 space-y-6">
          <div>
            <h1 className="text-3xl font-bold break-words text-slate-900">{product.title}</h1>
            <div className="mt-3 flex flex-wrap items-baseline gap-2">
              <span className="text-3xl font-bold text-primary">{unitPrice.toFixed(2)}</span>
              {showListStrike ? (
                <span className="text-xl text-gray-400 line-through">{compareAt.toFixed(2)}</span>
              ) : null}
            </div>
            <ProductShippingBadges
              className="mt-3"
              display="detail"
              shippingCost={product.shippingCost}
              freeShipping={product.freeShipping}
              expressShipping={product.expressShipping}
            />
            <p className="mt-2 text-sm text-gray-600">
              {availableStock == 0 && <span className="text-amber-700">Out of stock</span>}
            </p>
          </div>

          {product.variants?.map((g) => (
            <div key={g.name} className="grid gap-2">
              <Label>{g.name}</Label>
              <Select
                value={selections[g.name] || ""}
                onValueChange={(v) => setSelections((s) => ({ ...s, [g.name]: v }))}
              >
                <SelectTrigger className="max-w-xs">
                  <SelectValue placeholder={`Select ${g.name}`} />
                </SelectTrigger>
                <SelectContent>
                  {(g.values || []).map((v) => {
                    const hypo = { ...selections, [g.name]: v.label };
                    const pay = computeUnitPrice(product, product.variants, hypo);
                    const list = computeCompareAtPrice(product, product.variants, hypo);
                    const strike = list > pay + 0.005;
                    const payStr = pay.toFixed(2);
                    const listStr = list.toFixed(2);
                    const label = v?.label

                    return (
                      <SelectItem
                        key={v.label}
                        value={v.label}
                        textValue={`${v.label} ${payStr} ${strike ? listStr : ""}`}
                      >
                        {label}
                      </SelectItem>
                    );
                  })}
                </SelectContent>
              </Select>
            </div>
          ))}

          <div className="grid max-w-xs gap-2">
            <Label>Quantity</Label>
            {availableStock <= 0 ? (
              <p className="rounded-md border border-dashed px-3 py-2 text-sm text-gray-500">—</p>
            ) : (
              <div className="flex h-10 max-w-[11rem] items-stretch rounded-md border border-input bg-background">
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="shrink-0 rounded-r-none px-3"
                  disabled={qty <= 1}
                  onClick={() => setQty((q) => Math.max(1, q - 1))}
                  aria-label="Decrease quantity"
                >
                  <Minus className="size-4" />
                </Button>
                <div className="flex min-w-[2.5rem] flex-1 items-center justify-center text-sm font-medium tabular-nums text-slate-900">
                  {qty}
                </div>
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="shrink-0 rounded-l-none px-3"

                  onClick={() => setQty((q) => Math.min(availableStock, q + 1))}
                  aria-label="Increase quantity"
                >
                  <Plus className="size-4" />
                </Button>
              </div>
            )}
          </div>

          <div>
            <Button
              asChild
              type="button"
              size="lg"
              variant="outline"
              className="border-[#25D366] bg-white text-[#075E54] hover:bg-[#25D366]/10 hover:text-[#075E54]"
            >
              <a
                href={whatsappHref}
                target="_blank"
                rel="noopener noreferrer"
                aria-label="Chat about this product on WhatsApp"
              >
                <span className="mr-2 inline-flex size-6 items-center justify-center rounded-full bg-[#25D366] text-white">
                  <WhatsAppIcon className="size-4" />
                </span>
                Chat on WhatsApp
              </a>
            </Button>
          </div>

          <div className="flex flex-wrap gap-3">
            <Button
              type="button"
              size="lg"
              onClick={addToCart}
              disabled={availableStock <= 0}
            >
              <ShoppingCart className="mr-2 size-5" />
              Add to cart
            </Button>
            <Button type="button" size="lg" variant="secondary" onClick={buyNow} disabled={availableStock <= 0}>
              Buy now
            </Button>
            <Button
              type="button"
              size="lg"
              variant="outline"
              onClick={toggleWishlist}
              disabled={!wishlistRowId && availableStock <= 0}
            >
              <Heart
                className={cn(
                  "mr-2 size-5 shrink-0",
                  wishlistRowId && "fill-red-600 text-red-600",
                )}
              />
              {wishlistRowId ? "Remove In Wishlist" : "Add In Wishlist"}
            </Button>
          </div>
        </div>
      </div>

      <section
        className="mt-12 min-w-0 w-full max-w-full rounded-lg "
        aria-label="Product details"
      >
        <Tabs defaultValue="features" className="w-full min-w-0 max-w-full">
          <TabsList className="w-full min-w-0 justify-start sm:w-auto">
            <TabsTrigger value="features">Features &amp; description</TabsTrigger>
            <TabsTrigger value="reviews">Reviews</TabsTrigger>
          </TabsList>
          <TabsContent value="features" className="mt-6 min-w-0 space-y-8">
            {product.features && product.features.length > 0 ? (
              <div>
                <h2 className="text-lg font-semibold text-slate-900">Features</h2>
                <div className="mt-3 overflow-x-auto rounded-md border">
                  <table className="w-full min-w-[280px] text-sm">
                    <thead className="bg-slate-50 text-left text-slate-700">
                      <tr>
                        <th className="px-4 py-2 font-medium">Name</th>
                        <th className="px-4 py-2 font-medium">Detail</th>
                      </tr>
                    </thead>
                    <tbody>
                      {product.features.map((f, i) => {
                        if (typeof f === "string") {
                          return (
                            <tr key={`${f}-${i}`} className="border-t">
                              <td className="px-4 py-2 text-gray-500">—</td>
                              <td className="px-4 py-2 text-gray-800">{f}</td>
                            </tr>
                          );
                        }
                        return (
                          <tr key={`${f.label}-${f.value}-${i}`} className="border-t">
                            <td className="px-4 py-2 font-medium text-slate-900">
                              {f.label || "—"}
                            </td>
                            <td className="px-4 py-2 text-gray-800">{f.value}</td>
                          </tr>
                        );
                      })}
                    </tbody>
                  </table>
                </div>
              </div>
            ) : null}
            {product.description ? (
              <div className="w-full min-w-0 max-w-full">
                <h2 className="mb-3 text-lg font-semibold text-slate-900">Description</h2>
                <div
                  className={cn(
                    "prose prose-slate prose-sm max-w-none w-full min-w-0",
                    "break-words text-slate-700",
                    "[&_pre]:max-w-full [&_pre]:overflow-x-auto",
                    "[&_code]:break-words",
                    "[&_img]:my-2 [&_img]:max-w-full [&_img]:h-auto",
                    "[&_a]:text-primary hover:[&_a]:underline",
                  )}
                  dangerouslySetInnerHTML={{ __html: toProductDescriptionHtml(product.description) }}
                />
              </div>
            ) : null}
            {(!product.features || product.features.length === 0) && !product.description ? (
              <p className="text-sm text-gray-600">No features or description added for this product.</p>
            ) : null}
          </TabsContent>
          <TabsContent value="reviews" className="mt-6">
            <p className="text-sm text-gray-600">No reviews yet. Be the first to review this product.</p>
          </TabsContent>
        </Tabs>
      </section>
    </div>
  );
}
