import { Search, SlidersHorizontal, X } from "lucide-react";
import { useQuery } from "@tanstack/react-query";
import { useMemo, useState } from "react";
import { useSearchParams } from "react-router-dom";
import { contentApi, directoriesApi } from "../shared/api/endpoints";
import { normalizeContentList, toList } from "../shared/api/normalize";
import { queryKeys } from "../shared/api/queryKeys";
import { Button } from "../shared/ui/Button";
import { MaterialCard } from "../shared/ui/MaterialCard";
import { EmptyState, ErrorState, Skeleton } from "../shared/ui/States";

const materialTypes = [
  ["news", "Новость"],
  ["article", "Статья"],
  ["research", "Исследование"],
  ["announcement", "Объявление"],
  ["video", "Видео"],
];

function normalizeCategories(payload) {
  return toList(payload).map((item) => {
    if (typeof item === "string") {
      return { id: item, name: item, value: item };
    }

    return {
      id: item.id ?? item.slug ?? item.name,
      name: item.name ?? item.title ?? item.label,
      value: item.slug ?? item.id ?? item.name,
    };
  });
}

export function MaterialsPage() {
  const [params, setParams] = useSearchParams();
  const [mobileFilters, setMobileFilters] = useState(false);
  const query = params.get("q") ?? "";
  const category = params.get("category") ?? "";
  const type = params.get("type") ?? "";
  const apiParams = { q: query, category, type };
  const { data: contentPayload, isLoading, isError, refetch } = useQuery({
    queryKey: queryKeys.content(apiParams),
    queryFn: () => contentApi.list(apiParams),
  });
  const { data: categoriesPayload } = useQuery({
    queryKey: queryKeys.categories,
    queryFn: directoriesApi.categories,
  });
  const pageMaterials = normalizeContentList(contentPayload);
  const pageCategories = normalizeCategories(categoriesPayload);

  const filtered = useMemo(
    () =>
      pageMaterials.filter((material) => {
        const tags = Array.isArray(material.tags) ? material.tags.join(" ") : "";
        const matchesQuery = `${material.title} ${material.excerpt} ${tags}`
          .toLowerCase()
          .includes(query.toLowerCase());
        return matchesQuery;
      }),
    [pageMaterials, query],
  );

  const update = (key, value) => {
    const next = new URLSearchParams(params);
    value ? next.set(key, value) : next.delete(key);
    setParams(next);
  };

  const filters = (
    <div className="grid gap-5">
      <label className="text-sm font-semibold">
        Категория
        <select
          value={category}
          onChange={(event) => update("category", event.target.value)}
          className="mt-2 w-full rounded-md border border-line bg-white px-3 py-2.5 text-ink outline-none focus:border-primary dark:bg-paper dark:[color-scheme:dark]"
        >
          <option value="">Все категории</option>
          {pageCategories.map((item) => (
            <option key={item.id} value={item.value}>
              {item.name}
            </option>
          ))}
        </select>
      </label>
      <label className="text-sm font-semibold">
        Тип материала
        <select
          value={type}
          onChange={(event) => update("type", event.target.value)}
          className="mt-2 w-full rounded-md border border-line bg-white px-3 py-2.5 text-ink outline-none focus:border-primary dark:bg-paper dark:[color-scheme:dark]"
        >
          <option value="">Все типы</option>
          {materialTypes.map(([value, label]) => (
            <option key={value} value={value}>{label}</option>
          ))}
        </select>
      </label>
      <Button variant="ghost" onClick={() => setParams({})} icon={<X className="size-4" />}>
        Сбросить фильтры
      </Button>
    </div>
  );

  return (
    <div className="page-shell py-10">
      <div className="border-b border-line pb-8">
        <p className="text-xs font-bold uppercase tracking-widest text-accent">Архив редакции</p>
        <h1 className="mt-3 font-serif text-4xl sm:text-5xl">Материалы</h1>
        <p className="mt-4 max-w-2xl leading-7 text-muted">
          Новости университета, исследования, истории людей и полезные объявления загружаются из backend.
        </p>
      </div>

      <form
        className="mt-8 flex gap-3"
        onSubmit={(event) => {
          event.preventDefault();
          const data = new FormData(event.currentTarget);
          update("q", String(data.get("q") ?? ""));
        }}
      >
        <label className="relative min-w-0 flex-1">
          <Search className="absolute left-4 top-1/2 size-5 -translate-y-1/2 text-muted" />
          <input
            name="q"
            defaultValue={query}
            placeholder="Название, автор, тема или тег"
            className="h-12 w-full rounded-md border border-line bg-surface pl-12 pr-4 outline-none focus:border-primary focus:ring-2 focus:ring-primary/15"
          />
        </label>
        <Button type="submit">Найти</Button>
        <Button
          className="lg:hidden"
          type="button"
          variant="secondary"
          icon={<SlidersHorizontal className="size-4" />}
          onClick={() => setMobileFilters((value) => !value)}
        >
          <span className="hidden sm:inline">Фильтры</span>
        </Button>
      </form>

      {mobileFilters && <div className="mt-4 rounded-lg border border-line bg-surface p-5 lg:hidden">{filters}</div>}

      <div className="mt-8 grid gap-8 lg:grid-cols-[minmax(13rem,1fr)_minmax(0,4fr)]">
        <aside className="hidden lg:block">
          <div className="sticky top-24 rounded-lg border border-line bg-surface p-5">
            <h2 className="mb-5 font-serif text-xl">Фильтры</h2>
            {filters}
          </div>
        </aside>
        <section>
          <div className="mb-5 flex items-center justify-between">
            <p className="text-sm text-muted">Найдено: {filtered.length}</p>
            <select className="rounded-md border border-line bg-surface px-3 py-2 text-sm dark:[color-scheme:dark]">
              <option>Сначала новые</option>
              <option>По популярности</option>
            </select>
          </div>
          {isLoading ? (
            <div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
              {[1, 2, 3, 4, 5, 6].map((item) => (
                <Skeleton key={item} className="h-80 w-full" />
              ))}
            </div>
          ) : isError ? (
            <ErrorState retry={refetch} />
          ) : filtered.length ? (
            <div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
              {filtered.map((material) => (
                <MaterialCard key={material.id} material={material} />
              ))}
            </div>
          ) : (
            <EmptyState title="Ничего не найдено" text="Попробуйте изменить запрос или убрать часть фильтров." />
          )}
        </section>
      </div>
    </div>
  );
}
