"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import Link from "next/link";
import { useLocale, useTranslations } from "next-intl";
import { useQuery } from "@tanstack/react-query";
import {
  fetchDiscoverTaxonomy,
  fetchNlpHints,
  fetchPublicDiscover,
  type DiscoverSearchParams,
  type NlpHints,
  type PublicCafeDiscover,
} from "@/lib/api/public-discover";
import { resolveMediaUrl } from "@/lib/api/client";
import { formatNumber } from "@/lib/format";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent } from "@/components/ui/card";

const CITIES = [
  { id: "tehran", query: "تهران" },
  { id: "karaj", query: "کرج" },
] as const;

type FilterKey = "themes" | "vibes" | "occasions" | "spaceFeatures";

function toggle(list: string[], value: string): string[] {
  return list.includes(value) ? list.filter((x) => x !== value) : [...list, value];
}

// Count non-empty detected filter fields
function nlpHintCount(h: NlpHints | null): number {
  if (!h) return 0;
  return (
    h.themes.length +
    h.vibes.length +
    h.occasions.length +
    h.spaceFeatures.length +
    (h.noiseLevel ? 1 : 0) +
    (h.priceTier ? 1 : 0) +
    (h.size ? 1 : 0)
  );
}

export function PublicDiscoverScreen() {
  const t = useTranslations("discoverPublic");
  const tProfile = useTranslations("discoverProfile");
  const locale = useLocale();

  const [city, setCity] = useState<string>("tehran");
  const [search, setSearch] = useState("");
  const [debouncedSearch, setDebouncedSearch] = useState("");
  const [sort, setSort] = useState("rating");
  const [themes, setThemes] = useState<string[]>([]);
  const [vibes, setVibes] = useState<string[]>([]);
  const [occasions, setOccasions] = useState<string[]>([]);
  const [spaceFeatures, setSpaceFeatures] = useState<string[]>([]);
  const [noise, setNoise] = useState<string | null>(null);
  const [priceTier, setPriceTier] = useState<string | null>(null);
  const [size, setSize] = useState<string | null>(null);
  const [openNow, setOpenNow] = useState(false);

  // Debounce the search input for NLP hints
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  useEffect(() => {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => setDebouncedSearch(search), 600);
    return () => { if (debounceRef.current) clearTimeout(debounceRef.current); };
  }, [search]);

  // Fetch NLP hints whenever the debounced search changes
  const { data: nlpHints } = useQuery({
    queryKey: ["nlp-hints", debouncedSearch],
    queryFn: () => fetchNlpHints(debouncedSearch),
    enabled: debouncedSearch.trim().length > 2,
    staleTime: 30_000,
  });

  const cityQuery = CITIES.find((c) => c.id === city)?.query ?? "تهران";

  const params: DiscoverSearchParams = useMemo(
    () => ({
      city: cityQuery,
      q: search.trim() || undefined,
      sort,
      themes: themes.length ? themes : undefined,
      vibes: vibes.length ? vibes : undefined,
      occasions: occasions.length ? occasions : undefined,
      spaceFeatures: spaceFeatures.length ? spaceFeatures : undefined,
      noise: noise ?? undefined,
      priceTier: priceTier ?? undefined,
      size: size ?? undefined,
      openNow,
      requireProfile: true,
    }),
    [cityQuery, search, sort, themes, vibes, occasions, spaceFeatures, noise, priceTier, size, openNow]
  );

  const { data: taxonomy } = useQuery({
    queryKey: ["discover-taxonomy"],
    queryFn: fetchDiscoverTaxonomy,
  });

  const { data: cafes = [], isLoading, isFetching } = useQuery({
    queryKey: ["public-discover", params],
    queryFn: () => fetchPublicDiscover(params),
  });

  const label = useCallback(
    (key: string) => {
      const groups = ["themes", "vibes", "occasions", "spaceFeatures", "noiseLevels", "priceTiers", "sizes"] as const;
      for (const g of groups) {
        try { return tProfile(`${g}.${key}` as "themes.modern"); } catch { /* next */ }
      }
      return key;
    },
    [tProfile]
  );

  const clearAll = () => {
    setThemes([]); setVibes([]); setOccasions([]); setSpaceFeatures([]);
    setNoise(null); setPriceTier(null); setSize(null); setSearch("");
    setOpenNow(false);
  };

  const filterSection = (
    key: FilterKey,
    options: string[] | undefined,
    active: string[],
    setActive: (v: string[]) => void
  ) => {
    if (!options?.length) return null;
    return (
      <div className="space-y-2">
        <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
          {t(`filters.${key}`)}
        </p>
        <div className="flex flex-wrap gap-2">
          {options.slice(0, 14).map((opt) => (
            <button
              key={opt}
              type="button"
              onClick={() => setActive(toggle(active, opt))}
              className={cn(
                "rounded-lg border px-2.5 py-1 text-xs transition-colors active:scale-[0.98] cursor-pointer",
                active.includes(opt)
                  ? "border-[#0F6E56] bg-[#E1F5EE] text-[#0F6E56]"
                  : "border-border/80 hover:border-[#0F6E56]/40"
              )}
            >
              {label(opt)}
            </button>
          ))}
        </div>
      </div>
    );
  };

  const detectedCount = nlpHintCount(nlpHints ?? null);

  return (
    <div className="min-h-svh bg-[#f5f5f4]">
      <header className="border-b bg-white px-4 py-5">
        <div className="mx-auto max-w-3xl">
          <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
            {t("brand")}
          </p>
          <h1 className="text-lg font-medium text-foreground">{t("title")}</h1>
          <p className="mt-1 text-sm text-muted-foreground">{t("subtitle")}</p>
        </div>
      </header>

      <main className="mx-auto max-w-3xl space-y-4 p-4">
        {/* City selector */}
        <div className="flex flex-wrap gap-2">
          {CITIES.map((c) => (
            <Button
              key={c.id}
              size="sm"
              variant={city === c.id ? "default" : "outline"}
              className={city === c.id ? "bg-[#0F6E56]" : ""}
              onClick={() => setCity(c.id)}
            >
              {t(`cities.${c.id}`)}
            </Button>
          ))}
        </div>

        {/* AI smart search */}
        <div className="space-y-2">
          <div className="relative">
            <Input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder={t("searchPlaceholder")}
              className="text-end pe-10"
            />
            {/* AI spark indicator */}
            <span
              className={cn(
                "pointer-events-none absolute start-3 top-1/2 -translate-y-1/2 text-sm transition-opacity",
                debouncedSearch.trim().length > 2 ? "opacity-100" : "opacity-30"
              )}
              aria-hidden
            >
              ✦
            </span>
          </div>
          <p className="text-[11px] text-muted-foreground">{t("searchHint")}</p>

          {/* Detected filters banner */}
          {detectedCount > 0 && (
            <div className="flex flex-wrap items-center gap-2 rounded-lg border border-[#0F6E56]/30 bg-[#E1F5EE]/60 px-3 py-2">
              <span className="text-[11px] font-medium text-[#0F6E56]">
                {t("aiDetectedLabel")}
              </span>
              {nlpHints?.themes.map((k) => (
                <span key={k} className="rounded-md bg-[#0F6E56]/10 px-2 py-0.5 text-[11px] text-[#0F6E56]">
                  {label(k)}
                </span>
              ))}
              {nlpHints?.vibes.map((k) => (
                <span key={k} className="rounded-md bg-[#0F6E56]/10 px-2 py-0.5 text-[11px] text-[#0F6E56]">
                  {label(k)}
                </span>
              ))}
              {nlpHints?.occasions.map((k) => (
                <span key={k} className="rounded-md bg-[#0F6E56]/10 px-2 py-0.5 text-[11px] text-[#0F6E56]">
                  {label(k)}
                </span>
              ))}
              {nlpHints?.spaceFeatures.map((k) => (
                <span key={k} className="rounded-md bg-[#0F6E56]/10 px-2 py-0.5 text-[11px] text-[#0F6E56]">
                  {label(k)}
                </span>
              ))}
              {nlpHints?.noiseLevel && (
                <span className="rounded-md bg-[#0F6E56]/10 px-2 py-0.5 text-[11px] text-[#0F6E56]">
                  {label(nlpHints.noiseLevel)}
                </span>
              )}
              {nlpHints?.priceTier && (
                <span className="rounded-md bg-[#0F6E56]/10 px-2 py-0.5 text-[11px] text-[#0F6E56]">
                  {label(nlpHints.priceTier)}
                </span>
              )}
              {nlpHints?.size && (
                <span className="rounded-md bg-[#0F6E56]/10 px-2 py-0.5 text-[11px] text-[#0F6E56]">
                  {label(nlpHints.size)}
                </span>
              )}
              <button
                type="button"
                onClick={() => setSearch("")}
                className="ms-auto text-[11px] text-[#0F6E56] underline cursor-pointer"
              >
                {t("aiDetectedClear")}
              </button>
            </div>
          )}
        </div>

        {/* Filter panel */}
        <Card className="rounded-xl border border-border/80 shadow-sm">
          <CardContent className="space-y-4 p-4">
            {filterSection("occasions", taxonomy?.occasions, occasions, setOccasions)}
            {filterSection("vibes", taxonomy?.vibes, vibes, setVibes)}
            {filterSection("spaceFeatures", taxonomy?.spaceFeatures, spaceFeatures, setSpaceFeatures)}
            {filterSection("themes", taxonomy?.themes, themes, setThemes)}

            {/* Size filter — was missing before */}
            <div className="space-y-2">
              <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
                {t("filters.size")}
              </p>
              <div className="flex flex-wrap gap-2">
                {taxonomy?.sizes?.map((s) => (
                  <button
                    key={s}
                    type="button"
                    onClick={() => setSize(size === s ? null : s)}
                    className={cn(
                      "rounded-lg border px-2.5 py-1 text-xs transition-colors cursor-pointer",
                      size === s
                        ? "border-[#0F6E56] bg-[#E1F5EE] text-[#0F6E56]"
                        : "border-border/80 hover:border-[#0F6E56]/40"
                    )}
                  >
                    {label(s)}
                  </button>
                ))}
              </div>
            </div>

            {/* Noise level */}
            <div className="space-y-2">
              <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
                {t("filters.noise")}
              </p>
              <div className="flex flex-wrap gap-2">
                {taxonomy?.noiseLevels?.map((n) => (
                  <button
                    key={n}
                    type="button"
                    onClick={() => setNoise(noise === n ? null : n)}
                    className={cn(
                      "rounded-lg border px-2.5 py-1 text-xs transition-colors cursor-pointer",
                      noise === n
                        ? "border-[#0F6E56] bg-[#E1F5EE] text-[#0F6E56]"
                        : "border-border/80 hover:border-[#0F6E56]/40"
                    )}
                  >
                    {label(n)}
                  </button>
                ))}
              </div>
            </div>

            {/* Price tier */}
            <div className="space-y-2">
              <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
                {t("filters.priceTier")}
              </p>
              <div className="flex flex-wrap gap-2">
                {taxonomy?.priceTiers?.map((p) => (
                  <button
                    key={p}
                    type="button"
                    onClick={() => setPriceTier(priceTier === p ? null : p)}
                    className={cn(
                      "rounded-lg border px-2.5 py-1 text-xs transition-colors cursor-pointer",
                      priceTier === p
                        ? "border-[#0F6E56] bg-[#E1F5EE] text-[#0F6E56]"
                        : "border-border/80 hover:border-[#0F6E56]/40"
                    )}
                  >
                    {label(p)}
                  </button>
                ))}
              </div>
            </div>

            {/* Open now toggle + actions */}
            <div className="flex flex-wrap items-center gap-3 pt-1">
              <button
                type="button"
                onClick={() => setOpenNow((v) => !v)}
                className={cn(
                  "flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-xs font-medium transition-colors cursor-pointer",
                  openNow
                    ? "border-emerald-500 bg-emerald-50 text-emerald-700"
                    : "border-border/80 hover:border-emerald-400/60"
                )}
              >
                <span
                  className={cn(
                    "inline-block h-2 w-2 rounded-full",
                    openNow ? "bg-emerald-500" : "bg-muted-foreground/40"
                  )}
                />
                {t("openNow")}
              </button>

              <Button
                size="sm"
                variant="outline"
                onClick={clearAll}
                className="ms-auto"
              >
                {t("clearFilters")}
              </Button>
            </div>
          </CardContent>
        </Card>

        {/* Results header */}
        <div className="flex items-center justify-between">
          <p className="text-sm text-muted-foreground">
            {isLoading || isFetching
              ? t("loading")
              : t("resultCount", { count: cafes.length })}
          </p>
          <select
            value={sort}
            onChange={(e) => setSort(e.target.value)}
            className="rounded-lg border border-border/80 bg-white px-2 py-1 text-sm"
          >
            <option value="rating">{t("sort.rating")}</option>
            <option value="reviews">{t("sort.reviews")}</option>
            <option value="name">{t("sort.name")}</option>
          </select>
        </div>

        {/* Results */}
        {cafes.length === 0 && !isLoading ? (
          <Card className="rounded-xl border border-dashed p-8 text-center">
            <p className="text-sm text-muted-foreground">{t("empty")}</p>
          </Card>
        ) : (
          <ul className="space-y-3">
            {cafes.map((cafe) => (
              <CafeDiscoverCard key={cafe.id} cafe={cafe} locale={locale} label={label} t={t} />
            ))}
          </ul>
        )}
      </main>
    </div>
  );
}

// ── Card component ────────────────────────────────────────────────────────────

function CafeDiscoverCard({
  cafe,
  locale,
  label,
  t,
}: {
  cafe: PublicCafeDiscover;
  locale: string;
  label: (key: string) => string;
  t: ReturnType<typeof useTranslations<"discoverPublic">>;
}) {
  // Pick the best cover: gallery first, then coverImage, then logo
  const firstGallery = cafe.galleryUrls?.[0];
  const cover = resolveMediaUrl(firstGallery ?? cafe.coverImageUrl ?? cafe.logoUrl);

  const tags = [
    ...cafe.discoverProfile.occasions.slice(0, 2),
    ...cafe.discoverProfile.vibes.slice(0, 1),
  ];

  return (
    <li>
      <Link
        href={`/${locale}/discover/${cafe.slug}`}
        className="block rounded-xl border border-border/80 bg-white transition-all hover:border-[#0F6E56] hover:shadow-sm active:scale-[0.99] cursor-pointer"
      >
        {/* Cover image */}
        {cover ? (
          <div
            className="h-32 rounded-t-xl bg-cover bg-center"
            style={{ backgroundImage: `url(${cover})` }}
          />
        ) : (
          <div className="flex h-32 items-center justify-center rounded-t-xl bg-muted">
            <svg className="h-10 w-10 text-muted-foreground/30" viewBox="0 0 24 24" fill="currentColor">
              <path d="M2 19V7a2 2 0 012-2h1V4a1 1 0 012 0v1h10V4a1 1 0 112 0v1h1a2 2 0 012 2v12a2 2 0 01-2 2H4a2 2 0 01-2-2z"/>
            </svg>
          </div>
        )}

        <div className="space-y-2 p-4">
          <div className="flex items-start justify-between gap-2">
            <div className="flex items-center gap-2">
              <h2 className="font-medium text-foreground">{cafe.name}</h2>
              {/* Gallery count badge */}
              {cafe.galleryUrls?.length > 1 && (
                <span className="rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground">
                  +{cafe.galleryUrls.length - 1}
                </span>
              )}
            </div>
            <div className="flex shrink-0 items-center gap-2">
              {/* Open/closed badge */}
              {cafe.isOpenNow && (
                <span className="flex items-center gap-1 rounded-full bg-emerald-50 px-2 py-0.5 text-[10px] font-medium text-emerald-700">
                  <span className="h-1.5 w-1.5 rounded-full bg-emerald-500" />
                  {t("openNowLabel")}
                </span>
              )}
              {cafe.averageRating > 0 && (
                <span className="text-sm font-medium text-[#0F6E56]">
                  ★ {formatNumber(cafe.averageRating, locale)}
                </span>
              )}
            </div>
          </div>

          {cafe.city && (
            <p className="text-xs text-muted-foreground">
              {cafe.city}
              {cafe.address ? ` — ${cafe.address}` : ""}
            </p>
          )}

          <div className="flex flex-wrap gap-1">
            {tags.map((tag) => (
              <Badge key={tag} variant="secondary" className="text-[10px]">
                {label(tag)}
              </Badge>
            ))}
            {cafe.discoverProfile.priceTier && (
              <Badge className="bg-amber-100 text-[10px] text-amber-900">
                {label(cafe.discoverProfile.priceTier)}
              </Badge>
            )}
          </div>

          {/* Gallery strip */}
          {cafe.galleryUrls?.length > 1 && (
            <div className="flex gap-1 overflow-x-auto pb-0.5">
              {cafe.galleryUrls.slice(1, 4).map((url, i) => (
                <div
                  key={i}
                  className="h-10 w-16 shrink-0 rounded bg-cover bg-center"
                  style={{ backgroundImage: `url(${resolveMediaUrl(url)})` }}
                />
              ))}
            </div>
          )}

          <p className="text-xs text-[#0F6E56]">{t("viewCafe")} ←</p>
        </div>
      </Link>
    </li>
  );
}
