import { createFileRoute, Link } from "@tanstack/react-router";
import { queryOptions, useSuspenseQuery } from "@tanstack/react-query";
import { Suspense, useMemo, useState } from "react";
import { getIndexableTopics } from "@/lib/api/topics-registry.functions";
import { FEATURED_TOPICS } from "@/lib/devotional";
import { topicToSlug } from "@/lib/topics";
import { LoadingState, EmptyState } from "@/components/devotional/States";
import { Search } from "lucide-react";
import { pageSeo, jsonLd, absUrl } from "@/lib/seo";

type RegistryTopic = { slug: string; display_name: string; is_featured: boolean | null; result_count: number | null; is_indexable: boolean | null };

const topicsQuery = queryOptions({
  queryKey: ["registry-topics"],
  queryFn: () => getIndexableTopics(),
  staleTime: 60 * 60 * 1000,
});

export const Route = createFileRoute("/topics/")({
  head: () => {
    const seo = pageSeo({
      title: "Bible Topics | Bible Word of the Day",
      description:
        "Browse Bible devotional topics including prayer, faith, forgiveness, fear, wisdom, obedience, love, hope, and trusting God.",
      path: "/topics",
    });
    return {
      meta: seo.meta,
      links: seo.links,
      scripts: [
        jsonLd({
          "@context": "https://schema.org",
          "@type": "CollectionPage",
          name: "Bible Topics",
          url: absUrl("/topics"),
          description: "Browse Bible devotionals by topic.",
        }),
      ],
    };
  },
  loader: ({ context }) => context.queryClient.ensureQueryData(topicsQuery),
  component: TopicsPage,
  errorComponent: () => <FallbackTopics />,
  notFoundComponent: () => <FallbackTopics />,
});

function TopicsPage() {
  return (
    <Suspense fallback={<div className="mx-auto max-w-4xl px-4 py-16"><LoadingState /></div>}>
      <TopicsContent />
    </Suspense>
  );
}

function TopicsContent() {
  const { data } = useSuspenseQuery(topicsQuery);
  const topics = (data.topics ?? []) as RegistryTopic[];
  return <TopicsView topics={topics} />;
}

function FallbackTopics() {
  const topics: RegistryTopic[] = FEATURED_TOPICS.map((name) => ({
    slug: topicToSlug(name),
    display_name: name,
    is_featured: true,
    result_count: null,
    is_indexable: true,
  }));
  return <TopicsView topics={topics} />;
}

function TopicsView({ topics }: { topics: RegistryTopic[] }) {
  const [q, setQ] = useState("");
  // Show every catalog topic; pages lazy-sync on first visit and self-mark
  // non-indexable if the API returns zero results.
  const indexable = topics;
  const featured = useMemo(() => {
    const featuredSet = new Set(FEATURED_TOPICS.map(topicToSlug));
    const fromDb = indexable.filter((t) => t.is_featured || featuredSet.has(t.slug));
    if (fromDb.length > 0) return fromDb.slice(0, 12);
    return FEATURED_TOPICS.map((name) => ({
      slug: topicToSlug(name),
      display_name: name,
      is_featured: true,
      result_count: null,
      is_indexable: true,
    })) as RegistryTopic[];
  }, [indexable]);

  const filtered = useMemo(() => {
    const needle = q.trim().toLowerCase();
    const list = needle ? indexable.filter((t) => t.display_name.toLowerCase().includes(needle)) : indexable;
    return [...list].sort((a, b) => a.display_name.localeCompare(b.display_name));
  }, [q, indexable]);

  return (
    <div className="mx-auto max-w-6xl px-4 py-14 sm:px-6">
      <header className="max-w-2xl">
        <p className="text-xs font-medium uppercase tracking-[0.2em] text-[var(--gold)]">Bible topics</p>
        <h1 className="mt-2 font-serif text-4xl font-semibold text-primary sm:text-5xl">
          Browse Bible Devotionals by Topic
        </h1>
        <p className="mt-3 text-base text-muted-foreground">
          Whatever you're facing today — fear, doubt, loss, joy — there's a Bible word for it.
        </p>
      </header>

      <section className="mt-10">
        <h2 className="font-serif text-2xl font-semibold text-primary">Featured</h2>
        <div className="mt-4 grid gap-3 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
          {featured.map((t) => (
            <Link
              key={t.slug}
              to="/topics/$topic"
              params={{ topic: t.slug }}
              className="group rounded-2xl border border-border bg-card p-5 shadow-soft transition hover:-translate-y-0.5 hover:border-[var(--gold)]/60 hover:shadow-glow"
            >
              <h3 className="font-serif text-lg font-semibold text-primary group-hover:text-[var(--gold)]">
                {t.display_name}
              </h3>
              <p className="mt-1 text-xs text-muted-foreground">
                Bible word about {t.display_name.toLowerCase()}
              </p>
            </Link>
          ))}
        </div>
      </section>

      <section className="mt-14">
        <div className="flex flex-col items-start justify-between gap-3 sm:flex-row sm:items-end">
          <h2 className="font-serif text-2xl font-semibold text-primary">All topics</h2>
          <div className="relative w-full sm:w-72">
            <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
            <input
              value={q}
              onChange={(e) => setQ(e.target.value)}
              placeholder="Filter topics…"
              className="w-full rounded-full border border-border bg-card py-2.5 pl-9 pr-4 text-sm focus:border-[var(--gold)] focus:outline-none"
            />
          </div>
        </div>

        {filtered.length === 0 ? (
          <div className="mt-6"><EmptyState title="No topics match that search" message="Try a different word." /></div>
        ) : (
          <div className="mt-5 flex flex-wrap gap-2">
            {filtered.map((t) => (
              <Link
                key={t.slug}
                to="/topics/$topic"
                params={{ topic: t.slug }}
                className="inline-flex items-center rounded-full border border-[var(--gold)]/40 bg-[var(--gold)]/10 px-3 py-1 text-xs font-medium text-primary transition hover:bg-[var(--gold)]/20"
              >
                {t.display_name}
              </Link>
            ))}
          </div>
        )}
      </section>
    </div>
  );
}
