import { useEffect, useMemo, useRef, useState } from "react";
import { useNavigate, useParams, Link } from "react-router-dom";
import {
  ShoppingBag,
  Plus,
  Minus,
  Check,
  ShieldCheck,
  Truck,
  Download,
  ArrowLeft,
} from "lucide-react";
import { createClient } from "@metagptx/web-sdk";
import SiteLayout from "@/components/SiteLayout";
import LoadingSpinner from "@/components/LoadingSpinner";
import StarRating from "@/components/shop/StarRating";
import { useCart } from "@/context/CartContext";
import { toast } from "sonner";
import { formatPrice, PRIMARY_CURRENCY } from "@/lib/currency";
import { Price } from "@/components/ui/Price";
import { flyToCart } from "@/lib/flyToCart";
import { GetPriceModal } from "@/components/ContactModals";

const client = createClient();

interface Product {
  id: number;
  name: string;
  slug: string;
  description?: string | null;
  long_description?: string | null;
  product_type: string;
  price: number;
  compare_at_price?: number | null;
  currency?: string | null;
  category_id?: number | null;
  tags?: string | null;
  image_url?: string | null;
  gallery?: string | null;
  stock?: number | null;
  sku?: string | null;
  variants?: string | null;
  is_active?: boolean | null;
  featured?: boolean | null;
}

interface Review {
  id: number;
  product_id: number;
  rating: number;
  title?: string | null;
  comment?: string | null;
  user_id?: string | null;
  is_approved?: boolean | null;
  created_at?: string | null;
}

interface VariantOption {
  name: string;
  options: string[];
}

interface HardwareSpec {
  label: string;
  value: string;
}

interface HardwareMeta {
  brand?: string;
  model?: string;
  specs?: HardwareSpec[];
}

export default function ProductDetail() {
  const { slug } = useParams<{ slug: string }>();
  const navigate = useNavigate();
  const { addToCart } = useCart();

  const [product, setProduct] = useState<Product | null>(null);
  const [reviews, setReviews] = useState<Review[]>([]);
  const [loading, setLoading] = useState(true);
  const [quantity, setQuantity] = useState(1);
  const [activeImage, setActiveImage] = useState<string>("");
  const [selectedVariants, setSelectedVariants] = useState<Record<string, string>>({});
  // Reference to the main hero image so we can clone it for the fly-to-cart
  // animation when the user adds this product to their cart.
  const heroImageRef = useRef<HTMLImageElement | null>(null);

  // Review form
  const [newRating, setNewRating] = useState(5);
  const [newTitle, setNewTitle] = useState("");
  const [newComment, setNewComment] = useState("");
  const [submittingReview, setSubmittingReview] = useState(false);
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [quoteOpen, setQuoteOpen] = useState(false);

  useEffect(() => {
    const load = async () => {
      setLoading(true);
      try {
        // Find product by slug
        const res = await client.entities.products.queryAll({
          query: { slug },
          limit: 1,
        });
        const items = (res?.data?.items || []) as Product[];
        if (!items.length) {
          setProduct(null);
          return;
        }
        const p = items[0];
        setProduct(p);
        setActiveImage(p.image_url || "");

        // Load reviews for this product
        const revRes = await client.entities.product_reviews.queryAll({
          query: { product_id: p.id, is_approved: true },
          sort: "-id",
          limit: 50,
        });
        setReviews((revRes?.data?.items || []) as Review[]);
      } finally {
        setLoading(false);
      }
    };
    if (slug) load();
  }, [slug]);

  useEffect(() => {
    const checkAuth = async () => {
      try {
        const u = await client.auth.me();
        setIsLoggedIn(!!u?.data);
      } catch {
        setIsLoggedIn(false);
      }
    };
    checkAuth();
  }, []);

  const variantConfig = useMemo<VariantOption[]>(() => {
    if (!product?.variants) return [];
    try {
      const parsed = JSON.parse(product.variants);
      if (Array.isArray(parsed)) return parsed;
    } catch {
      // ignore
    }
    return [];
  }, [product]);

  // Hardware metadata: when variants is an object with a `specs` array (as
  // produced by the Server Hardware seed), surface a brand/model header and a
  // spec table rather than clickable variant pills.
  const hardwareMeta = useMemo<HardwareMeta | null>(() => {
    if (!product?.variants) return null;
    try {
      const parsed = JSON.parse(product.variants);
      if (
        parsed &&
        typeof parsed === "object" &&
        !Array.isArray(parsed) &&
        Array.isArray((parsed as HardwareMeta).specs)
      ) {
        return parsed as HardwareMeta;
      }
    } catch {
      // ignore
    }
    return null;
  }, [product]);

  const galleryImages = useMemo<string[]>(() => {
    if (!product) return [];
    const list = [product.image_url].filter(Boolean) as string[];
    if (product.gallery) {
      try {
        const parsed = JSON.parse(product.gallery);
        if (Array.isArray(parsed)) {
          for (const u of parsed) {
            if (typeof u === "string" && u && !list.includes(u)) list.push(u);
          }
        }
      } catch {
        // ignore
      }
    }
    return list;
  }, [product]);

  const avgRating = useMemo(() => {
    if (!reviews.length) return 0;
    return reviews.reduce((a, r) => a + (r.rating || 0), 0) / reviews.length;
  }, [reviews]);

  const variantLabel = useMemo(() => {
    if (!variantConfig.length) return "";
    return variantConfig
      .map((v) => selectedVariants[v.name])
      .filter(Boolean)
      .map((val, i) => `${variantConfig[i].name}: ${val}`)
      .join(", ");
  }, [variantConfig, selectedVariants]);

  const stock = product?.stock ?? 0;
  const inStock = stock === -1 || stock > 0;
  const hasDiscount =
    product?.compare_at_price &&
    product.compare_at_price > 0 &&
    product.compare_at_price > product.price;

  const handleAddToCart = (opts: { skipAnimation?: boolean } = {}) => {
    if (!product) return false;
    if (variantConfig.length && Object.keys(selectedVariants).length < variantConfig.length) {
      toast.error("Please select all variant options.");
      return false;
    }
    // Fire-and-forget: animation runs independently so state updates aren't blocked.
    if (!opts.skipAnimation) {
      void flyToCart({
        source: heroImageRef.current,
        imageSrc: activeImage || product.image_url || undefined,
      });
    }
    addToCart({
      product_id: product.id,
      name: product.name,
      slug: product.slug,
      image_url: product.image_url || "",
      product_type: product.product_type,
      unit_price: product.price,
      currency: PRIMARY_CURRENCY,
      variant_label: variantLabel,
      quantity,
      stock: product.stock ?? -1,
    });
    toast.success(`${product.name} added to cart`);
    return true;
  };

  const handleBuyNow = () => {
    // Skip the flying animation here — we're navigating straight to checkout
    // so there's no cart icon to fly towards.
    const added = handleAddToCart({ skipAnimation: true });
    if (added) navigate("/shop/checkout");
  };

  const handleSubmitReview = async () => {
    if (!product) return;
    if (!isLoggedIn) {
      toast.error("Please log in to leave a review.");
      await client.auth.toLogin();
      return;
    }
    if (!newComment.trim()) {
      toast.error("Please write a review comment.");
      return;
    }
    setSubmittingReview(true);
    try {
      await client.entities.product_reviews.create({
        data: {
          product_id: product.id,
          rating: newRating,
          title: newTitle.trim(),
          comment: newComment.trim(),
          is_approved: true,
        },
      });
      toast.success("Thanks for your review!");
      setNewTitle("");
      setNewComment("");
      setNewRating(5);
      // Refresh list
      const revRes = await client.entities.product_reviews.queryAll({
        query: { product_id: product.id, is_approved: true },
        sort: "-id",
        limit: 50,
      });
      setReviews((revRes?.data?.items || []) as Review[]);
    } catch (e) {
      toast.error("Failed to submit review. Please try again.");
    } finally {
      setSubmittingReview(false);
    }
  };

  if (loading) {
    return (
      <SiteLayout>
        <div className="py-32 flex justify-center">
          <LoadingSpinner />
        </div>
      </SiteLayout>
    );
  }

  if (!product) {
    return (
      <SiteLayout>
        <div className="max-w-3xl mx-auto px-4 py-24 text-center">
          <h1 className="text-2xl font-bold text-slate-900">Product not found</h1>
          <p className="text-slate-500 mt-2">
            The product you are looking for does not exist or is no longer available.
          </p>
          <Link
            to="/shop"
            className="inline-flex items-center gap-2 mt-6 text-[#0b6e3e] font-semibold"
          >
            <ArrowLeft className="w-4 h-4" /> Back to shop
          </Link>
        </div>
      </SiteLayout>
    );
  }

  return (
    <SiteLayout>
      <div className="max-w-6xl mx-auto px-4 md:px-6 py-8 md:py-12">
        <Link
          to="/shop"
          className="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-[#0b6e3e] mb-6"
        >
          <ArrowLeft className="w-4 h-4" /> Back to shop
        </Link>

        <div className="grid md:grid-cols-2 gap-8 md:gap-12">
          {/* Gallery */}
          <div>
            <div className="aspect-square bg-slate-50 rounded-2xl overflow-hidden border border-slate-200">
              {activeImage ? (
                <img
                  ref={heroImageRef}
                  src={activeImage}
                  alt={product.name}
                  className="w-full h-full object-cover"
                />
              ) : (
                <div className="w-full h-full flex items-center justify-center text-slate-300">
                  <ShoppingBag className="w-16 h-16" />
                </div>
              )}
            </div>
            {galleryImages.length > 1 && (
              <div className="mt-3 grid grid-cols-4 gap-2">
                {galleryImages.map((src) => (
                  <button
                    key={src}
                    onClick={() => setActiveImage(src)}
                    className={`aspect-square rounded-lg overflow-hidden border-2 ${
                      activeImage === src ? "border-[#0b6e3e]" : "border-slate-200"
                    }`}
                  >
                    <img src={src} alt="" className="w-full h-full object-cover" />
                  </button>
                ))}
              </div>
            )}
          </div>

          {/* Details */}
          <div>
            <div className="inline-flex items-center gap-2 px-2.5 py-1 bg-[#0b6e3e]/10 text-[#0b6e3e] rounded-full text-xs font-bold uppercase tracking-wider">
              {product.product_type === "digital"
                ? "Digital Download"
                : product.product_type === "hosting"
                ? "Hosting Add-on"
                : "Physical Item"}
            </div>
            <h1 className="text-2xl md:text-4xl font-extrabold text-slate-900 mt-2">
              {product.name}
            </h1>

            <div className="flex items-center gap-3 mt-2">
              <StarRating value={avgRating} size={18} />
              <span className="text-xs text-slate-500">
                {reviews.length} review{reviews.length === 1 ? "" : "s"}
              </span>
              {product.sku && (
                <span className="text-xs text-slate-400">SKU: {product.sku}</span>
              )}
            </div>

            <div className="flex items-baseline gap-3 mt-4">
              <span className="text-3xl md:text-4xl font-extrabold text-[#0b6e3e]">
                <Price amount={product.price} />
              </span>
              {hasDiscount && (
                <span className="text-lg text-slate-400 line-through">
                  <Price amount={product.compare_at_price!} />
                </span>
              )}
              <span className="text-xs uppercase tracking-wider text-slate-400">
                {PRIMARY_CURRENCY}
              </span>
            </div>

            {product.description && (
              <p className="text-slate-600 mt-4 leading-relaxed">{product.description}</p>
            )}

            {/* Hardware metadata: brand / model / spec table */}
            {hardwareMeta && (
              <div className="mt-5 rounded-2xl border border-slate-200 bg-slate-50/60 p-4 sm:p-5">
                {(hardwareMeta.brand || hardwareMeta.model) && (
                  <div className="flex flex-wrap items-center gap-2 mb-3">
                    {hardwareMeta.brand && (
                      <span className="inline-flex items-center gap-1 rounded-full bg-white border border-slate-200 px-3 py-1 text-xs font-semibold text-slate-700">
                        Brand: <span className="text-[#0b6e3e]">{hardwareMeta.brand}</span>
                      </span>
                    )}
                    {hardwareMeta.model && (
                      <span className="inline-flex items-center gap-1 rounded-full bg-white border border-slate-200 px-3 py-1 text-xs font-semibold text-slate-700">
                        Model: <span className="text-slate-900">{hardwareMeta.model}</span>
                      </span>
                    )}
                  </div>
                )}
                {Array.isArray(hardwareMeta.specs) && hardwareMeta.specs.length > 0 && (
                  <div className="overflow-hidden rounded-xl border border-slate-200 bg-white">
                    <table className="w-full text-sm">
                      <tbody>
                        {hardwareMeta.specs.map((s, idx) => (
                          <tr
                            key={`${s.label}-${idx}`}
                            className={idx % 2 === 0 ? "bg-white" : "bg-slate-50/60"}
                          >
                            <th className="text-left font-semibold text-slate-700 px-4 py-2.5 w-2/5 align-top">
                              {s.label}
                            </th>
                            <td className="text-slate-800 px-4 py-2.5 align-top">{s.value}</td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  </div>
                )}
                <div className="mt-3 flex flex-col sm:flex-row gap-2">
                  <button
                    type="button"
                    onClick={() => setQuoteOpen(true)}
                    className="inline-flex items-center justify-center px-4 py-2.5 rounded-xl bg-[#f5c400] text-slate-900 font-bold hover:bg-yellow-400 transition"
                  >
                    Request a quote for this hardware
                  </button>
                  <p className="text-xs text-slate-500 sm:self-center">
                    Bulk pricing, custom configurations, and corporate invoicing available.
                  </p>
                </div>
              </div>
            )}

            {/* Variants */}
            {variantConfig.length > 0 && (
              <div className="mt-5 space-y-3">
                {variantConfig.map((v) => (
                  <div key={v.name}>
                    <div className="text-sm font-semibold text-slate-700 mb-1.5">
                      {v.name}
                    </div>
                    <div className="flex flex-wrap gap-2">
                      {v.options.map((opt) => (
                        <button
                          key={opt}
                          onClick={() =>
                            setSelectedVariants((s) => ({ ...s, [v.name]: opt }))
                          }
                          className={`px-3.5 py-1.5 text-sm rounded-lg border font-semibold transition ${
                            selectedVariants[v.name] === opt
                              ? "bg-[#0b6e3e] text-white border-[#0b6e3e]"
                              : "bg-white text-slate-700 border-slate-200 hover:border-[#0b6e3e]"
                          }`}
                        >
                          {opt}
                        </button>
                      ))}
                    </div>
                  </div>
                ))}
              </div>
            )}

            {/* Quantity + CTA */}
            <div className="mt-6 flex flex-col sm:flex-row items-stretch sm:items-center gap-3">
              <div className="inline-flex items-center border border-slate-200 rounded-xl">
                <button
                  onClick={() => setQuantity((q) => Math.max(1, q - 1))}
                  className="p-3 hover:bg-slate-50"
                  aria-label="Decrease quantity"
                >
                  <Minus className="w-4 h-4" />
                </button>
                <span className="px-5 text-base font-bold">{quantity}</span>
                <button
                  onClick={() => setQuantity((q) => (stock === -1 ? q + 1 : Math.min(stock, q + 1)))}
                  className="p-3 hover:bg-slate-50"
                  aria-label="Increase quantity"
                  disabled={stock !== -1 && quantity >= stock}
                >
                  <Plus className="w-4 h-4" />
                </button>
              </div>
              <button
                onClick={() => handleAddToCart()}
                disabled={!inStock}
                className="flex-1 py-3 px-5 rounded-xl bg-slate-900 text-white font-semibold hover:bg-slate-800 disabled:opacity-50 inline-flex items-center justify-center gap-2"
              >
                <ShoppingBag className="w-4 h-4" />
                {inStock ? "Add to cart" : "Out of stock"}
              </button>
              <button
                onClick={handleBuyNow}
                disabled={!inStock}
                className="flex-1 py-3 px-5 rounded-xl bg-[#0b6e3e] text-white font-semibold hover:bg-[#0a8048] disabled:opacity-50"
              >
                Buy now
              </button>
            </div>

            {/* Trust row */}
            <div className="mt-6 grid grid-cols-3 gap-2 text-[11px] text-slate-600">
              <div className="bg-slate-50 rounded-lg p-2.5 text-center">
                <ShieldCheck className="w-4 h-4 mx-auto text-[#0b6e3e] mb-1" />
                Secure checkout
              </div>
              <div className="bg-slate-50 rounded-lg p-2.5 text-center">
                {product.product_type === "digital" ? (
                  <>
                    <Download className="w-4 h-4 mx-auto text-[#0b6e3e] mb-1" />
                    Instant delivery
                  </>
                ) : (
                  <>
                    <Truck className="w-4 h-4 mx-auto text-[#0b6e3e] mb-1" />
                    Ships worldwide
                  </>
                )}
              </div>
              <div className="bg-slate-50 rounded-lg p-2.5 text-center">
                <Check className="w-4 h-4 mx-auto text-[#0b6e3e] mb-1" />
                30-day support
              </div>
            </div>
          </div>
        </div>

        {/* Long description */}
        {product.long_description && (
          <section className="mt-12 bg-white border border-slate-200 rounded-2xl p-6 md:p-8">
            <h2 className="text-xl font-bold text-slate-900 mb-3">Product details</h2>
            <div className="text-slate-700 leading-relaxed whitespace-pre-wrap">
              {product.long_description}
            </div>
          </section>
        )}

        {/* Reviews */}
        <section className="mt-12 grid md:grid-cols-3 gap-8">
          <div className="md:col-span-2">
            <h2 className="text-xl font-bold text-slate-900 mb-4">
              Customer reviews ({reviews.length})
            </h2>
            {reviews.length === 0 ? (
              <p className="text-slate-500 text-sm">
                Be the first to review this product.
              </p>
            ) : (
              <div className="space-y-4">
                {reviews.map((r) => (
                  <div
                    key={r.id}
                    className="border border-slate-200 rounded-xl p-4 bg-white"
                  >
                    <div className="flex items-center gap-2">
                      <StarRating value={r.rating || 0} />
                      {r.title && (
                        <span className="font-semibold text-slate-900">{r.title}</span>
                      )}
                    </div>
                    {r.comment && (
                      <p className="text-slate-700 text-sm mt-2">{r.comment}</p>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>

          <aside className="md:col-span-1">
            <div className="border border-slate-200 rounded-xl p-5 bg-white sticky top-6">
              <h3 className="font-bold text-slate-900">Write a review</h3>
              <p className="text-xs text-slate-500 mt-1">
                Share your thoughts with other shoppers.
              </p>
              <div className="mt-3">
                <StarRating
                  value={newRating}
                  onChange={setNewRating}
                  readOnly={false}
                  size={22}
                />
              </div>
              <input
                value={newTitle}
                onChange={(e) => setNewTitle(e.target.value)}
                placeholder="Title (optional)"
                className="mt-3 w-full border border-slate-200 rounded-lg px-3 py-2 text-sm"
              />
              <textarea
                value={newComment}
                onChange={(e) => setNewComment(e.target.value)}
                placeholder="What did you like or dislike?"
                rows={4}
                className="mt-3 w-full border border-slate-200 rounded-lg px-3 py-2 text-sm"
              />
              <button
                onClick={handleSubmitReview}
                disabled={submittingReview}
                className="mt-3 w-full py-2.5 rounded-lg bg-[#0b6e3e] text-white font-semibold hover:bg-[#0a8048] disabled:opacity-60"
              >
                {submittingReview ? "Submitting…" : "Submit review"}
              </button>
            </div>
          </aside>
        </section>
      </div>
      <GetPriceModal open={quoteOpen} onClose={() => setQuoteOpen(false)} />
    </SiteLayout>
  );
}