"use client";

import { useState, useTransition } from "react";
import Link from "next/link";
import { Bookmark, BookmarkCheck } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { ScoreRing } from "@/components/score-ring";
import { DemoBadge } from "@/components/dashboard/demo-badge";
import { ConfidenceBadge } from "@/components/dashboard/confidence-badge";
import { useLanguage } from "@/lib/i18n/context";
import { saveProductAction, unsaveProductAction } from "@/actions/product-actions";
import type { ProductCardView } from "@/lib/product-data/view-models";

function formatPrice(price: number, currency: string, locale: "en" | "es"): string {
  return new Intl.NumberFormat(locale === "es" ? "es-US" : "en-US", {
    style: "currency",
    currency,
    maximumFractionDigits: 2,
  }).format(price);
}

/**
 * One product tile in the discovery grid. Save/unsave is optimistic (flips
 * immediately, reverts on a failed server response) — the server action is
 * still the real gate (plan limit, product still active), this is purely
 * a snappier UI while that round trip is in flight.
 */
export function ProductCard({
  product,
  initiallySaved,
}: {
  product: ProductCardView;
  initiallySaved: boolean;
}) {
  const { t, locale } = useLanguage();
  const c = t.productCatalog;
  const [saved, setSaved] = useState(initiallySaved);
  const [isPending, startTransition] = useTransition();

  function toggleSave() {
    const next = !saved;
    setSaved(next);
    startTransition(async () => {
      const result = next
        ? await saveProductAction(product.id, locale)
        : await unsaveProductAction(product.id, locale);
      if (!result.success) {
        setSaved(!next);
        toast.error(result.error);
      }
    });
  }

  return (
    <div className="flex flex-col gap-3 rounded-2xl border border-border bg-card/50 p-4 transition-colors hover:border-brand-cyan/40">
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0 flex-1">
          <Link
            href={`/dashboard/products/${product.id}`}
            className="truncate text-sm font-semibold text-foreground hover:text-primary"
          >
            {product.canonicalName}
          </Link>
          <p className="mt-0.5 truncate text-xs text-muted-foreground">
            {product.brand ? `${product.brand} · ` : ""}
            {product.category}
          </p>
        </div>
        {product.score ? (
          <ScoreRing value={product.score.opportunityScore} size={48} strokeWidth={5} />
        ) : null}
      </div>

      <div className="flex flex-wrap items-center gap-1.5">
        {product.isDemo && <DemoBadge />}
        {product.score && <ConfidenceBadge score={product.score.confidenceScore} />}
      </div>

      {product.currentPrice !== null && (
        <p className="text-sm font-medium text-foreground">
          {formatPrice(product.currentPrice, product.currency, locale)}
        </p>
      )}

      <div className="mt-1 flex items-center gap-2">
        <Button asChild size="sm" className="flex-1">
          <Link href={`/dashboard/products/${product.id}`}>{c.card.viewDetails}</Link>
        </Button>
        <Button
          variant="outline"
          size="sm"
          onClick={toggleSave}
          disabled={isPending}
          aria-pressed={saved}
          aria-label={saved ? c.card.saved : c.card.save}
        >
          {saved ? <BookmarkCheck className="size-4 text-primary" /> : <Bookmark className="size-4" />}
        </Button>
      </div>
    </div>
  );
}
