import Link from "next/link";

import { AddToCartButton } from "@/components/cart/AddToCartButton";
import { ProductImage } from "@/components/products/ProductImage";
import { RatingStars } from "@/components/ui/RatingStars";
import { formatPrice, toMatchPercent, truncate } from "@/lib/format";
import type { Product } from "@/types/product";
import type { ProductResult } from "@/types/result";

/**
 * Product card.
 *
 * Rendered on the server wherever possible; only the add-to-cart button needs to
 * be interactive. When the card is a search result it also shows how well it
 * matched, which is the whole point of the page.
 */
export function ProductCard({ product }: { product: Product }) {
  return (
    <article className="group flex h-full flex-col overflow-hidden rounded-2xl border border-slate-200 bg-white transition-shadow duration-200 hover:shadow-lg focus-within:ring-2 focus-within:ring-indigo-600">
      <Link
        href={`/products/${product.id}`}
        className="focus-visible:ring-2 focus-visible:ring-indigo-600 focus-visible:outline-none"
      >
        <ProductImage product={product} />
      </Link>

      <div className="flex flex-1 flex-col gap-2 p-4">
        <div className="flex items-center gap-2 text-xs">
          <span className="rounded-full bg-indigo-50 px-2 py-0.5 font-semibold text-indigo-700">
            {product.category}
          </span>
          <span className="truncate text-slate-500">{product.brand}</span>
        </div>

        <h3 className="text-sm leading-snug font-semibold text-slate-900">
          <Link
            href={`/products/${product.id}`}
            className="transition-colors hover:text-indigo-700 focus-visible:ring-2 focus-visible:ring-indigo-600 focus-visible:outline-none"
          >
            {truncate(product.name, 52)}
          </Link>
        </h3>

        <p className="line-clamp-2 text-sm text-slate-600">
          {truncate(product.description, 96)}
        </p>

        <RatingStars rating={product.rating} />

        <div className="mt-auto flex items-end justify-between gap-2 pt-2">
          <span className="text-lg font-bold text-slate-900">{formatPrice(product.price)}</span>
          <span className="text-xs text-slate-500">
            {product.stock > 0 ? `${product.stock} in stock` : "Unavailable"}
          </span>
        </div>

        <div className="flex gap-2 pt-1">
          <Link
            href={`/products/${product.id}`}
            className="flex-1 rounded-xl border border-slate-300 px-3 py-2.5 text-center text-sm font-semibold text-slate-700 transition-colors hover:border-slate-400 hover:bg-slate-50 focus-visible:ring-2 focus-visible:ring-indigo-600 focus-visible:ring-offset-2 focus-visible:outline-none"
          >
            View details
          </Link>
          <AddToCartButton product={product} className="flex-1" />
        </div>
      </div>
    </article>
  );
}

/** Search-result variant: adds the relevance read-out above the card body. */
export function SearchResultCard({ result }: { result: ProductResult }) {
  const percent = toMatchPercent(result.similarity);

  return (
    <article className="group relative flex h-full flex-col overflow-hidden rounded-2xl border border-slate-200 bg-white transition-shadow duration-200 hover:shadow-lg focus-within:ring-2 focus-within:ring-indigo-600">
      <Link
        href={`/products/${result.id}`}
        className="focus-visible:ring-2 focus-visible:ring-indigo-600 focus-visible:outline-none"
      >
        <ProductImage product={result} />
      </Link>

      <div className="flex flex-1 flex-col gap-2 p-4">
        <div className="flex items-center justify-between gap-2">
          <span className="rounded-full bg-indigo-50 px-2 py-0.5 text-xs font-semibold text-indigo-700">
            {result.category}
          </span>
          <span
            className="text-xs font-semibold text-emerald-700"
            title={`Cosine similarity ${result.similarity.toFixed(3)}`}
          >
            {percent}% match
          </span>
        </div>

        <h3 className="text-sm leading-snug font-semibold text-slate-900">
          <Link
            href={`/products/${result.id}`}
            className="transition-colors hover:text-indigo-700 focus-visible:ring-2 focus-visible:ring-indigo-600 focus-visible:outline-none"
          >
            {truncate(result.name, 52)}
          </Link>
        </h3>

        <p className="line-clamp-2 text-sm text-slate-600">{truncate(result.description, 96)}</p>

        <div className="flex items-center justify-between gap-2">
          <RatingStars rating={result.rating} />
          <span className="truncate text-xs text-slate-500">{result.brand}</span>
        </div>

        <MatchBar similarity={result.similarity} keywordScore={result.keywordScore} />

        <div className="mt-auto flex items-end justify-between gap-2 pt-2">
          <span className="text-lg font-bold text-slate-900">{formatPrice(result.price)}</span>
          <span className="text-xs text-slate-500">
            {result.stock > 0 ? `${result.stock} in stock` : "Unavailable"}
          </span>
        </div>

        <div className="flex gap-2 pt-1">
          <Link
            href={`/products/${result.id}`}
            className="flex-1 rounded-xl border border-slate-300 px-3 py-2.5 text-center text-sm font-semibold text-slate-700 transition-colors hover:border-slate-400 hover:bg-slate-50 focus-visible:ring-2 focus-visible:ring-indigo-600 focus-visible:ring-offset-2 focus-visible:outline-none"
          >
            View details
          </Link>
          <AddToCartButton product={result} className="flex-1" />
        </div>
      </div>
    </article>
  );
}

/** Visualises the two ranking components so the hybrid score is legible. */
function MatchBar({ similarity, keywordScore }: { similarity: number; keywordScore: number }) {
  const semantic = Math.round(Math.max(0, Math.min(1, similarity)) * 100);
  const keyword = Math.round(Math.max(0, Math.min(1, keywordScore)) * 100);

  return (
    <div className="space-y-1" title={`Semantic ${semantic}% · keyword ${keyword}%`}>
      <div className="h-1.5 overflow-hidden rounded-full bg-slate-100">
        <div
          className="h-full rounded-full bg-indigo-500 transition-[width] duration-300"
          style={{ width: `${semantic}%` }}
        />
      </div>
      <p className="text-[11px] text-slate-500">
        Semantic {semantic}% · Keyword {keyword}%
      </p>
    </div>
  );
}
