"use client";

import { useEffect } from "react";
import { motion, AnimatePresence, useReducedMotion } from "motion/react";
import { CitySelect, SearchField, Chip } from "@/components/life/Controls";
import { LifeNotice, LifeSkeleton } from "@/components/life/LifeStatus";
import Pager from "@/components/life/Pager";
import PlaceCard from "@/components/life/PlaceCard";
import type { PlaceFilters, PlaceItem } from "@/lib/api/places";
import type { ListState } from "@/store/createListStore";


/** One directory for any place list (destinations, venues, embassies, airports...): city filter, search, cards, pager. Cards link to <base>?kind=<kind>&id=. */
export default function ExploreDirectory<F extends PlaceFilters = PlaceFilters>({
  useStore,
  kind,
  noun,
  base = "/explore/place",
  tags,
  search = true,
  extra,
  href,
}: {
  useStore: () => ListState<PlaceItem, F>;
  kind: string;
  noun: string;
  base?: string;
  tags?: (p: PlaceItem) => string[];
  search?: boolean;
  /** Extra filter controls (chips) shown in the toolbar. */
  extra?: React.ReactNode;
  /** Card link. Defaults to <base>?kind=<kind>&id=. */
  href?: (p: PlaceItem) => string;
}) {
  const reduce = useReducedMotion();
  const store = useStore();

  useEffect(() => {
    void store.load();
  }, [store.filters, store.load]);

  const setFilters = (patch: Partial<PlaceFilters>) => store.setFilters({ page: 1, ...patch } as Partial<F>);

  const items = store.items.map((p) => ({
    key: `${kind}-${p.id}`,
    name: p.name,
    meta: p.address ?? p.city?.name ?? "",
    tags: tags?.(p) ?? [],
    src: p.cover?.url ?? null,
    href: href ? href(p) : `${base}?kind=${kind}&id=${p.id}`,
  }));
  const filtered = Object.entries(store.filters).some(([k, v]) => k !== "page" && v !== undefined && v !== "");
  const loading = store.status === "idle" || store.status === "loading";
  const total = store.meta?.total ?? items.length;

  return (
    <div className="lf">
      <div className="lf-toolbar">
        <div className="lf-tools">
          <CitySelect value={store.filters.city_id} onChange={(city_id) => setFilters({ city_id })} />
          {extra}
          {search && <SearchField value={store.filters.q ?? ""} onChange={(q) => setFilters({ q })} placeholder={`Search ${noun}`} />}
        </div>
      </div>

      <LifeNotice status={store.status} error={store.error} hasFallback={false} onRetry={() => void store.load()} />

      <p className="lf-count" aria-live="polite">{loading ? "Loading" : `${total} ${total === 1 ? noun.slice(0, -1) : noun}`}</p>

      {loading && items.length === 0 ? (
        <LifeSkeleton />
      ) : items.length > 0 ? (
        <motion.div layout className="lf-grid">
          <AnimatePresence mode="popLayout">
            {items.map((item, i) => (
              <PlaceCard key={item.key} item={item} index={reduce ? 0 : Math.min(i, 6)} />
            ))}
          </AnimatePresence>
        </motion.div>
      ) : (
        <div className="lf-empty">
          <p>{filtered ? `No ${noun} match these filters.` : `No ${noun} are listed yet.`}</p>
          {filtered && (
            <Chip pressed={false} onClick={store.resetFilters}>
              Clear filters
            </Chip>
          )}
        </div>
      )}

      <Pager meta={store.meta} onPage={(page) => store.setFilters({ page } as Partial<F>)} />
    </div>
  );
}
