"use client";

import { useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import Icon from "@/components/ui/Icon";
import { CitySelect, SearchField, Chip } from "@/components/life/Controls";
import { LifeNotice, LifeSkeleton } from "@/components/life/LifeStatus";
import Pager from "@/components/life/Pager";
import PlaceCard, { type PlaceCardModel } from "@/components/life/PlaceCard";
import { venues, type Venue } from "@/data/food";
import type { CafeItem, RestaurantItem } from "@/lib/api/dining";
import type { PlaceFilters } from "@/lib/api/places";
import { useCafesStore, useRestaurantsStore } from "@/store/dining";

type Kind = "restaurant" | "cafe";

const KINDS: { value: Kind; label: string; icon: string; param: string }[] = [
  { value: "restaurant", label: "Restaurants", icon: "restaurant", param: "restaurants" },
  { value: "cafe", label: "Cafés", icon: "local_cafe", param: "cafes" },
];

const spring = { type: "spring", stiffness: 500, damping: 40 } as const;

function restaurantModel(r: RestaurantItem): PlaceCardModel {
  return {
    key: `r-${r.id}`,
    name: r.name,
    meta: r.address ?? r.city?.name ?? "",
    tags: [...r.subtype.cuisines.map((c) => c.name), ...(r.subtype.has_delivery ? ["Delivery"] : []), ...(r.subtype.has_booking ? ["Booking"] : [])],
    src: r.cover?.url ?? null,
    href: `/life-and-fun/details/restaurant?id=${r.id}`,
  };
}

function cafeModel(c: CafeItem): PlaceCardModel {
  return {
    key: `c-${c.id}`,
    name: c.name,
    meta: c.address ?? c.city?.name ?? "",
    tags: [...(c.subtype.has_delivery ? ["Delivery"] : []), ...(c.subtype.has_booking ? ["Booking"] : [])],
    src: c.cover?.url ?? null,
    href: `/life-and-fun/details/cafe?id=${c.id}`,
  };
}

/** Sample venue shown while the API is unreachable. It has no detail page. */
function sampleModel(v: Venue): PlaceCardModel {
  return {
    key: `s-${v.id}`,
    name: v.name,
    meta: `${v.area}, ${v.city}`,
    tags: v.cuisine ? [v.cuisine] : [],
    src: v.src,
    href: null,
  };
}

/** Restaurant / café toggle with live city and search filters, paginated. Falls back to sample venues when the API fails. */
export default function FoodDirectory() {
  const reduce = useReducedMotion();
  const params = useSearchParams();
  const fromUrl: Kind = params.get("type") === "cafes" ? "cafe" : "restaurant";
  const [kind, setKind] = useState<Kind>(fromUrl);

  // A nav link to ?type=... while already on this page changes the URL but not this component, so follow it.
  useEffect(() => setKind(fromUrl), [fromUrl]);

  // Mirror the tab into ?type= without a reload, so the view can be shared.
  const chooseKind = (next: Kind) => {
    if (next === kind) return;
    setKind(next);
    const url = new URL(window.location.href);
    url.searchParams.set("type", KINDS.find((k) => k.value === next)!.param);
    window.history.replaceState(null, "", url);
  };

  const restaurants = useRestaurantsStore();
  const cafes = useCafesStore();
  const active = kind === "cafe" ? cafes : restaurants;

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

  // Any filter change goes back to page 1; only the page control keeps its place.
  const setFilters = (patch: Partial<PlaceFilters>) => active.setFilters({ page: 1, ...patch });

  const hasFallback = active.status === "error";
  const items: PlaceCardModel[] = hasFallback
    ? venues.filter((v) => v.kind === kind).map(sampleModel)
    : kind === "cafe"
      ? cafes.items.map(cafeModel)
      : restaurants.items.map(restaurantModel);

  const filtered = Boolean(active.filters.city_id || active.filters.q);
  const loading = active.status === "idle" || active.status === "loading";
  const total = active.meta?.total ?? items.length;

  return (
    <div className="lf">
      <div className="lf-toolbar">
        <div className="lf-seg" role="group" aria-label="Place type">
          {KINDS.map((k) => {
            const on = kind === k.value;
            return (
              <button key={k.value} type="button" className="lf-seg-btn" aria-pressed={on} onClick={() => chooseKind(k.value)}>
                {on && <motion.span layoutId="lf-seg-pill" className="lf-seg-pill" transition={reduce ? { duration: 0 } : spring} />}
                <span className="lf-seg-label">
                  <Icon name={k.icon} />
                  {k.label}
                </span>
              </button>
            );
          })}
        </div>

        <div className="lf-tools">
          <CitySelect value={active.filters.city_id} onChange={(city_id) => setFilters({ city_id })} disabled={hasFallback} />
          <SearchField
            value={active.filters.q ?? ""}
            onChange={(q) => setFilters({ q })}
            placeholder={kind === "cafe" ? "Search cafés" : "Search restaurants"}
            disabled={hasFallback}
          />
        </div>
      </div>

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

      {!hasFallback && <p className="lf-count" aria-live="polite">{loading ? "Loading" : `${total} ${total === 1 ? "place" : "places"}`}</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 places match these filters." : "No places are listed yet."}</p>
          {filtered && (
            <Chip pressed={false} onClick={() => setFilters({ city_id: undefined, q: "" })}>
              Clear filters
            </Chip>
          )}
        </div>
      )}

      {!hasFallback && <Pager meta={active.meta} onPage={(page) => active.setFilters({ page })} />}
    </div>
  );
}
