"use client";

import { useState } from "react";
import Link from "next/link";
import { Loader2, Search, Sparkles } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { useLanguage } from "@/lib/i18n/context";
import { ProductImage } from "@/components/dashboard/product-image";

interface AffiliateProduct {
  id: string | null;
  title: string | null;
  imageUrl: string | null;
  category: string | null;
  price: number | null;
  currency: string | null;
  commissionRate: number | null;
  commissionAmount: number | null;
  sales: number | null;
  views: number | null;
}

const COPY = {
  en: {
    eyebrow: "Affiliate intelligence",
    title: "Find products worth promoting",
    description: "Search TikTok Shop open collaborations with the Creator account you actually use for affiliate content.",
    search: "Search products or categories",
    min: "Min commission %",
    max: "Max commission %",
    find: "Search marketplace",
    connect: "Connect Creator account",
    noConnection: "Connect a TikTok Creator account to search affiliate collaborations.",
    noResults: "No products matched these filters.",
    commission: "Commission",
    price: "Price",
    sales: "Sales",
    views: "Views",
    unavailable: "Not provided",
    source: "Source: TikTok Creator Affiliate Marketplace",
    scoreNote: "TokNext Opportunity Score is shown only after a product is synchronized into your catalog; it is not invented from missing TikTok fields.",
  },
  es: {
    eyebrow: "Inteligencia para afiliados",
    title: "Encuentra productos que vale la pena promocionar",
    description: "Busca colaboraciones abiertas de TikTok Shop con la cuenta de creador que usas para tus contenidos de afiliado.",
    search: "Buscar productos o categorías",
    min: "Comisión mínima %",
    max: "Comisión máxima %",
    find: "Buscar en marketplace",
    connect: "Conectar cuenta de creador",
    noConnection: "Conecta una cuenta de creador de TikTok para buscar colaboraciones de afiliados.",
    noResults: "No hay productos con estos filtros.",
    commission: "Comisión",
    price: "Precio",
    sales: "Ventas",
    views: "Vistas",
    unavailable: "No disponible",
    source: "Fuente: Marketplace de afiliados de TikTok Creator",
    scoreNote: "El Opportunity Score de TokNext solo aparece después de sincronizar el producto al catálogo; no se inventa con campos faltantes.",
  },
} as const;

function number(value: number | null, locale: "en" | "es") {
  return value === null ? "—" : new Intl.NumberFormat(locale === "es" ? "es-US" : "en-US", { maximumFractionDigits: 2 }).format(value);
}

function money(value: number | null, currency: string | null, locale: "en" | "es") {
  if (value === null) return "—";
  try {
    return new Intl.NumberFormat(locale === "es" ? "es-US" : "en-US", { style: "currency", currency: currency ?? "USD" }).format(value);
  } catch {
    return number(value, locale);
  }
}

export function AffiliateProductsPage({ connected }: { connected: boolean }) {
  const { locale } = useLanguage();
  const copy = COPY[locale];
  const [query, setQuery] = useState("");
  const [minCommission, setMinCommission] = useState("");
  const [maxCommission, setMaxCommission] = useState("");
  const [products, setProducts] = useState<AffiliateProduct[]>([]);
  const [loading, setLoading] = useState(false);
  const [message, setMessage] = useState<string | null>(null);

  async function search() {
    setLoading(true);
    setMessage(null);
    const params = new URLSearchParams();
    if (query.trim()) params.set("q", query.trim());
    if (minCommission.trim()) params.set("minCommissionRate", minCommission.trim());
    if (maxCommission.trim()) params.set("maxCommissionRate", maxCommission.trim());
    try {
      const response = await fetch(`/api/tiktok/affiliate/products?${params.toString()}`);
      const payload = (await response.json()) as { products?: AffiliateProduct[]; error?: string };
      if (!response.ok) throw new Error(payload.error ?? "affiliate_products_unavailable");
      setProducts(payload.products ?? []);
    } catch (error) {
      setProducts([]);
      setMessage(error instanceof Error && error.message === "creator_not_connected" ? copy.noConnection : copy.noResults);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="flex w-full max-w-[1500px] flex-col gap-6 pb-10">
      <div>
        <p className="m-0 text-xs font-semibold uppercase tracking-[0.18em] text-primary">{copy.eyebrow}</p>
        <h1 className="mt-2 text-3xl font-semibold tracking-tight text-foreground">{copy.title}</h1>
        <p className="mt-2 max-w-3xl text-sm text-muted-foreground">{copy.description}</p>
      </div>

      {!connected ? (
        <Card className="flex flex-wrap items-center justify-between gap-4 rounded-2xl border-primary/15 bg-primary/[0.04] p-6">
          <p className="m-0 max-w-2xl text-sm text-muted-foreground">{copy.noConnection}</p>
          <Button asChild><Link href="/api/auth/tiktok/creator/connect">{copy.connect}</Link></Button>
        </Card>
      ) : (
        <>
          <Card className="rounded-2xl p-5">
            <div className="grid gap-3 md:grid-cols-[minmax(0,1fr)_170px_170px_auto] md:items-center">
              <div className="relative"><Search className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" /><Input value={query} onChange={(event) => setQuery(event.target.value)} onKeyDown={(event) => { if (event.key === "Enter") void search(); }} className="pl-9" placeholder={copy.search} /></div>
              <Input value={minCommission} onChange={(event) => setMinCommission(event.target.value)} type="number" min="0" max="100" placeholder={copy.min} />
              <Input value={maxCommission} onChange={(event) => setMaxCommission(event.target.value)} type="number" min="0" max="100" placeholder={copy.max} />
              <Button onClick={() => void search()} disabled={loading}>{loading ? <Loader2 className="mr-2 size-4 animate-spin" /> : <Sparkles className="mr-2 size-4" />}{copy.find}</Button>
            </div>
          </Card>
          {message ? <p className="px-1 text-sm text-muted-foreground">{message}</p> : null}
          {products.length > 0 ? (
            <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
              {products.map((product, index) => (
                <Card key={`${product.id ?? "product"}-${index}`} className="overflow-hidden rounded-2xl p-0">
                  <div className="flex h-40 items-center justify-center bg-muted/40">
                    {product.imageUrl ? <ProductImage src={product.imageUrl} alt={product.title ?? ""} fit="contain" className="h-full w-full rounded-none !aspect-auto" /> : <Sparkles className="size-8 text-muted-foreground/50" />}
                  </div>
                  <div className="space-y-3 p-5">
                    <h2 className="line-clamp-2 text-base font-semibold text-foreground">{product.title ?? copy.unavailable}</h2>
                    {product.category ? <Badge variant="secondary">{product.category}</Badge> : null}
                    <div className="grid grid-cols-2 gap-3 text-sm">
                      <Metric label={copy.commission} value={product.commissionRate === null ? copy.unavailable : `${number(product.commissionRate, locale)}%`} positive />
                      <Metric label={copy.price} value={money(product.price, product.currency, locale)} />
                      <Metric label={copy.sales} value={number(product.sales, locale)} />
                      <Metric label={copy.views} value={number(product.views, locale)} />
                    </div>
                  </div>
                </Card>
              ))}
            </div>
          ) : !message ? <p className="px-1 text-sm text-muted-foreground">{copy.noResults}</p> : null}
          <p className="text-xs text-muted-foreground">{copy.source}. {copy.scoreNote}</p>
        </>
      )}
    </div>
  );
}

function Metric({ label, value, positive = false }: { label: string; value: string; positive?: boolean }) {
  return <div><p className="m-0 text-xs text-muted-foreground">{label}</p><p className={`mt-1 font-semibold ${positive ? "text-emerald-600" : "text-foreground"}`}>{value}</p></div>;
}
