"use client";

import { Button, Spinner, toast } from "@heroui/react";
import Image from "next/image";
import Link from "next/link";
import { useId, useState, useCallback } from "react";
import { useConvexAuth, useMutation } from "convex/react";
import { api } from "../../../../../convex/_generated/api";
import type { Id } from "../../../../../convex/_generated/dataModel";
import type { ProductCardProps } from "./ProductCard";

function HeartIcon({ className }: { className?: string }) {
  return (
    <svg
      className={className}
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="2"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden
    >
      <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
    </svg>
  );
}

/** Renders a single star (filled or half) for list tile. */
function StarIcon({
  filled,
  half,
  gradientId,
}: {
  filled?: boolean;
  half?: boolean;
  gradientId?: string;
}) {
  if (half && gradientId) {
    return (
      <svg
        className="size-3.5 text-[var(--warm)]"
        viewBox="0 0 24 24"
        fill="currentColor"
        aria-hidden
      >
        <defs>
          <linearGradient id={gradientId} x1="0" x2="1" y1="0" y2="0">
            <stop offset="50%" stopColor="currentColor" />
            <stop offset="50%" stopColor="transparent" />
          </linearGradient>
        </defs>
        <path
          fill={`url(#${gradientId})`}
          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>
    );
  }
  return (
    <svg
      className="size-3.5 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 StarRow({ rating }: { rating: number }) {
  const id = useId();
  const full = Math.floor(rating);
  const hasHalf = rating % 1 >= 0.25 && rating % 1 < 0.75;
  const stars = [];
  for (let i = 0; i < full; i++) stars.push(<StarIcon key={i} filled />);
  if (hasHalf)
    stars.push(
      <StarIcon key="half" half gradientId={id.replace(/:/g, "")} />
    );
  return <div className="flex items-center gap-0.5">{stars}</div>;
}

/**
 * Compact product tile for mobile list view. Same props as ProductCard.
 * Horizontal layout: image left, brand/name/rating/price right.
 */
export function ProductListTile({
  brand,
  name,
  price,
  compareAtPrice,
  imageSrc,
  imageAlt,
  url,
  rating,
  reviewCount,
  badge,
  productId,
  variantId,
  hideWishlistAction,
}: ProductCardProps) {
  const { isAuthenticated } = useConvexAuth();
  const addToWishlist = useMutation(api.wishlists.add);
  const [isSaving, setIsSaving] = useState(false);
  const ratingLabel = `Rated ${rating} out of 5${reviewCount ? ` (${reviewCount} reviews)` : ""}`;

  const handleSave = useCallback(async () => {
    if (!productId) return;
    if (!isAuthenticated) {
      toast.info("Sign in to save items to your wishlist");
      return;
    }
    setIsSaving(true);
    try {
      const result = await addToWishlist({
        productId: productId as Id<"products">,
        variantId: variantId as Id<"productVariants"> | undefined,
      });
      if (result.alreadyExisted) {
        toast.info("This item is already in your wishlist");
      } else {
        toast.success("Added to your wishlist");
      }
    } finally {
      setIsSaving(false);
    }
  }, [productId, variantId, isAuthenticated, addToWishlist]);

  return (
    <article className="flex flex-row gap-3 rounded-[var(--radius)] border border-[var(--border)] bg-[var(--surface)] p-3 shadow-[0_2px_8px_rgba(56,169,159,0.08)] transition-[box-shadow] duration-[var(--transition-base)]">
      <Link
        href={url}
        className="relative block h-20 w-20 shrink-0 overflow-hidden rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--accent)] focus:ring-offset-2 focus:ring-offset-[var(--surface)]"
      >
        <Image
          src={imageSrc}
          alt={imageAlt}
          fill
          sizes="80px"
          className="object-contain mix-blend-multiply"
          loading="lazy"
        />
        {badge && (
          <span
            className={`absolute right-0.5 top-0.5 rounded px-1.5 py-0.5 text-[10px] font-bold uppercase ${
              badge === "new"
                ? "bg-[#fde8c8] text-[#b36a10]"
                : "bg-[#fce0da] text-[var(--coral)]"
            }`}
          >
            {badge === "new" ? "New" : "Sale"}
          </span>
        )}
      </Link>
      <div className="flex min-w-0 flex-1 flex-col">
        <div
          className="flex items-center gap-1"
          role="img"
          aria-label={ratingLabel}
        >
          <StarRow rating={rating} />
          {reviewCount > 0 && (
            <span className="text-[10px] font-medium text-[var(--muted)]">
              ({reviewCount})
            </span>
          )}
        </div>
        <h3 className="mt-0.5 line-clamp-2 text-sm font-medium leading-snug text-[var(--foreground)]">
          <Link
            href={url}
            className="focus:outline-none focus:ring-2 focus:ring-[var(--accent)] focus:ring-offset-2 focus:ring-offset-[var(--surface)] rounded"
          >
            <span className="font-[family-name:var(--font-fraunces)] font-bold text-[var(--foreground)]">
              {brand}
            </span>{" "}
            {name}
          </Link>
        </h3>
        <div className="mt-auto flex items-center justify-between gap-2 pt-2">
          <div className="flex items-baseline gap-2 min-w-0">
            {compareAtPrice && (
              <s
                className="text-xs text-[var(--muted)] shrink-0"
                aria-label="Original price"
              >
                {compareAtPrice}
              </s>
            )}
            <p className="text-base font-semibold text-[var(--brand-dark)] truncate">
              {price}
            </p>
          </div>
          {!hideWishlistAction && (
            <Button
              variant="ghost"
              isIconOnly
              size="sm"
              aria-label={`Save ${name} to wishlist`}
              aria-busy={isSaving}
              className="shrink-0 text-[var(--brand-dark)] hover:opacity-80"
              isPending={isSaving}
              onPress={handleSave}
            >
              {isSaving ? (
                <Spinner size="sm" color="current" />
              ) : (
                <HeartIcon className="size-5" />
              )}
            </Button>
          )}
        </div>
      </div>
    </article>
  );
}
