"use client";

import { useEffect } from "react";
import { AnimatePresence, motion, 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 EventCard, { type EventCardModel } from "@/components/life/EventCard";
import { eventItems, type EventItem as SampleEvent } from "@/data/events";
import type { EventFilters, EventItem } from "@/lib/api/events";
import { useExhibitionsStore, useFestivalsStore } from "@/store/events";

function apiModel(e: EventItem): EventCardModel {
  const price = e.is_free ? "Free" : e.price_from ? `From ${e.price_from}${e.currency ? ` ${e.currency}` : ""}` : "";
  return {
    key: `e-${e.id}`,
    name: e.name,
    meta: [e.category?.name, e.city?.name].filter(Boolean).join(", "),
    date: e.starts_at,
    price,
    free: e.is_free,
    src: e.cover?.url ?? null,
    href: `/life-and-fun/details/event?id=${e.id}`,
  };
}

/** Sample event shown while the API is unreachable. Dates are noon Damascus time. It has no detail page. */
function sampleModel(e: SampleEvent): EventCardModel {
  return {
    key: `s-${e.id}`,
    name: e.name,
    meta: `${e.category}, ${e.city}`,
    date: `${e.date}T12:00:00+03:00`,
    price: e.price,
    free: e.free,
    src: e.src,
    href: null,
  };
}

/** Festivals & Events or Exhibitions list, paginated by the server. Falls back to sample events on the festivals page only. */
export default function EventDirectory({ scope }: { scope: "festivals" | "exhibitions" }) {
  const reduce = useReducedMotion();
  const festivals = useFestivalsStore();
  const exhibitions = useExhibitionsStore();
  const store = scope === "exhibitions" ? exhibitions : festivals;

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

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

  const hasFallback = store.status === "error" && scope === "festivals";
  const items: EventCardModel[] = hasFallback
    ? eventItems.filter((e) => e.kind !== "exhibition").map(sampleModel)
    : store.items.map(apiModel);

  const filtered = Boolean(store.filters.city_id || store.filters.q || store.filters.free_only);
  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 })} disabled={hasFallback} />
          <SearchField
            value={store.filters.q ?? ""}
            onChange={(q) => setFilters({ q })}
            placeholder={scope === "exhibitions" ? "Search exhibitions" : "Search festivals and events"}
            disabled={hasFallback}
          />
        </div>
        <div className="lf-group" role="group" aria-label="Price">
          <Chip pressed={Boolean(store.filters.free_only)} onClick={() => setFilters({ free_only: !store.filters.free_only })} disabled={hasFallback}>
            Free only
          </Chip>
        </div>
      </div>

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

      {!hasFallback && <p className="lf-count" aria-live="polite">{loading ? "Loading" : `${total} ${total === 1 ? "event" : "events"}`}</p>}

      {loading && items.length === 0 ? (
        <LifeSkeleton />
      ) : items.length > 0 ? (
        <motion.div layout className="lf-grid">
          <AnimatePresence mode="popLayout">
            {items.map((item, i) => (
              <EventCard key={item.key} item={item} index={reduce ? 0 : Math.min(i, 6)} />
            ))}
          </AnimatePresence>
        </motion.div>
      ) : (
        <div className="lf-empty">
          <p>
            {filtered
              ? "No events match these filters."
              : scope === "exhibitions"
                ? "No exhibitions are listed yet."
                : "No festivals or events are listed yet."}
          </p>
          {filtered && (
            <Chip pressed={false} onClick={() => setFilters({ city_id: undefined, q: "", free_only: false })}>
              Clear filters
            </Chip>
          )}
        </div>
      )}

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