import { useEffect, useMemo, useRef, useState, type FormEvent, type MouseEvent } from "react";
import { apiFetch } from '@/utils/api';
import { useQuery } from "@tanstack/react-query";
import { Search, Loader2, PackageOpen, Copy, Check, ChevronsUpDown, X } from "lucide-react";

import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { toast } from "sonner";
import { cn } from "@/lib/utils";

type NumericAggregate = {
  count: number;
  sample_size: number;
  avg?: number;
  median?: number;
  min?: number;
  max?: number;
  stddev?: number;
  mode?: number | null;
  mode_count?: number;
  recent_mode?: number | null;
  recent_mode_count?: number;
  recent_window?: number;
  trending?: boolean;
  distribution: { value: number; count: number }[];
};

type CategoricalEntry = { value: string; count: number };

type DescriptionAggregate = {
  duplicates: { value: string; count: number }[];
  samples: { value: string; title: string; pid: number; sku: string }[];
};

type ProductRow = {
  pid: number;
  title: string;
  sku: string;
  brand: string | null;
  vendor: string | null;
  artist: string | null;
  country_of_origin: string | null;
  harmonized_tariff_code: string | null;
  description: string | null;
  categories: string | null;
  cost_price: number | null;
  regular_price: number | null;
  moq: number | null;
  weight: number | null;
  length: number | null;
  width: number | null;
  height: number | null;
  created_at: string | null;
};

type SpecLookupResponse = {
  company: string;
  term: string;
  total: number;
  truncated: boolean;
  products: ProductRow[];
  aggregates: {
    numeric: Record<string, NumericAggregate>;
    categorical: Record<string, CategoricalEntry[]>;
    categories: CategoricalEntry[];
    themes: CategoricalEntry[];
    description: DescriptionAggregate;
  };
};

type NumericFieldDef = {
  key: keyof SpecLookupResponse["aggregates"]["numeric"] | string;
  label: string;
  format: (n: number) => string;
};

const NUMERIC_FIELDS: NumericFieldDef[] = [
  { key: "moq", label: "Min Qty", format: (n) => formatInt(n) },
  { key: "cost_price", label: "Wholesale", format: (n) => formatCurrency(n) },
  { key: "regular_price", label: "MSRP", format: (n) => formatCurrency(n) },
  { key: "weight", label: "Weight (oz)", format: (n) => `${formatNumber(n)} oz` },
  { key: "length", label: "Length (in)", format: (n) => `${formatNumber(n)} in` },
  { key: "width", label: "Width (in)", format: (n) => `${formatNumber(n)} in` },
  { key: "height", label: "Height (in)", format: (n) => `${formatNumber(n)} in` },
];

const CATEGORICAL_FIELDS: { key: string; label: string }[] = [
  { key: "artist", label: "Artist" },
  { key: "country_of_origin", label: "COO" },
  { key: "harmonized_tariff_code", label: "HTS Code" },
];

function formatNumber(n: number): string {
  if (Math.abs(n) >= 100) return n.toFixed(1);
  if (Math.abs(n) >= 1) return n.toFixed(2);
  return n.toFixed(3);
}

function formatInt(n: number): string {
  return Number.isInteger(n) ? String(n) : n.toFixed(2);
}

function formatCurrency(n: number): string {
  return `$${n.toFixed(2)}`;
}

export default function SpecLookup() {
  const [company, setCompany] = useState("");
  const [term, setTerm] = useState("");
  const [companyOpen, setCompanyOpen] = useState(false);
  const [submitted, setSubmitted] = useState<{ company: string; term: string } | null>(null);
  const [copied, setCopied] = useState<string | null>(null);
  const copyTimerRef = useRef<number | null>(null);

  const { data: brandsData } = useQuery<{ brands: string[] }>({
    queryKey: ["spec-lookup-brands"],
    queryFn: async () => {
      const response = await apiFetch(`/api/brands-aggregate/filter-options`);
      if (!response.ok) throw new Error("Failed to load brands");
      return response.json();
    },
    staleTime: 10 * 60 * 1000,
  });
  const brands = brandsData?.brands ?? [];

  const queryKey = useMemo(
    () => ["spec-lookup", submitted?.company ?? "", submitted?.term ?? ""],
    [submitted],
  );

  const { data, error, isFetching, isFetched, refetch } = useQuery<SpecLookupResponse>({
    queryKey,
    enabled: false,
    queryFn: async () => {
      const params = new URLSearchParams();
      if (submitted?.company) params.set("company", submitted.company);
      if (submitted?.term) params.set("term", submitted.term);

      const response = await apiFetch(`/api/spec-lookup?${params.toString()}`);
      const payload = await response.json().catch(() => ({}));

      if (!response.ok) {
        const message = typeof payload.error === "string" ? payload.error : "Failed to fetch spec lookup";
        throw new Error(message);
      }
      return payload as SpecLookupResponse;
    },
    staleTime: 2 * 60 * 1000,
  });

  useEffect(() => {
    if (submitted) void refetch();
  }, [submitted, refetch]);

  useEffect(() => {
    return () => {
      if (copyTimerRef.current) window.clearTimeout(copyTimerRef.current);
    };
  }, []);

  useEffect(() => {
    if (error instanceof Error) {
      toast.error("Search failed", { description: error.message });
    }
  }, [error]);

  const handleSubmit = (event?: FormEvent) => {
    event?.preventDefault();
    const trimmedCompany = company.trim();
    const trimmedTerm = term.trim();

    if (!trimmedCompany && !trimmedTerm) {
      toast.info("Enter a company or product type");
      return;
    }

    if (submitted?.company === trimmedCompany && submitted?.term === trimmedTerm) {
      void refetch();
    } else {
      setSubmitted({ company: trimmedCompany, term: trimmedTerm });
    }
  };

  const handleCopy = async (event: MouseEvent<HTMLButtonElement>, key: string, value: string) => {
    event.preventDefault();
    event.stopPropagation();
    if (!navigator?.clipboard) {
      toast.error("Clipboard unavailable");
      return;
    }
    try {
      await navigator.clipboard.writeText(value);
      if (copyTimerRef.current) window.clearTimeout(copyTimerRef.current);
      setCopied(key);
      copyTimerRef.current = window.setTimeout(() => setCopied(null), 1200);
    } catch (err) {
      toast.error("Copy failed", {
        description: err instanceof Error ? err.message : "Unable to copy",
      });
    }
  };

  const renderEmpty = (label: string) => (
    <div className="text-xs italic text-muted-foreground">No {label} data in matches</div>
  );

  const renderNumericCard = (def: NumericFieldDef) => {
    const agg = data?.aggregates.numeric[def.key];
    const hasData = agg && agg.count > 0;
    const modeKey = `num:${def.key}`;
    // When we've detected a recent shift, the recommended (headline) value becomes the recent mode
    // — but the overall mode and full distribution are still shown below for verification.
    const recommendedValue = !hasData
      ? null
      : agg.trending && agg.recent_mode != null
        ? agg.recent_mode
        : agg.mode;
    const formattedRecommended =
      hasData && recommendedValue != null ? def.format(recommendedValue) : "—";

    return (
      <Card key={def.key}>
        <CardHeader className="pb-2">
          <div className="flex items-center justify-between gap-2">
            <div className="flex items-center gap-1.5">
              <CardDescription>{def.label}</CardDescription>
              {hasData && agg.trending && (
                <Badge variant="default" className="h-4 px-1.5 text-[9px] font-medium uppercase">
                  Recent shift
                </Badge>
              )}
            </div>
            {hasData && recommendedValue != null && (
              <Button
                type="button"
                size="icon"
                variant={copied === modeKey ? "secondary" : "ghost"}
                className="h-6 w-6"
                aria-label={`Copy ${def.label}`}
                onClick={(e) => handleCopy(e, modeKey, String(recommendedValue))}
              >
                {copied === modeKey ? <Check className="h-3 w-3 text-emerald-500" /> : <Copy className="h-3 w-3" />}
              </Button>
            )}
          </div>
          <CardTitle className="text-2xl">{formattedRecommended}</CardTitle>
        </CardHeader>
        <CardContent className="space-y-2 text-xs text-muted-foreground">
          {hasData ? (
            <>
              {agg.trending && agg.recent_mode != null ? (
                <>
                  <div>
                    Recent: <span className="text-foreground font-medium">{def.format(agg.recent_mode)}</span> ({agg.recent_mode_count} of last {agg.recent_window})
                  </div>
                  <div>
                    Overall mode was <span className="text-foreground">{def.format(agg.mode!)}</span> ({agg.mode_count} of {agg.count})
                  </div>
                </>
              ) : (
                <div>
                  Mode: <span className="text-foreground font-medium">{def.format(agg.mode!)}</span> ({agg.mode_count} of {agg.count})
                </div>
              )}
              <div>
                Median: <span className="text-foreground">{def.format(agg.median!)}</span>
                {" · "}
                Avg: <span className="text-foreground">{def.format(agg.avg!)}</span>
              </div>
              <div>
                Range: {def.format(agg.min!)} – {def.format(agg.max!)}
              </div>
              <div>
                {agg.count} of {agg.sample_size} products have this set
              </div>
              {agg.distribution.length > 1 && (
                <Accordion type="single" collapsible>
                  <AccordionItem value="dist" className="border-none">
                    <AccordionTrigger className="py-1 text-xs">Distribution ({agg.distribution.length} distinct)</AccordionTrigger>
                    <AccordionContent>
                      <div className="max-h-56 overflow-auto pr-2">
                        <Table>
                          <TableHeader>
                            <TableRow>
                              <TableHead className="h-7">Value</TableHead>
                              <TableHead className="h-7 text-right">Count</TableHead>
                            </TableRow>
                          </TableHeader>
                          <TableBody>
                            {agg.distribution.map((d) => (
                              <TableRow key={`${def.key}-${d.value}`}>
                                <TableCell className="py-1 font-mono">{def.format(d.value)}</TableCell>
                                <TableCell className="py-1 text-right">{d.count}</TableCell>
                              </TableRow>
                            ))}
                          </TableBody>
                        </Table>
                      </div>
                    </AccordionContent>
                  </AccordionItem>
                </Accordion>
              )}
            </>
          ) : (
            renderEmpty(def.label)
          )}
        </CardContent>
      </Card>
    );
  };

  const renderCategoricalCard = (key: string, label: string) => {
    const entries = data?.aggregates.categorical[key] ?? [];
    const top = entries[0];
    const cardKey = `cat:${key}`;

    return (
      <Card key={key}>
        <CardHeader className="pb-2">
          <div className="flex items-center justify-between gap-2">
            <CardDescription>{label}</CardDescription>
            {top && (
              <Button
                type="button"
                size="icon"
                variant={copied === cardKey ? "secondary" : "ghost"}
                className="h-6 w-6"
                aria-label={`Copy top ${label}`}
                onClick={(e) => handleCopy(e, cardKey, top.value)}
              >
                {copied === cardKey ? <Check className="h-3 w-3 text-emerald-500" /> : <Copy className="h-3 w-3" />}
              </Button>
            )}
          </div>
          <CardTitle className="text-base break-words">{top ? top.value : "—"}</CardTitle>
          {top && (
            <div className="text-xs text-muted-foreground">
              {top.count} of {data?.total ?? 0} products
            </div>
          )}
        </CardHeader>
        <CardContent className="text-xs text-muted-foreground">
          {entries.length === 0 ? (
            renderEmpty(label)
          ) : entries.length === 1 ? (
            <div>Only one distinct value across matches.</div>
          ) : (
            <Accordion type="single" collapsible>
              <AccordionItem value="all" className="border-none">
                <AccordionTrigger className="py-1 text-xs">All values ({entries.length})</AccordionTrigger>
                <AccordionContent>
                  <div className="max-h-56 overflow-auto pr-2">
                    <Table>
                      <TableHeader>
                        <TableRow>
                          <TableHead className="h-7">Value</TableHead>
                          <TableHead className="h-7 text-right">Count</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {entries.map((e) => (
                          <TableRow key={`${key}-${e.value}`}>
                            <TableCell className="py-1 break-all">{e.value}</TableCell>
                            <TableCell className="py-1 text-right">{e.count}</TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  </div>
                </AccordionContent>
              </AccordionItem>
            </Accordion>
          )}
        </CardContent>
      </Card>
    );
  };

  const renderTokenCard = (
    title: string,
    emptyLabel: string,
    entries: CategoricalEntry[],
  ) => {
    const dominantThreshold = Math.max(2, (data?.total ?? 0) * 0.5);
    return (
      <Card>
        <CardHeader>
          <CardTitle className="text-base">{title}</CardTitle>
        </CardHeader>
        <CardContent>
          {entries.length === 0 ? (
            renderEmpty(emptyLabel)
          ) : (
            <div className="flex flex-wrap gap-2">
              {entries.map((e) => (
                <Badge
                  key={e.value}
                  variant={e.count >= dominantThreshold ? "default" : "outline"}
                  className="font-normal"
                >
                  {e.value}
                  <span className="ml-1.5 text-[10px] opacity-70">×{e.count}</span>
                </Badge>
              ))}
            </div>
          )}
        </CardContent>
      </Card>
    );
  };

  const renderDescriptionCard = () => {
    const desc = data?.aggregates.description;
    if (!desc) return null;

    return (
      <Card>
        <CardHeader>
          <CardTitle className="text-base">Description</CardTitle>
        </CardHeader>
        <CardContent className="space-y-6">
          <div className="space-y-2">
            <div className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
              Used More Than Once {desc.duplicates.length > 0 && `(${desc.duplicates.length})`}
            </div>
            {desc.duplicates.length === 0 ? (
              <div className="text-xs italic text-muted-foreground">No description was used more than once.</div>
            ) : (
              <div className="max-h-96 space-y-2 overflow-auto pr-2">
                {desc.duplicates.map((d, i) => (
                  <div key={`dup-${i}`} className="rounded-md border p-3">
                    <div className="mb-1 flex items-center justify-between gap-2">
                      <Badge variant="default">Used {d.count}× </Badge>
                      <Button
                        type="button"
                        size="icon"
                        variant={copied === `dup:${i}` ? "secondary" : "ghost"}
                        className="h-6 w-6"
                        aria-label="Copy description"
                        onClick={(e) => handleCopy(e, `dup:${i}`, d.value)}
                      >
                        {copied === `dup:${i}` ? <Check className="h-3 w-3 text-emerald-500" /> : <Copy className="h-3 w-3" />}
                      </Button>
                    </div>
                    <div className="whitespace-pre-wrap text-sm">{d.value}</div>
                  </div>
                ))}
              </div>
            )}
          </div>

          <div className="space-y-2">
            <div className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
              Recent samples
            </div>
            {desc.samples.length === 0 ? (
              <div className="text-xs italic text-muted-foreground">No descriptions in matches.</div>
            ) : (
              <div className="max-h-96 space-y-2 overflow-auto pr-2">
                {desc.samples.map((s, i) => (
                  <div key={`sample-${s.pid}`} className="rounded-md border p-3">
                    <div className="mb-1 flex items-center justify-between gap-2">
                      <a
                        href={`https://backend.acherryontop.com/product/${s.pid}`}
                        target="_blank"
                        rel="noreferrer"
                        className="text-xs font-medium text-primary hover:underline"
                      >
                        {s.title}
                      </a>
                      <Button
                        type="button"
                        size="icon"
                        variant={copied === `sample:${i}` ? "secondary" : "ghost"}
                        className="h-6 w-6"
                        aria-label="Copy description"
                        onClick={(e) => handleCopy(e, `sample:${i}`, s.value)}
                      >
                        {copied === `sample:${i}` ? <Check className="h-3 w-3 text-emerald-500" /> : <Copy className="h-3 w-3" />}
                      </Button>
                    </div>
                    <div className="whitespace-pre-wrap text-sm">{s.value}</div>
                  </div>
                ))}
              </div>
            )}
          </div>
        </CardContent>
      </Card>
    );
  };

  const renderProductsTable = () => {
    if (!data || data.products.length === 0) return null;
    return (
      <Card>
        <CardHeader>
          <CardTitle className="text-base">Matched products ({data.total})</CardTitle>
          <CardDescription>
            {data.truncated ? "Showing first 500 matches (newest first)." : ""}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <div className="max-h-96 overflow-auto rounded-md border">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Product</TableHead>
                  <TableHead>SKU</TableHead>
                  <TableHead>Brand</TableHead>
                  <TableHead className="text-right">Cost</TableHead>
                  <TableHead className="text-right">MSRP</TableHead>
                  <TableHead className="text-right">Wt</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {data.products.map((p) => (
                  <TableRow key={p.pid}>
                    <TableCell>
                      <a
                        href={`https://backend.acherryontop.com/product/${p.pid}`}
                        target="_blank"
                        rel="noreferrer"
                        className="font-medium text-primary hover:underline"
                      >
                        {p.title}
                      </a>
                    </TableCell>
                    <TableCell className="whitespace-nowrap">{p.sku}</TableCell>
                    <TableCell>{p.brand || "—"}</TableCell>
                    <TableCell className="text-right">{p.cost_price != null ? formatCurrency(p.cost_price) : "—"}</TableCell>
                    <TableCell className="text-right">{p.regular_price != null ? formatCurrency(p.regular_price) : "—"}</TableCell>
                    <TableCell className="text-right">{p.weight != null ? formatNumber(p.weight) : "—"}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>
 
    );
  };

  return (
    <div className="space-y-6 p-6">
      <div className="space-y-2">
        <h1 className="text-3xl font-bold">Spec Lookup</h1>
        <p className="text-sm text-muted-foreground">
          Use this to compare existing values across similar products when setting up a new product.
        </p>
      </div>

      <Card>
        <CardHeader>
          <CardTitle>Search</CardTitle>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleSubmit} className="grid gap-3 md:grid-cols-[1fr_1fr_auto] md:items-end">
            <div className="space-y-1">
              <Label htmlFor="pd-company">Company</Label>
              <Popover open={companyOpen} onOpenChange={setCompanyOpen}>
                <PopoverTrigger asChild>
                  <Button
                    id="pd-company"
                    type="button"
                    variant="outline"
                    role="combobox"
                    aria-expanded={companyOpen}
                    className={cn("w-full justify-between font-normal", !company && "text-muted-foreground")}
                  >
                    <span className="truncate">{company || "Select company..."}</span>
                    <div className="flex shrink-0 items-center gap-1">
                      {company && (
                        <span
                          role="button"
                          tabIndex={0}
                          aria-label="Clear company"
                          className="rounded hover:bg-muted"
                          onClick={(e) => {
                            e.preventDefault();
                            e.stopPropagation();
                            setCompany("");
                          }}
                          onKeyDown={(e) => {
                            if (e.key === "Enter" || e.key === " ") {
                              e.preventDefault();
                              e.stopPropagation();
                              setCompany("");
                            }
                          }}
                        >
                          <X className="h-3 w-3 opacity-60" />
                        </span>
                      )}
                      <ChevronsUpDown className="h-4 w-4 opacity-50" />
                    </div>
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0">
                  <Command>
                    <CommandInput placeholder="Search companies..." />
                    <CommandList>
                      <CommandEmpty>No matching company.</CommandEmpty>
                      <CommandGroup>
                        {brands.map((b) => (
                          <CommandItem
                            key={b}
                            value={b}
                            onSelect={(value) => {
                              setCompany(value === company ? "" : value);
                              setCompanyOpen(false);
                            }}
                          >
                            <Check className={cn("mr-2 h-4 w-4", company === b ? "opacity-100" : "opacity-0")} />
                            {b}
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
            </div>
            <div className="space-y-1">
              <Label htmlFor="pd-term">Product Type</Label>
              <Input
                id="pd-term"
                placeholder="Paper pad, washi, stickers, etc."
                value={term}
                onChange={(e) => setTerm(e.target.value)}
              />
            </div>
            <div className="flex gap-2">
              <Button type="submit" disabled={isFetching}>
                {isFetching ? <Loader2 className="h-4 w-4 animate-spin" /> : <Search className="h-4 w-4" />}
                <span className="ml-2">Search</span>
              </Button>
              {isFetched && (
                <Button
                  type="button"
                  variant="outline"
                  disabled={isFetching}
                  onClick={() => {
                    setCompany("");
                    setTerm("");
                    setSubmitted(null);
                  }}
                >
                  Clear
                </Button>
              )}
            </div>
          </form>
        </CardContent>
      </Card>

      {isFetched && data && data.total === 0 && (
        <Card>
          <CardContent className="space-y-3 py-8 text-center text-muted-foreground">
            <PackageOpen className="mx-auto h-10 w-10" />
            <div>No products matched.</div>
          </CardContent>
        </Card>
      )}

      {isFetched && data && data.total > 0 && (
        <>
          <div className="grid gap-4 md:grid-cols-3">
            <Card>
              <CardHeader>
                <CardDescription>Matched products</CardDescription>
                <CardTitle className="text-3xl">{data.total}</CardTitle>
                {data.truncated && (
                  <div className="text-xs text-muted-foreground">capped at 500 — refine search to narrow</div>
                )}
              </CardHeader>
            </Card>
            <Card>
              <CardHeader>
                <CardDescription>Company filter</CardDescription>
                <CardTitle className="text-base break-words">{data.company || "(any)"}</CardTitle>
              </CardHeader>
            </Card>
            <Card>
              <CardHeader>
                <CardDescription>Product type</CardDescription>
                <CardTitle className="text-base break-words">{data.term || "(any)"}</CardTitle>
              </CardHeader>
            </Card>
          </div>

          <div>
            <h2 className="mb-3 text-lg font-semibold">Numeric fields</h2>
            <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
              {NUMERIC_FIELDS.map(renderNumericCard)}
            </div>
          </div>

          <div>
            <h2 className="mb-3 text-lg font-semibold">Categorical fields</h2>
            <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
              {CATEGORICAL_FIELDS.map((f) => renderCategoricalCard(f.key, f.label))}
            </div>
          </div>

          <div className="grid gap-4 md:grid-cols-2">
            {renderTokenCard(
              "Categories",
              "category",
              data.aggregates.categories,
            )}
            {renderTokenCard(
              "Themes",
              "theme",
              data.aggregates.themes ?? [],
            )}
          </div>
          {renderDescriptionCard()}
          {renderProductsTable()}
        </>
      )}
    </div>
  );
}
