"use client";

import { ChevronRight, Flame, Rows3, Search, Truck } from "lucide-react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type { WebsiteMenu } from "@/lib/menu-db";
import { DishCard } from "./dish-card";

export function MenuBrowser({ deliveryOnly = false, menu, adminMode = false }: { deliveryOnly?: boolean; menu: WebsiteMenu; adminMode?: boolean }) {
  const { categories: menuCategories, items: menuItems } = menu;
  const [category, setCategory] = useState("all");
  const [query, setQuery] = useState("");
  const [hitsOnly, setHitsOnly] = useState(false);
  const [deliveryFilter, setDeliveryFilter] = useState(deliveryOnly);
  const [compact, setCompact] = useState(false);
  const tabsRef = useRef<HTMLDivElement | null>(null);
  const [tabsCanScroll, setTabsCanScroll] = useState(false);

  const updateTabsScrollState = useCallback(() => {
    const tabs = tabsRef.current;
    if (!tabs) return;
    setTabsCanScroll(tabs.scrollWidth - tabs.clientWidth - tabs.scrollLeft > 4);
  }, []);

  useEffect(() => {
    updateTabsScrollState();
    const tabs = tabsRef.current;
    if (!tabs) return;

    const resizeObserver = new ResizeObserver(updateTabsScrollState);
    resizeObserver.observe(tabs);
    tabs.addEventListener("scroll", updateTabsScrollState, { passive: true });
    return () => {
      resizeObserver.disconnect();
      tabs.removeEventListener("scroll", updateTabsScrollState);
    };
  }, [menuCategories, menuItems, updateTabsScrollState]);

  const scrollTabs = () => {
    const tabs = tabsRef.current;
    if (!tabs) return;
    tabs.scrollBy({ left: Math.max(180, tabs.clientWidth * 0.75), behavior: "smooth" });
  };

  const visible = useMemo(
    () =>
      menuItems.filter((dish) => {
        if (deliveryFilter && (!dish.deliveryAvailable || dish.alcohol)) return false;
        if (category !== "all" && dish.categorySlug !== category) return false;
        if (hitsOnly && !(dish.hit || dish.isHit)) return false;
        if (query && !dish.name.toLowerCase().includes(query.toLowerCase())) return false;
        return true;
      }),
    [category, deliveryFilter, hitsOnly, query, menuItems]
  );

  const visibleCategories = menuCategories.filter((item) => item.slug !== "bar" && menuItems.some((dish) => dish.categorySlug === item.slug));
  const grouped = visibleCategories
    .map((item) => ({ category: item, dishes: visible.filter((dish) => dish.categorySlug === item.slug) }))
    .filter((group) => group.dishes.length);

  return (
    <div className="grid gap-6">
      <div className="menu-toolbar sticky top-14 z-20 w-full min-w-0 overflow-hidden border-y border-white/10 py-3">
        <div className="flex min-w-0 max-w-full flex-col gap-3">
          <div className="relative min-w-0">
            <div ref={tabsRef} className="no-scrollbar flex max-w-full min-w-0 gap-2 overflow-x-auto pb-1 pr-1">
            <button
              className={`button shrink-0 ${category === "all" ? "button-primary" : "button-secondary"} whitespace-nowrap`}
              onClick={() => {
                setCategory("all");
                requestAnimationFrame(() => document.getElementById("menu-top")?.scrollIntoView({ behavior: "smooth", block: "start" }));
              }}
            >
              Все
            </button>
            {visibleCategories.map((item) => (
              <button
                key={item.slug}
                className={`button shrink-0 ${category === item.slug ? "button-primary" : "button-secondary"} whitespace-nowrap`}
                onClick={() => setCategory(item.slug)}
              >
                {item.title}
              </button>
            ))}
            </div>
            {tabsCanScroll ? (
              <button type="button" className="menu-tabs-next" onClick={scrollTabs} aria-label="Прокрутить категории вправо">
                <ChevronRight size={20} strokeWidth={2.5} />
              </button>
            ) : null}
          </div>
          <div className="flex min-w-0 max-w-full gap-2">
            <label className="relative block min-w-0 flex-1">
              <Search className="pointer-events-none absolute left-3 top-1/2 z-[1] -translate-y-1/2 text-kiln-milk/50" size={18} />
              <input className="input search-input" placeholder="Поиск по названию" value={query} onChange={(event) => setQuery(event.target.value)} />
            </label>
            <button type="button" className={`icon-button shrink-0 ${hitsOnly ? "is-active" : ""}`} onClick={() => setHitsOnly((value) => !value)} aria-label="Показывать только хиты" aria-pressed={hitsOnly} data-tooltip="Только хиты"><Flame size={19} /></button>
            {!deliveryOnly ? (
              <button type="button" className={`icon-button shrink-0 ${deliveryFilter ? "is-active" : ""}`} onClick={() => setDeliveryFilter((value) => !value)} aria-label="Доступно для доставки" aria-pressed={deliveryFilter} data-tooltip="Доставка"><Truck size={19} /></button>
            ) : null}
            <button type="button" className={`icon-button shrink-0 ${compact ? "is-active" : ""}`} onClick={() => setCompact((value) => !value)} aria-label="Компактный вид" aria-pressed={compact} data-tooltip="Компактный вид"><Rows3 size={19} /></button>
          </div>
        </div>
      </div>
      <div className="grid gap-10">
        {grouped.map((group) => (
          <section key={group.category.slug} id={`cat-${group.category.slug}`} className="scroll-mt-40">
            <div className="mb-4">
              <h2 className="text-3xl">{group.category.title}</h2>
              <p className="mt-2 muted">{group.category.description}</p>
            </div>
            <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
              {group.dishes.map((dish, index) => (
                <DishCard key={dish.id} dish={dish} compact={compact} priority={group === grouped[0] && index === 0} adminMode={adminMode} />
              ))}
            </div>
          </section>
        ))}
      </div>
      {!visible.length ? <p className="muted">По этим условиям блюд нет.</p> : null}
    </div>
  );
}
