"use client";

import { useEffect, useState, useTransition } from "react";
import Link from "next/link";
import { Bookmark, BookmarkCheck, ExternalLink, Loader2 } from "lucide-react";
import { toast } from "sonner";
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetDescription,
  SheetFooter,
  SheetClose,
} from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { ScoreRing } from "@/components/score-ring";
import { ProductImage } from "@/components/dashboard/product-image";
import { DemoBadge } from "@/components/dashboard/demo-badge";
import { ConfidenceBadge } from "@/components/dashboard/confidence-badge";
import { MetricChart } from "@/components/dashboard/metric-chart";
import { UpgradePrompt } from "@/components/dashboard/upgrade-prompt";
import { useLanguage } from "@/lib/i18n/context";
import { getProductQuickViewAction, saveProductAction, unsaveProductAction } from "@/actions/product-actions";
import type { ProductQuickViewResult } from "@/actions/product-actions";
import type { ScoreImpact } from "@/lib/scoring/types";
import type { Dictionary } from "@/lib/i18n/translations";

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);
}

function explanationLabel(t: Dictionary, key: string): string {
  return (t.scoreExplanation as unknown as Record<string, string>)[key] ?? key;
}

/**
 * Right-side drawer for the Market Explorer table's "quick view" action —
 * loads full product detail (score breakdown, history, gallery) on demand
 * instead of navigating away from the results table. Shares the exact same
 * PRODUCT_ANALYSIS usage-gate result as the full detail page (both call
 * resolveProductAnalysisAccess under the hood via getProductQuickViewAction).
 */
export function ProductQuickView({
  productId,
  open,
  onOpenChange,
}: {
  productId: string | null;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const { t, locale } = useLanguage();
  const d = t.productCatalog.detail;
  const qv = t.productCatalog.quickView;
  // Keyed by productId so a state update is only ever applied from inside
  // the async .then() below — never synchronously in the effect body — and
  // a stale in-flight response for a since-closed/changed product is
  // dropped by the `loadedFor !== productId` check below rather than by
  // canceling a setState call the lint rule already disallows here.
  const [{ loadedFor, result }, setResult] = useState<{ loadedFor: string | null; result: ProductQuickViewResult | null }>({
    loadedFor: null,
    result: null,
  });
  const [saved, setSaved] = useState(false);
  const [isPending, startTransition] = useTransition();

  useEffect(() => {
    if (!open || !productId) return;
    let cancelled = false;
    getProductQuickViewAction(productId).then((response) => {
      if (cancelled) return;
      setResult({ loadedFor: productId, result: response });
      setSaved(response.initiallySaved);
    });
    return () => {
      cancelled = true;
    };
  }, [open, productId]);

  const loading = Boolean(open && productId && loadedFor !== productId);
  const data = productId && loadedFor === productId ? result : null;

  function toggleSave() {
    if (!productId) return;
    const next = !saved;
    setSaved(next);
    startTransition(async () => {
      const result = next
        ? await saveProductAction(productId, locale)
        : await unsaveProductAction(productId, locale);
      if (!result.success) {
        setSaved(!next);
        toast.error(result.error);
      }
    });
  }

  const product = data?.product ?? null;
  const breakdown = product?.score?.scoreBreakdown as
    | { strengths?: ScoreImpact[]; risks?: ScoreImpact[] }
    | undefined;

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent side="right" className="w-full overflow-y-auto sm:max-w-xl">
        {loading || !data ? (
          <div className="flex flex-1 items-center justify-center">
            <Loader2 className="size-6 animate-spin text-muted-foreground" />
          </div>
        ) : !product ? (
          <div className="flex flex-1 items-center justify-center p-6 text-center text-sm text-muted-foreground">
            {d.notFound}
          </div>
        ) : (
          <div className="flex flex-col gap-6 p-6">
            <SheetHeader className="p-0">
              <SheetTitle className="text-balance">{product.canonicalName}</SheetTitle>
              <SheetDescription className="flex flex-wrap items-center gap-x-3 gap-y-1">
                <span>{product.storeName ?? t.productCatalog.table.unknownStore}</span>
                <span>·</span>
                <span>{product.category}</span>
                {product.isDemo && <DemoBadge />}
              </SheetDescription>
            </SheetHeader>

            <div className="flex gap-3">
              <ProductImage
                src={product.imageUrl}
                alt={product.canonicalName}
                className="size-28"
                sizes="112px"
              />
              {product.galleryImageUrls.length > 1 && (
                <div className="flex flex-1 flex-wrap gap-2 self-start">
                  {product.galleryImageUrls.slice(1, 5).map((url) => (
                    <ProductImage key={url} src={url} alt={product.canonicalName} className="size-14" sizes="56px" />
                  ))}
                </div>
              )}
            </div>

            <div className="flex items-center justify-between">
              {product.currentPrice !== null ? (
                <p className="text-xl font-semibold text-foreground">
                  {formatPrice(product.currentPrice, product.currency, locale)}
                </p>
              ) : (
                <span />
              )}
              {product.score && <ConfidenceBadge score={product.score.confidenceScore} />}
            </div>

            <p className="text-xs text-muted-foreground">
              {product.imageSyncedAt
                ? qv.lastSynced.replace(
                    "{date}",
                    new Intl.DateTimeFormat(locale === "es" ? "es-US" : "en-US", { dateStyle: "medium" }).format(
                      product.imageSyncedAt,
                    ),
                  )
                : qv.neverSynced}
            </p>

            <Separator />

            {!data.canViewAdvanced ? (
              <UpgradePrompt requiredPlan={data.nextPlan} currentPlan={data.currentPlan} featureLabel={d.analysisLimitReached} />
            ) : product.score ? (
              <>
                <div className="flex flex-wrap items-center gap-6">
                  <ScoreRing value={product.score.opportunityScore} size={72} label="Opportunity" tone="cyan" />
                  <div className="grid grid-cols-2 gap-x-6 gap-y-2 text-sm">
                    <div>
                      <p className="text-xs text-muted-foreground">{t.productCatalog.filters.growthVelocity}</p>
                      <p className="font-medium text-foreground">{product.score.growthVelocityScore ?? "—"}</p>
                    </div>
                    <div>
                      <p className="text-xs text-muted-foreground">{t.productCatalog.filters.demandAcceleration}</p>
                      <p className="font-medium text-foreground">{product.score.demandAccelerationScore ?? "—"}</p>
                    </div>
                    <div>
                      <p className="text-xs text-muted-foreground">{t.productCatalog.table.risk}</p>
                      <p className="font-medium text-foreground">{product.score.riskScore ?? "—"}</p>
                    </div>
                    <div>
                      <p className="text-xs text-muted-foreground">{t.productCatalog.filters.competitionTrend}</p>
                      <p className="font-medium text-foreground">{product.score.competitionTrendScore ?? "—"}</p>
                    </div>
                  </div>
                </div>

                <Separator />

                <div className="grid gap-4 sm:grid-cols-2">
                  <div>
                    <h3 className="mb-2 text-xs font-semibold tracking-wide text-success uppercase">{d.strengths}</h3>
                    {(breakdown?.strengths ?? []).length === 0 ? (
                      <p className="text-sm text-muted-foreground">{d.noStrengths}</p>
                    ) : (
                      <ul className="flex flex-col gap-1.5">
                        {breakdown!.strengths!.map((s) => (
                          <li key={s.key} className="text-sm text-foreground">
                            {explanationLabel(t, s.key)}
                          </li>
                        ))}
                      </ul>
                    )}
                  </div>
                  <div>
                    <h3 className="mb-2 text-xs font-semibold tracking-wide text-destructive uppercase">{d.risks}</h3>
                    {(breakdown?.risks ?? []).length === 0 ? (
                      <p className="text-sm text-muted-foreground">{d.noRisks}</p>
                    ) : (
                      <ul className="flex flex-col gap-1.5">
                        {breakdown!.risks!.map((r) => (
                          <li key={r.key} className="text-sm text-foreground">
                            {explanationLabel(t, r.key)}
                          </li>
                        ))}
                      </ul>
                    )}
                  </div>
                </div>

                {product.scoreHistory && product.scoreHistory.length >= 2 && (
                  <>
                    <Separator />
                    <div>
                      <h3 className="mb-2 text-xs font-semibold tracking-wide text-muted-foreground uppercase">
                        {d.opportunityTrend}
                      </h3>
                      <MetricChart
                        title={d.opportunityTrend}
                        points={product.scoreHistory.map((h) => ({ date: h.calculatedAt, value: h.opportunityScore }))}
                        color="var(--brand-cyan)"
                        emptyLabel={d.noChartData}
                      />
                    </div>
                  </>
                )}
              </>
            ) : (
              <p className="text-sm text-muted-foreground">{d.noChartData}</p>
            )}

            <Separator />

            <SheetFooter className="flex-row justify-end gap-2 p-0">
              <Button variant="outline" size="sm" onClick={toggleSave} disabled={isPending}>
                {saved ? <BookmarkCheck className="size-4 text-primary" /> : <Bookmark className="size-4" />}
                {saved ? d.unsaveProduct : d.saveProduct}
              </Button>
              <Button asChild size="sm">
                <Link href={`/dashboard/products/${product.id}`}>
                  <ExternalLink className="size-3.5" />
                  {qv.fullAnalysis}
                </Link>
              </Button>
              <SheetClose asChild>
                <Button variant="ghost" size="sm">
                  {qv.close}
                </Button>
              </SheetClose>
            </SheetFooter>
          </div>
        )}
      </SheetContent>
    </Sheet>
  );
}
