import type { Metadata } from "next";
import { defineQuery } from "next-sanity";
import { sanity } from "@/lib/sanity";
import { ArtistCard } from "@/components/artist/ArtistCard";
import { formatYears, type ComposerCardData } from "@/components/artist/types";
import { AnimatedText } from "@/components/AnimatedText";
import { SearchBar } from "@/components/SearchBar";
import { PaginationNav } from "@/components/PaginationNav";
import { CARD_GRID_CLASSES_4 } from "@/lib/constants";
import { PAGE_SIZE, clampInt, normalizeQuery, groqLikeParam } from "@/lib/listHelpers";
import type { SortOption } from "@/components/SortDropdown";

export const revalidate = 86400;

type SortMode = "name" | "sortKey" | "birthYearAsc" | "birthYearDesc";

const SORT_OPTIONS: SortOption<SortMode>[] = [
  { value: "name", label: "Sort by first name" },
  { value: "sortKey", label: "Sort by last name" },
  { value: "birthYearAsc", label: "Sort by birth year", iconDirection: "asc" },
  { value: "birthYearDesc", label: "Sort by birth year", iconDirection: "desc" },
];

function normalizeSort(s: string | undefined): SortMode {
  switch (s) {
    case "name":
    case "sortKey":
    case "birthYearAsc":
    case "birthYearDesc":
      return s;
    default:
      return "sortKey";
  }
}

const COMPOSER_FILTER_CLAUSE = `
_type == "composer" &&
(
  $q == "" ||
  name match $qPattern ||
  role match $qPattern
)
`;

const COMPOSER_PROJECTION = `{
  _id,
  name,
  birthYear,
  deathYear,
  "slug": slug.current,
  image
}`;

const COMPOSERS_BY_NAME_QUERY = defineQuery(`
*[
  ${COMPOSER_FILTER_CLAUSE}
]
| order(lower(name) asc)
[$start...$end]${COMPOSER_PROJECTION}
`);

const COMPOSERS_BY_SORT_KEY_QUERY = defineQuery(`
*[
  ${COMPOSER_FILTER_CLAUSE}
]
| order(lower(coalesce(sortKey, name)) asc, lower(name) asc)
[$start...$end]${COMPOSER_PROJECTION}
`);

const COMPOSERS_BY_BIRTH_YEAR_ASC_QUERY = defineQuery(`
*[
  ${COMPOSER_FILTER_CLAUSE}
]
| order(coalesce(birthYear, 999999) asc, lower(name) asc)
[$start...$end]${COMPOSER_PROJECTION}
`);

const COMPOSERS_BY_BIRTH_YEAR_DESC_QUERY = defineQuery(`
*[
  ${COMPOSER_FILTER_CLAUSE}
]
| order(coalesce(birthYear, -999999) desc, lower(name) asc)
[$start...$end]${COMPOSER_PROJECTION}
`);

const COMPOSERS_COUNT_QUERY = defineQuery(`
count(*[
  ${COMPOSER_FILTER_CLAUSE}
])
`);

export const metadata: Metadata = {
  title: "Composers",
  description:
    "Discover composers featured on TRPTK recordings, from early music to contemporary works.",
};

export default async function ComposersPage({
  searchParams,
}: {
  searchParams: Promise<{ page?: string; q?: string; sort?: string }>;
}) {
  const sp = await searchParams;

  const q = normalizeQuery(sp.q);
  const sort = normalizeSort(sp.sort);
  const page = clampInt(sp.page, 1, 1, 9999);

  const start = (page - 1) * PAGE_SIZE;
  const end = start + PAGE_SIZE;

  const qPattern = q ? `${groqLikeParam(q)}*` : "";

  const listQuery =
    sort === "sortKey"
      ? COMPOSERS_BY_SORT_KEY_QUERY
      : sort === "birthYearAsc"
        ? COMPOSERS_BY_BIRTH_YEAR_ASC_QUERY
        : sort === "birthYearDesc"
          ? COMPOSERS_BY_BIRTH_YEAR_DESC_QUERY
          : COMPOSERS_BY_NAME_QUERY;

  const [composers, total] = await Promise.all([
    sanity.fetch<ComposerCardData[]>(listQuery, { start, end, q, qPattern }),
    sanity.fetch<number>(COMPOSERS_COUNT_QUERY, { q, qPattern }),
  ]);

  const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE));
  const safePage = Math.min(page, totalPages);

  const buildHref = (nextPage: number) => {
    const params = new URLSearchParams();
    if (q) params.set("q", q);
    if (sort !== "sortKey") params.set("sort", sort);
    if (nextPage > 1) params.set("page", String(nextPage));
    const qs = params.toString();
    return qs ? `/composers?${qs}` : "/composers";
  };

  return (
    <main className="mx-auto my-auto max-w-300 px-6 py-12 font-silka md:px-8 md:py-16 2xl:max-w-400">
      <div className="mb-10">
        <AnimatedText text="Composers" as="h1" className="font-argesta text-3xl" />
        <p className="mt-2 text-base text-lightsec dark:text-darksec">
          {total ? `${total} composer(s)` : "No composers found."}
        </p>
      </div>

      <div className="mb-12">
        <SearchBar
          initialQuery={q}
          initialSort={sort}
          initialPage={safePage}
          defaultSort="sortKey"
          placeholder="Search composers…"
          sortOptions={SORT_OPTIONS}
          sortAriaLabel="Sort composers"
          sortMenuClassName="absolute right-0 z-20 mt-4 min-w-47 overflow-hidden rounded-2xl bg-lightbg shadow-lg ring-1 ring-lightline transition-colors duration-300 ease-in-out hover:ring-lightline-hover dark:bg-darkbg dark:ring-darkline dark:hover:ring-darkline-hover"
        />
      </div>

      <section className={CARD_GRID_CLASSES_4}>
        {composers.map((composer) => (
          <ArtistCard
            key={composer._id}
            name={composer.name}
            subtitle={formatYears(composer.birthYear, composer.deathYear)}
            image={composer.image}
            href={composer.slug ? `/composer/${composer.slug}` : "/composers/"}
            label="Composer"
          />
        ))}
      </section>

      {totalPages > 1 ? (
        <PaginationNav page={safePage} totalPages={totalPages} buildHref={buildHref} />
      ) : null}
    </main>
  );
}
