"use client";

import { useMemo, useState, useTransition } from "react";
import Link from "next/link";
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";
import { ArrowLeft, Heart, ExternalLink, AlertTriangle } from "lucide-react";
import { toast } from "sonner";
import { Alert, AlertTitle } from "@/components/ui/alert";
import { Separator } from "@/components/ui/separator";
import { Card } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { ChartContainer, ChartTooltip, ChartTooltipContent, type ChartConfig } from "@/components/ui/chart";
import { ScoreRing } from "@/components/score-ring";
import { OpportunityGauge } from "@/components/dashboard/products/opportunity-gauge";
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 { cn } from "@/lib/utils";
import { saveProductAction, unsaveProductAction } from "@/actions/product-actions";
import { scoreLevel, opportunityLevel, signalLevel } from "@/lib/scoring/config";
import { changeOverDays, computeScoreChange } from "@/lib/product-data/product-detail-metrics";
import type { ProductDetailView, SnapshotPointView } from "@/lib/product-data/view-models";
import type { ScoreImpact, ScoreWarning } from "@/lib/scoring/types";
import type { Dictionary } from "@/lib/i18n/translations";
import type { PlanCode } from "@prisma/client";

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 formatDate(date: Date, locale: "en" | "es"): string {
  return new Intl.DateTimeFormat(locale === "es" ? "es-US" : "en-US", {
    year: "numeric",
    month: "short",
    day: "numeric",
  }).format(date);
}

function formatShortDate(date: Date, locale: "en" | "es"): string {
  return new Intl.DateTimeFormat(locale === "es" ? "es-US" : "en-US", { month: "short", day: "numeric" }).format(date);
}

function formatPercent(value: number, locale: "en" | "es"): string {
  return new Intl.NumberFormat(locale === "es" ? "es-US" : "en-US", {
    style: "percent",
    maximumFractionDigits: 1,
    signDisplay: "exceptZero",
  }).format(value);
}

/** Every scoreExplanation/warning key is looked up dynamically — fall back
 * to the raw key (a visible signal something's missing from the
 * dictionary) rather than silently dropping the entry. */
function explanationLabel(t: Dictionary, key: string): string {
  return (t.scoreExplanation as unknown as Record<string, string>)[key] ?? key;
}

const WARNING_SEVERITY_CLASSES: Record<ScoreWarning["severity"], string> = {
  low: "border-border bg-secondary/50 text-muted-foreground",
  medium: "border-warning/30 bg-warning/15 text-warning",
  high: "border-destructive/30 bg-destructive/15 text-destructive",
};

const LEVEL_TONE: Record<"low" | "medium" | "high", string> = {
  low: "text-destructive",
  medium: "text-warning",
  high: "text-success",
};

const OPPORTUNITY_LABEL_KEY = {
  limited: "opportunityLimited",
  fair: "opportunityFair",
  good: "opportunityGood",
  excellent: "opportunityExcellent",
} as const;

/** Tiny 7-day decorative sparkline for the summary card — deliberately kept
 * as a hand-rolled SVG rather than recharts; the big Performance chart below
 * is the page's real chart and uses recharts + ChartContainer like Resumen. */
function buildAreaChart(
  values: number[],
  { width, height, padX, padTop, padBottom }: { width: number; height: number; padX: number; padTop: number; padBottom: number },
): { coords: { x: number; y: number }[]; line: string; area: string } | null {
  if (values.length < 2) return null;
  const min = Math.min(...values);
  const max = Math.max(...values);
  const range = max - min || 1;
  const top = padTop;
  const bottom = height - padBottom;
  const coords = values.map((v, i) => ({
    x: padX + (i / (values.length - 1)) * (width - padX * 2),
    y: bottom - ((v - min) / range) * (bottom - top),
  }));
  const line = coords.map((c) => `${c.x},${c.y}`).join(" ");
  const area = `M${coords[0].x} ${bottom} L${coords.map((c) => `${c.x} ${c.y}`).join(" L")} L${coords[coords.length - 1].x} ${bottom} Z`;
  return { coords, line, area };
}

function SignalCell({ label, score, invert }: { label: string; score: number | null; invert?: boolean }) {
  const { t } = useLanguage();
  if (score === null) {
    return (
      <div className="flex flex-col gap-1 rounded-xl bg-muted/50 px-3 py-2.5">
        <span className="text-[11px] text-muted-foreground">{label}</span>
        <b className="text-sm font-bold text-muted-foreground">—</b>
      </div>
    );
  }
  const level = signalLevel(score, invert);
  const words = { low: t.productData.levelLow, medium: t.productData.levelMedium, high: t.productData.levelHigh };
  return (
    <div className="flex flex-col gap-1 rounded-xl bg-muted/50 px-3 py-2.5">
      <span className="text-[11px] text-muted-foreground">{label}</span>
      <b className={cn("text-sm font-bold", LEVEL_TONE[level])}>{words[level]}</b>
    </div>
  );
}

const RANGE_DAYS = [7, 30, 90, 180] as const;
type RangeDays = (typeof RANGE_DAYS)[number];

export function ProductDetailContent({
  product,
  snapshots,
  initiallySaved,
  canViewAdvanced,
  currentPlan,
  nextPlan,
}: {
  product: ProductDetailView | null;
  snapshots: SnapshotPointView[];
  initiallySaved: boolean;
  canViewAdvanced: boolean;
  currentPlan: PlanCode;
  nextPlan: PlanCode;
}) {
  const { t, locale } = useLanguage();
  const d = t.productCatalog.detail;
  const [saved, setSaved] = useState(initiallySaved);
  const [isPending, startTransition] = useTransition();
  const [galleryIndex, setGalleryIndex] = useState(0);
  const [range, setRange] = useState<RangeDays>(7);

  function toggleSave() {
    if (!product) return;
    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);
      }
    });
  }

  const rangedSnapshots = useMemo(() => {
    if (snapshots.length === 0) return snapshots;
    const latest = snapshots[snapshots.length - 1];
    const cutoff = latest.capturedAt.getTime() - range * 86_400_000;
    return snapshots.filter((s) => s.capturedAt.getTime() >= cutoff);
  }, [snapshots, range]);

  if (!product) {
    return (
      <div className="flex w-full max-w-[1500px] flex-col items-center gap-4 py-16 text-center">
        <p className="text-sm text-muted-foreground">{d.notFound}</p>
        <Link href="/dashboard/products" className="flex items-center gap-1.5 text-sm font-medium text-primary hover:underline">
          <ArrowLeft className="size-4" />
          {d.backToProducts}
        </Link>
      </div>
    );
  }

  const breakdown = product.score?.scoreBreakdown as
    | { strengths?: ScoreImpact[]; risks?: ScoreImpact[] }
    | undefined;
  const strengths = breakdown?.strengths ?? [];
  const risks = breakdown?.risks ?? [];
  const warnings = (product.score?.warnings as ScoreWarning[] | undefined) ?? [];

  const gallery = Array.from(
    new Set([product.imageUrl, ...product.galleryImageUrls].filter((url): url is string => Boolean(url))),
  );
  const activeImage = gallery[galleryIndex] ?? product.imageUrl;

  const latestSnapshot = snapshots[snapshots.length - 1] ?? null;
  const sales7d = latestSnapshot?.unitsSold ?? null;
  const growth7d = changeOverDays(snapshots, 7, (s) => s.unitsSold);
  const scoreChange7d = product.scoreHistory ? computeScoreChange(product.scoreHistory, 7) : null;

  const sparkValues = snapshots
    .slice(-7)
    .map((s) => s.unitsSold)
    .filter((v): v is number => v !== null);
  const sparkChart = buildAreaChart(sparkValues, { width: 220, height: 70, padX: 4, padTop: 6, padBottom: 6 });

  const perfChartRows = rangedSnapshots.map((s) => ({ t: s.capturedAt.getTime(), revenue: s.revenue }));
  const hasPerfChart = perfChartRows.filter((r) => r.revenue !== null).length >= 2;
  const perfChartConfig = {
    revenue: { label: d.revenue, color: "var(--color-violet-500)" },
  } satisfies ChartConfig;

  const metricRows: { labelKey: string; metric: (s: SnapshotPointView) => number | null; current: number | null }[] = [
    { labelKey: "revenue", metric: (s) => s.revenue, current: latestSnapshot?.revenue ?? null },
    { labelKey: "unitsSold", metric: (s) => s.unitsSold, current: latestSnapshot?.unitsSold ?? null },
    { labelKey: "avgPrice", metric: (s) => s.price, current: latestSnapshot?.price ?? null },
    { labelKey: "views", metric: (s) => s.views, current: latestSnapshot?.views ?? null },
  ];

  return (
    <div className="flex w-full max-w-[1500px] flex-col gap-4 pb-8">
      {!product.isActive && (
        <Alert variant="destructive">
          <AlertTriangle />
          <AlertTitle>{d.inactive}</AlertTitle>
        </Alert>
      )}

      <div className="flex items-center justify-between gap-3">
        <Link href="/dashboard/products" className="flex items-center gap-1.5 text-sm font-medium text-muted-foreground hover:text-foreground">
          <ArrowLeft className="size-4" />
          {d.backToProducts}
        </Link>
        <Button
          variant={saved ? "default" : "outline"}
          onClick={toggleSave}
          disabled={isPending}
          aria-pressed={saved}
          aria-label={saved ? d.unsaveProduct : d.saveProduct}
          className="gap-1.5"
        >
          <Heart className="size-4" fill={saved ? "currentColor" : "none"} />
          {saved ? d.savedAction : d.saveAction}
        </Button>
      </div>

      <div className="grid grid-cols-1 gap-4 lg:grid-cols-[380px_minmax(0,1fr)]">
        {/* Gallery */}
        <div className="flex flex-col gap-3">
          <div className="flex aspect-square items-center justify-center overflow-hidden rounded-2xl bg-muted p-6">
            <ProductImage
              src={activeImage ?? null}
              alt={product.canonicalName}
              className="!aspect-square !w-[85%] !rounded-none !bg-transparent"
              sizes="(min-width: 1024px) 380px, 100vw"
              fit="contain"
            />
          </div>
          {gallery.length > 1 && (
            <div className="grid grid-cols-4 gap-2" role="tablist" aria-label={d.gallery}>
              {gallery.slice(0, 8).map((url, i) => (
                <button
                  key={url}
                  type="button"
                  role="tab"
                  aria-selected={i === galleryIndex}
                  onClick={() => setGalleryIndex(i)}
                  className={cn(
                    "aspect-square overflow-hidden rounded-xl bg-muted ring-2 ring-offset-2 ring-offset-background transition-all",
                    i === galleryIndex ? "ring-primary" : "ring-transparent hover:ring-border",
                  )}
                >
                  <ProductImage src={url} alt="" className="!size-full !rounded-none !bg-transparent" sizes="88px" />
                </button>
              ))}
            </div>
          )}
        </div>

        {/* Details column */}
        <div className="flex flex-col gap-4">
          <div>
            <h1 className="text-xl font-bold text-foreground sm:text-2xl">{product.canonicalName}</h1>
            <div className="mt-2 flex flex-wrap items-center gap-2">
              <Badge variant="outline">{product.category}</Badge>
              {product.isDemo && <DemoBadge />}
              {product.score && <ConfidenceBadge score={product.score.confidenceScore} />}
            </div>
          </div>

          {product.score ? (
            <Card className="rounded-2xl p-5">
              <div className="flex flex-wrap items-center gap-5">
                <OpportunityGauge value={product.score.opportunityScore} />
                <div>
                  <p className="text-xs font-medium text-muted-foreground">{d.scoreOverview}</p>
                  <div className="flex items-baseline gap-2">
                    <span className="text-3xl font-bold text-foreground tabular-nums">{product.score.opportunityScore}</span>
                    {scoreChange7d !== null && (
                      <Badge className={cn("gap-0.5 font-normal", scoreChange7d < 0 ? "bg-destructive/10 text-destructive" : "bg-success/10 text-success")}>
                        {scoreChange7d > 0 ? "↑" : scoreChange7d < 0 ? "↓" : "→"} {Math.abs(scoreChange7d)}
                      </Badge>
                    )}
                  </div>
                  <p className={cn("text-sm font-semibold", LEVEL_TONE[scoreLevel(product.score.opportunityScore)])}>
                    {d[OPPORTUNITY_LABEL_KEY[opportunityLevel(product.score.opportunityScore)]]}
                  </p>
                </div>
              </div>
              <div className="mt-5 grid grid-cols-2 gap-3 border-t pt-4 sm:grid-cols-4">
                <SignalCell label={d.signalDemand} score={product.score.demandScore} />
                <SignalCell label={d.signalCompetition} score={product.score.competitionScore} invert />
                <SignalCell label={d.signalProfitPotential} score={product.score.valueScore} />
                <SignalCell label={d.signalGrowth} score={product.score.trendScore} />
              </div>
            </Card>
          ) : (
            <Card className="rounded-2xl p-6 text-sm text-muted-foreground">{d.noChartData}</Card>
          )}

          <Card className="flex flex-col gap-4 rounded-2xl p-5 sm:flex-row sm:items-center sm:justify-between">
            <div className="grid grid-cols-3 gap-6">
              <div>
                <div className="text-xl font-bold text-foreground tabular-nums">
                  {product.currentPrice !== null ? formatPrice(product.currentPrice, product.currency, locale) : "—"}
                </div>
                <div className="mt-0.5 text-xs text-muted-foreground">{d.price}</div>
              </div>
              <div>
                <div className="text-xl font-bold text-foreground tabular-nums">
                  {sales7d !== null ? new Intl.NumberFormat(locale).format(sales7d) : "—"}
                </div>
                <div className="mt-0.5 text-xs text-muted-foreground">{d.salesWindow}</div>
              </div>
              <div>
                <div className={cn("text-xl font-bold tabular-nums", growth7d !== null && growth7d >= 0 ? "text-success" : "text-foreground")}>
                  {growth7d !== null ? formatPercent(growth7d, locale) : "—"}
                </div>
                <div className="mt-0.5 text-xs text-muted-foreground">{d.growthWindow}</div>
              </div>
            </div>
            <div className="h-[70px] w-full shrink-0 sm:w-[220px]">
              {sparkChart ? (
                <svg viewBox="0 0 220 70" className="size-full">
                  <defs>
                    <linearGradient id="sparkFill" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="0" stopColor="var(--success)" stopOpacity=".22" />
                      <stop offset="1" stopColor="var(--success)" stopOpacity="0" />
                    </linearGradient>
                  </defs>
                  <path d={sparkChart.area} fill="url(#sparkFill)" />
                  <polyline points={sparkChart.line} fill="none" stroke="var(--success)" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              ) : null}
            </div>
          </Card>

          <Card className="gap-0 overflow-hidden rounded-2xl py-0">
            <div className="flex flex-wrap items-center justify-between gap-3 border-b px-5 py-4">
              <h2 className="text-[15px] font-bold text-foreground">{d.performanceTitle}</h2>
              <div className="flex gap-1 rounded-lg bg-muted p-1">
                {RANGE_DAYS.map((days) => (
                  <button
                    key={days}
                    type="button"
                    onClick={() => setRange(days)}
                    aria-pressed={range === days}
                    className={cn(
                      "rounded-md px-3 py-1.5 text-xs font-semibold transition-colors",
                      range === days ? "bg-card text-foreground shadow-xs" : "text-muted-foreground hover:text-foreground",
                    )}
                  >
                    {d[`range${days}d` as "range7d" | "range30d" | "range90d" | "range180d"]}
                  </button>
                ))}
              </div>
            </div>

            <div className="grid grid-cols-2 gap-4 border-b px-5 py-4 sm:grid-cols-4">
              {metricRows.map((row) => {
                const change = changeOverDays(rangedSnapshots, range, row.metric);
                return (
                  <div key={row.labelKey}>
                    <div className="text-xs text-muted-foreground">{d[row.labelKey as "unitsSold" | "revenue" | "avgPrice" | "views"]}</div>
                    <div className="mt-0.5 text-lg font-bold text-foreground tabular-nums">
                      {row.current !== null
                        ? row.labelKey === "revenue" || row.labelKey === "avgPrice"
                          ? formatPrice(row.current, product.currency, locale)
                          : new Intl.NumberFormat(locale).format(row.current)
                        : "—"}
                    </div>
                    <div className={cn("mt-0.5 text-xs font-semibold", change !== null && change < 0 ? "text-destructive" : "text-success")}>
                      {change !== null ? formatPercent(change, locale) : d.noChartData}
                    </div>
                  </div>
                );
              })}
            </div>

            <div className="p-5">
              {!hasPerfChart ? (
                <p className="flex min-h-[200px] items-center justify-center text-sm text-muted-foreground">{d.noChartData}</p>
              ) : (
                <ChartContainer config={perfChartConfig} className="aspect-auto h-[230px] w-full">
                  <AreaChart data={perfChartRows} margin={{ left: 0, right: 8, top: 8, bottom: 0 }}>
                    <defs>
                      <linearGradient id="productPerfFill" x1="0" y1="0" x2="0" y2="1">
                        <stop offset="0%" stopColor="var(--color-revenue)" stopOpacity={0.25} />
                        <stop offset="100%" stopColor="var(--color-revenue)" stopOpacity={0} />
                      </linearGradient>
                    </defs>
                    <CartesianGrid vertical={false} strokeDasharray="3 3" />
                    <XAxis
                      dataKey="t"
                      type="number"
                      scale="time"
                      domain={["dataMin", "dataMax"]}
                      tickLine={false}
                      axisLine={false}
                      tickMargin={8}
                      fontSize={11}
                      tickFormatter={(value) => formatShortDate(new Date(value), locale)}
                    />
                    <YAxis hide domain={["auto", "auto"]} />
                    <ChartTooltip
                      content={
                        <ChartTooltipContent
                          labelFormatter={(_value, payload) => {
                            const ts = payload?.[0]?.payload?.t;
                            return typeof ts === "number" ? formatDate(new Date(ts), locale) : "";
                          }}
                        />
                      }
                    />
                    <Area
                      dataKey="revenue"
                      type="monotone"
                      stroke="var(--color-revenue)"
                      fill="url(#productPerfFill)"
                      strokeWidth={2.5}
                      connectNulls
                    />
                  </AreaChart>
                </ChartContainer>
              )}
            </div>
          </Card>
        </div>
      </div>

      <div className="flex flex-wrap items-center gap-4 text-sm text-muted-foreground">
        {product.brand && (
          <span>
            {d.brand}: {product.brand}
          </span>
        )}
        <span>
          {d.source}: {product.sourceName}
        </span>
        <span>
          {d.lastUpdated}: {formatDate(product.lastSeenAt, locale)}
        </span>
        {product.productUrl && (
          <a href={product.productUrl} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-1 hover:text-foreground">
            <ExternalLink className="size-3.5" />
            {d.productLink}
          </a>
        )}
      </div>

      {!canViewAdvanced ? (
        <UpgradePrompt requiredPlan={nextPlan} currentPlan={currentPlan} featureLabel={d.analysisLimitReached} />
      ) : (
        <>
          {product.score && (
            <Card className="rounded-2xl p-5">
              <h2 className="text-[15px] font-bold text-foreground">{d.scoreOverview}</h2>
              <Separator className="my-4" />
              <div className="grid grid-cols-3 gap-6 sm:grid-cols-6">
                {(
                  [
                    { key: "trendScore", labelKey: "trend" },
                    { key: "saturationScore", labelKey: "saturation" },
                    { key: "engagementScore", labelKey: "engagement" },
                    { key: "valueScore", labelKey: "value" },
                    { key: "competitionScore", labelKey: "competition" },
                    { key: "confidenceScore", labelKey: "confidence" },
                  ] as const
                ).map((row) => (
                  <div key={row.key} className="flex flex-col items-center gap-2">
                    <ScoreRing value={product.score![row.key]} size={56} strokeWidth={5} tone="purple" />
                    <span className="text-center text-xs text-muted-foreground capitalize">{row.labelKey}</span>
                  </div>
                ))}
              </div>
            </Card>
          )}

          <Card className="rounded-2xl p-5">
            <h2 className="text-[15px] font-bold text-foreground">{d.whyThisScore}</h2>
            <Separator className="my-4" />
            <div className="grid gap-6 sm:grid-cols-2">
              <div className="flex flex-col gap-2">
                <h3 className="text-xs font-semibold tracking-wide text-success uppercase">{d.strengths}</h3>
                {strengths.length === 0 ? (
                  <p className="text-sm text-muted-foreground">{d.noStrengths}</p>
                ) : (
                  <ul className="flex flex-col gap-1.5">
                    {strengths.map((s) => (
                      <li key={s.key} className="text-sm text-foreground">
                        {explanationLabel(t, s.key)}
                      </li>
                    ))}
                  </ul>
                )}
              </div>
              <div className="flex flex-col gap-2">
                <h3 className="text-xs font-semibold tracking-wide text-destructive uppercase">{d.risks}</h3>
                {risks.length === 0 ? (
                  <p className="text-sm text-muted-foreground">{d.noRisks}</p>
                ) : (
                  <ul className="flex flex-col gap-1.5">
                    {risks.map((r) => (
                      <li key={r.key} className="text-sm text-foreground">
                        {explanationLabel(t, r.key)}
                      </li>
                    ))}
                  </ul>
                )}
              </div>
            </div>
            {warnings.length > 0 && (
              <div className="mt-6 flex flex-col gap-2 border-t pt-4">
                <h3 className="text-xs font-semibold tracking-wide text-muted-foreground uppercase">{d.warnings}</h3>
                <div className="flex flex-wrap gap-1.5">
                  {warnings.map((w) => (
                    <span key={w.key} className={cn("rounded-full border px-2.5 py-1 text-xs font-medium", WARNING_SEVERITY_CLASSES[w.severity])}>
                      {explanationLabel(t, w.key)}
                    </span>
                  ))}
                </div>
              </div>
            )}
          </Card>

          {product.scoreHistory && product.scoreHistory.length >= 2 && (
            <Card className="rounded-2xl p-5">
              <h2 className="text-[15px] font-bold text-foreground">{d.scoreTrend}</h2>
              <Separator className="my-4" />
              <div className="grid gap-6 sm:grid-cols-2">
                <div>
                  <p className="mb-2 text-xs font-medium text-muted-foreground">{d.opportunityTrend}</p>
                  <MetricChart
                    title={d.opportunityTrend}
                    points={product.scoreHistory.map((h) => ({ date: h.calculatedAt, value: h.opportunityScore }))}
                    color="var(--brand-cyan)"
                    emptyLabel={d.noChartData}
                  />
                </div>
                <div>
                  <p className="mb-2 text-xs font-medium text-muted-foreground">{d.trendScoreTrend}</p>
                  <MetricChart
                    title={d.trendScoreTrend}
                    points={product.scoreHistory.map((h) => ({ date: h.calculatedAt, value: h.trendScore }))}
                    color="var(--brand-purple)"
                    emptyLabel={d.noChartData}
                  />
                </div>
              </div>
            </Card>
          )}
        </>
      )}

      <p className="text-center text-xs text-muted-foreground">{t.productCatalog.disclaimer}</p>
    </div>
  );
}
