import { ChevronRight } from "lucide-react";
import { Link } from "react-router-dom";
import { useEffect, useRef, useState } from "react";
import { getJSON, itemsOrEmpty, type Category } from "../../api";
import { CategoryIcon } from "../../components/CategoryIcon";
import { FigmaBanner } from "../../components/FigmaBanner";
import {
  ComingSoonLatestUpdateRow,
  LatestUpdateRow,
} from "../../components/LatestUpdateRow";
import { RecommendedCard } from "../../components/RecommendedCard";
import { SectionHeader } from "../../components/SectionHeader";
import { langQuery, useI18n } from "../../i18n";
import { sourceLanguageQuery } from "../../i18nLanguages";
import { categoryCardLines } from "../../utils/categoryDisplay";
import {
  postToResource,
  type PostBackedResource,
} from "../../utils/postResourceAdapter";
import type { Post } from "../../types/post";

export function Home() {
  const { t, lang } = useI18n();
  const [cats, setCats] = useState<Category[]>([]);
  const [rec, setRec] = useState<PostBackedResource[]>([]);
  const [latest, setLatest] = useState<PostBackedResource[]>([]);
  const [err, setErr] = useState<string | null>(null);
  const recRowRef = useRef<HTMLDivElement>(null);
  const categoryRowRef = useRef<HTMLDivElement>(null);
  const [activeCategoryPage, setActiveCategoryPage] = useState(0);
  const [canScrollRec, setCanScrollRec] = useState(false);
  const [recScroll, setRecScroll] = useState({ ratio: 1, progress: 0 });

  useEffect(() => {
    const langParam = encodeURIComponent(langQuery(lang));
    const languageParam = encodeURIComponent(sourceLanguageQuery(lang));
    const catQ = `?lang=${langParam}`;
    const postQ = `?lang=${langParam}&language=${languageParam}`;
    Promise.all([
      getJSON<Category[]>(`/api/categories${catQ}`),
      getJSON<{ items: Post[] }>(`/api/posts/recommended${postQ}&limit=12`),
      getJSON<{ items: Post[] }>(`/api/posts/latest${postQ}&limit=8`),
    ])
      .then(([c, r, l]) => {
        setCats(itemsOrEmpty(c));
        setRec(
          itemsOrEmpty(r.items).map((post) =>
            postToResource(post, lang, itemsOrEmpty(c)),
          ),
        );
        setLatest(
          itemsOrEmpty(l.items).map((post) =>
            postToResource(post, lang, itemsOrEmpty(c)),
          ),
        );
      })
      .catch((e) => setErr(String(e)));
  }, [lang]);

  const iconKeyForResource = (r: PostBackedResource) =>
    cats.find((c) => c.id === r.categoryId)?.iconKey ?? "folder";

  const categoryPages: Category[][] = [];
  for (let index = 0; index < cats.length; index += 9) {
    categoryPages.push(cats.slice(index, index + 9));
  }

  useEffect(() => {
    const row = categoryRowRef.current;
    if (!row) return;

    const update = () => {
      const width = row.clientWidth || 1;
      const next = Math.round(row.scrollLeft / width);
      setActiveCategoryPage((prev) => (prev === next ? prev : next));
    };

    update();
    row.addEventListener("scroll", update, { passive: true });
    return () => row.removeEventListener("scroll", update);
  }, [cats.length]);

  useEffect(() => {
    setActiveCategoryPage(0);
    categoryRowRef.current?.scrollTo({ left: 0 });
  }, [lang]);

  useEffect(() => {
    const row = recRowRef.current;
    if (!row) {
      setCanScrollRec(false);
      return;
    }

    const update = () => {
      const overflow = row.scrollWidth > row.clientWidth + 1;
      setCanScrollRec(overflow);
      const ratio = overflow ? row.clientWidth / row.scrollWidth : 1;
      const maxScroll = Math.max(1, row.scrollWidth - row.clientWidth);
      const progress = overflow ? row.scrollLeft / maxScroll : 0;
      setRecScroll({
        ratio: Math.min(1, Math.max(0.15, ratio)),
        progress: Math.min(1, Math.max(0, progress)),
      });
    };

    update();
    const resizeObserver = new ResizeObserver(update);
    resizeObserver.observe(row);
    row.addEventListener("scroll", update, { passive: true });
    return () => {
      resizeObserver.disconnect();
      row.removeEventListener("scroll", update);
    };
  }, [rec.length]);

  const scrollRec = (dir: 1 | -1) => {
    recRowRef.current?.scrollBy({ left: dir * 280, behavior: "smooth" });
  };

  const latestPlaceholderCount = Math.max(0, 5 - latest.length);

  if (err) {
    return (
      <div className="mt-6 rounded-xl border border-red-900 bg-red-950/40 p-4 text-red-200 md:mt-0">
        {err}
      </div>
    );
  }

  return (
    <div className="space-y-[30px] pb-10 md:space-y-10 md:pb-16 xl:space-y-[34px]">
      <section className="-mt-6 md:mt-0">
        <FigmaBanner />
      </section>

      <section id="categories" className="scroll-mt-24">
        <SectionHeader
          title={t("categorySection")}
          viewAllTo="/browse"
          viewAllLabel={t("viewAll")}
        />

        <div className="md:hidden">
          <div
            ref={categoryRowRef}
            className="flex snap-x snap-mandatory overflow-x-auto overflow-y-hidden scroll-smooth [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
            aria-label={t("categorySection")}
          >
            {categoryPages.map((page, pageIndex) => (
              <div
                key={`category-page-${pageIndex}`}
                className="grid w-full shrink-0 snap-start grid-cols-3 gap-2"
              >
                {page.map((c) => (
                  <Link
                    key={c.id}
                    to={`/category/${c.slug}`}
                    className="group flex h-[88px] min-w-0 flex-col items-center justify-center gap-2 rounded-xl bg-[#1D1E23] px-4 py-3 text-center transition hover:bg-[#252630] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
                  >
                    <CategoryIcon
                      iconKey={c.iconKey}
                      categorySlug={c.slug}
                      className="h-9 w-9 shrink-0 text-ark-gold"
                    />
                    <div className="w-full truncate text-[13px] font-medium leading-[19.5px] text-white">
                      {c.name}
                    </div>
                  </Link>
                ))}
              </div>
            ))}
          </div>

          {categoryPages.length > 1 ? (
            <div
              className="flex h-[30px] items-center justify-center gap-1.5"
              aria-label="Category pagination"
            >
              {categoryPages.map((_, index) => (
                <button
                  key={`category-dot-${index}`}
                  type="button"
                  aria-label={`Go to category page ${index + 1}`}
                  aria-current={activeCategoryPage === index}
                  onClick={() => {
                    const row = categoryRowRef.current;
                    if (!row) return;
                    row.scrollTo({
                      left: row.clientWidth * index,
                      behavior: "smooth",
                    });
                    setActiveCategoryPage(index);
                  }}
                  className={`h-1.5 rounded-full transition-all ${
                    activeCategoryPage === index
                      ? "w-6 bg-ark-gold"
                      : "w-1.5 bg-[#7C7C7C]"
                  }`}
                />
              ))}
            </div>
          ) : null}
        </div>

        <div className="mt-7 hidden grid-cols-3 gap-3 min-[440px]:gap-3.5 md:grid md:grid-cols-5 md:gap-3 lg:grid-cols-6 xl:grid-cols-7 xl:gap-4">
          {cats.map((c) => {
            const { line1, line2 } = categoryCardLines(c.name);
            return (
              <Link
                key={c.id}
                to={`/category/${c.slug}`}
                className="group flex min-h-[111px] min-w-0 flex-col items-center justify-center gap-3 rounded-xl border border-ark-line bg-ark-panel px-2.5 py-4 text-center transition hover:border-ark-gold/55 hover:shadow-[0_0_0_1px_rgba(238,183,38,0.12)] md:min-h-24 md:flex-row md:justify-start md:gap-4 md:px-5 md:text-left"
              >
                <CategoryIcon
                  iconKey={c.iconKey}
                  categorySlug={c.slug}
                  className="h-9 w-9 shrink-0 text-ark-gold md:h-9 md:w-9"
                />
                <div className="min-w-0">
                  <div className="text-[15px] font-bold leading-snug text-white line-clamp-2 md:text-sm">
                    {line1}
                  </div>
                  {line2 ? (
                    <div className="mt-0.5 text-[15px] font-bold leading-snug text-white line-clamp-2 md:text-sm">
                      {line2}
                    </div>
                  ) : null}
                </div>
              </Link>
            );
          })}
        </div>
      </section>

      <section>
        <SectionHeader
          title={t("officialSection")}
          viewAllTo="/browse?sort=recommended"
          viewAllLabel={t("viewAll")}
        />
        <div className="relative mt-7">
          <div
            ref={recRowRef}
            className="flex gap-3 overflow-x-auto pb-5 pr-0 scroll-smooth snap-x snap-mandatory [-ms-overflow-style:none] [scrollbar-width:none] md:gap-4 [&::-webkit-scrollbar]:hidden"
          >
            {rec.map((r, index) => (
              <div key={r.id} className="snap-start">
                <RecommendedCard r={r} visualIndex={index} />
              </div>
            ))}
          </div>
          <div className="h-1 overflow-hidden rounded-full bg-black/80 md:hidden">
            <div
              className="h-full rounded-full bg-ark-gold transition-transform duration-300 ease-out"
              style={{
                width: `${Math.round(recScroll.ratio * 100)}%`,
                transform: `translateX(${recScroll.progress * (100 / recScroll.ratio - 100)}%)`,
              }}
            />
          </div>
          {canScrollRec ? (
            <button
              type="button"
              onClick={() => scrollRec(1)}
              className="absolute right-0 top-[45%] hidden h-9 w-9 -translate-y-1/2 items-center justify-center rounded-lg border border-ark-line bg-[#292a31]/95 text-neutral-200 shadow-lg backdrop-blur transition hover:border-ark-gold hover:text-ark-gold md:flex"
              aria-label={t("viewAll")}
            >
              <ChevronRight className="h-5 w-5" />
            </button>
          ) : null}
        </div>
      </section>

      <section>
        <SectionHeader
          title={t("latestSection")}
          viewAllTo="/browse?sort=latest"
          viewAllLabel={t("viewAll")}
        />
        <div className="mt-7 grid gap-3 min-[576px]:grid-cols-2 md:gap-4 lg:grid-cols-3 xl:grid-cols-5">
          {latest.map((r) => (
            <LatestUpdateRow key={r.id} r={r} iconKey={iconKeyForResource(r)} />
          ))}
          {Array.from({ length: latestPlaceholderCount }).map((_, index) => (
            <ComingSoonLatestUpdateRow
              key={`latest-coming-soon-${index}`}
              index={latest.length + index}
            />
          ))}
        </div>
      </section>
    </div>
  );
}
