"use client";

import { useEffect } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import { LifeNotice, LifeSkeleton } from "@/components/life/LifeStatus";
import Pager from "@/components/life/Pager";
import PlaceCard from "@/components/life/PlaceCard";
import { favoriteHref, favoriteKind, listFavorites, type FavoriteEntry } from "@/lib/api/auth";
import { createListStore } from "@/store/createListStore";
import { useAuth } from "@/store/auth";
import SaveButton from "./SaveButton";

const useFavoritesStore = createListStore<FavoriteEntry, { page: number }>({ fetcher: (f, s) => listFavorites(f.page, s), initialFilters: { page: 1 } });

const when = new Intl.DateTimeFormat("en-GB", { day: "numeric", month: "short", timeZone: "Asia/Damascus" });

/** One line under the name: what it is, plus the most useful detail for that kind. */
function meta(e: FavoriteEntry) {
  const extra =
    e.entity_type === "event" && e.starts_at
      ? when.format(new Date(e.starts_at))
      : e.entity_type === "experience" && e.days
        ? `${e.days} ${e.days === 1 ? "day" : "days"}`
        : e.entity_type === "travel_deal" && e.discount_percent
          ? `${Math.round(Number(e.discount_percent))}% off`
          : (e.address ?? null);
  return [favoriteKind(e), extra ?? e.city?.name].filter(Boolean).join(" · ");
}

/** Saved items for the signed-in user. Unsaving a card removes it in place; guests go to login first. */
export default function Favourites() {
  const router = useRouter();
  const reduce = useReducedMotion();
  const status = useAuth((s) => s.status);
  const favorites = useAuth((s) => s.favorites);
  const ready = useAuth((s) => s.favoritesReady);
  const store = useFavoritesStore();
  const userId = useAuth((s) => s.user?.id ?? null);

  useEffect(() => {
    if (status !== "guest") return;
    // Signed out: drop the last account's list so the next account never sees it.
    useFavoritesStore.setState({ items: [], meta: null, status: "idle", filters: { page: 1 } });
    router.replace("/login?next=%2Ffavourites");
  }, [status, router]);

  // Reload when the user or the page changes.
  useEffect(() => {
    if (status !== "user" || userId === null) return;
    void store.load();
  }, [status, userId, store.filters, store.load]);

  // Once the saved ids are known, a card the user just unsaved drops out of the grid.
  const items = store.items.filter((e) => !ready || favorites.has(e.reviewable_id));
  const loading = status !== "user" || store.status === "idle" || store.status === "loading";
  // The server total is from page load; subtract cards unsaved since then.
  const total = Math.max(0, (store.meta?.total ?? store.items.length) - (store.items.length - items.length));

  return (
    <>
      <header className="lf-head">
        <div className="wrap">
          <span className="eyebrow">Your account</span>
          <h1 className="lf-title">Favourites</h1>
          <p className="lead">Places, events, guides and deals you saved, in one list.</p>
        </div>
      </header>
      <section className="wrap lf-body">
        <div className="lf">
          <LifeNotice status={store.status} error={store.error} hasFallback={false} onRetry={() => void store.load()} />
          {!loading && <p className="lf-count" aria-live="polite">{`${total} saved`}</p>}

          {loading && items.length === 0 ? (
            <LifeSkeleton />
          ) : items.length > 0 ? (
            <motion.div layout className="lf-grid">
              <AnimatePresence mode="popLayout">
                {items.map((e, i) => {
                  const name = e.name ?? e.title ?? "Saved place";
                  return (
                    <motion.div key={e.favorite_id} layout className="fav-item" exit={reduce ? undefined : { opacity: 0, scale: 0.96, transition: { duration: 0.18 } }}>
                      <PlaceCard index={reduce ? 0 : Math.min(i, 6)} item={{ key: `fav-${e.favorite_id}`, name, meta: meta(e), tags: [], src: e.cover?.url ?? null, href: favoriteHref(e) }} />
                      <SaveButton reviewableId={e.reviewable_id} name={name} />
                    </motion.div>
                  );
                })}
              </AnimatePresence>
            </motion.div>
          ) : store.status === "ready" ? (
            <div className="lf-empty">
              <p>Nothing saved yet.</p>
              <span className="lf-muted">Tap Save on any place, event or deal to keep it here.</span>
              <Link className="btn btn-rose btn-sm" href="/explore/history-and-heritage">
                Start exploring
              </Link>
            </div>
          ) : null}

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