import {
  Check,
  ChevronDown,
  Globe,
  Menu,
  Search as SearchIcon,
  X,
} from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { Link, Outlet, useLocation, useNavigate } from "react-router-dom";
import { ArkLogoMark } from "../components/ArkLogoMark";
import { useI18n, type Lang } from "../i18n";
import { LANG_OPTIONS } from "../i18nLanguages";
import { adminUiPrefix } from "../adminPaths";

type PublicNavWhich =
  | "home"
  | "browseAll"
  | "categories"
  | "browseLatest"
  | "browseRecommended"
  | "browsePopular"
  | "wallet"
  | "about";

function navIsActive(
  pathname: string,
  search: string,
  hash: string,
  which: PublicNavWhich,
): boolean {
  const sp = new URLSearchParams(search);
  switch (which) {
    case "home":
      return pathname === "/";
    case "browseAll":
      return pathname === "/browse" && !sp.has("sort");
    case "categories":
      return pathname === "/" && hash === "#categories";
    case "browseLatest":
      return pathname === "/browse" && sp.get("sort") === "latest";
    case "browseRecommended":
      return pathname === "/browse" && sp.get("sort") === "recommended";
    case "browsePopular":
      return pathname === "/browse" && sp.get("sort") === "popular";
    case "wallet":
      return pathname === "/wallet";
    case "about":
      return pathname === "/about";
    default:
      return false;
  }
}

function navClassName(active: boolean) {
  return [
    "shrink-0 rounded-sm px-2 py-2 text-[13px] font-medium leading-none whitespace-nowrap no-underline outline-none transition-colors",
    "focus-visible:ring-2 focus-visible:ring-ark-gold/90 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg",
    active
      ? "text-ark-gold visited:text-ark-gold"
      : "text-[#d7d7dc] visited:text-[#d7d7dc] hover:text-ark-gold",
  ].join(" ");
}

type LanguageDropdownProps = {
  lang: Lang;
  setLang: (lang: Lang) => void;
  ariaLabel: string;
  className?: string;
};

function LanguageDropdown({
  lang,
  setLang,
  ariaLabel,
  className = "",
}: LanguageDropdownProps) {
  const [open, setOpen] = useState(false);
  const rootRef = useRef<HTMLDivElement>(null);
  const selected = LANG_OPTIONS.find((option) => option.code === lang);

  useEffect(() => {
    if (!open) return;

    const closeOnOutside = (event: MouseEvent | TouchEvent) => {
      if (!rootRef.current?.contains(event.target as Node)) setOpen(false);
    };
    const closeOnEscape = (event: KeyboardEvent) => {
      if (event.key === "Escape") setOpen(false);
    };

    document.addEventListener("mousedown", closeOnOutside);
    document.addEventListener("touchstart", closeOnOutside);
    window.addEventListener("keydown", closeOnEscape);
    return () => {
      document.removeEventListener("mousedown", closeOnOutside);
      document.removeEventListener("touchstart", closeOnOutside);
      window.removeEventListener("keydown", closeOnEscape);
    };
  }, [open]);

  return (
    <div ref={rootRef} className={`relative ${className}`}>
      <button
        type="button"
        onClick={() => setOpen((value) => !value)}
        className="flex h-full w-full items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] px-3 py-2 text-sm text-neutral-200 shadow-inner outline-none transition hover:border-ark-gold/50 focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
        aria-label={ariaLabel}
        aria-haspopup="listbox"
        aria-expanded={open}
      >
        <Globe size={16} className="shrink-0 text-ark-gold/80" aria-hidden />
        <span className="min-w-0 flex-1 truncate text-left">
          {selected?.label ?? lang}
        </span>
        <ChevronDown
          size={16}
          className={`shrink-0 text-neutral-400 transition ${
            open ? "rotate-180 text-ark-gold" : ""
          }`}
          aria-hidden
        />
      </button>

      {open ? (
        <div
          className="absolute left-0 right-0 top-[calc(100%+0.5rem)] z-50 overflow-hidden rounded-2xl border border-white/10 bg-[#1c1c21]/95 p-1.5 shadow-2xl shadow-black/70 ring-1 ring-ark-line/80 backdrop-blur-xl"
          role="listbox"
          aria-label={ariaLabel}
        >
          {LANG_OPTIONS.map((option) => {
            const active = option.code === lang;
            return (
              <button
                key={option.code}
                type="button"
                role="option"
                aria-selected={active}
                onClick={() => {
                  setLang(option.code as Lang);
                  setOpen(false);
                }}
                className={`flex w-full items-center gap-2 rounded-xl px-3 py-2 text-left text-sm transition ${
                  active
                    ? "bg-ark-gold/10 text-ark-gold2"
                    : "text-neutral-200 hover:bg-white/10 hover:text-white"
                }`}
              >
                <span className="flex h-4 w-4 shrink-0 items-center justify-center">
                  {active ? (
                    <Check className="h-4 w-4" strokeWidth={2.4} />
                  ) : null}
                </span>
                <span className="truncate font-medium">{option.label}</span>
              </button>
            );
          })}
        </div>
      ) : null}
    </div>
  );
}

export function PublicLayout() {
  const { t, lang, setLang } = useI18n();
  const { pathname, search, hash } = useLocation();
  const [open, setOpen] = useState(false);
  const [q, setQ] = useState("");
  const nav = useNavigate();

  const na = (which: PublicNavWhich) =>
    navIsActive(pathname, search, hash, which);

  const goSearch = () => {
    const s = q.trim();
    if (!s) return;
    nav(`/search?q=${encodeURIComponent(s)}`);
    setOpen(false);
  };

  return (
    <div className="min-h-full flex flex-col pb-20 md:pb-0">
      <header className="sticky top-0 z-40 border-b border-ark-line bg-ark-nav/98 backdrop-blur-md">
        <div className="mx-auto max-w-[1280px] px-4 py-[15px] min-[440px]:px-5 sm:px-6 md:px-9 xl:px-0">
          {/* Single row (md+): logo | scrollable nav (左對齊，可橫向滑動) | 搜尋 + 語言 */}
          <div className="flex h-10 items-center gap-2 min-[1200px]:gap-0 lg:gap-4">
            <Link
              to="/"
              className="flex min-w-0 shrink-0 items-center gap-2.5 rounded-sm text-xl font-bold tracking-wide text-ark-gold outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
            >
              <ArkLogoMark className="h-10 w-10 shrink-0" />
              <span className="max-w-[8rem] truncate text-ark-gold sm:inline">
                {t("brand")}
              </span>
            </Link>

            <nav
              className="header-nav-scroll hidden min-w-0 flex-1 items-center justify-center gap-4 overflow-x-auto overflow-y-hidden py-1 min-[1200px]:flex lg:gap-5"
              aria-label={t("mainNav")}
            >
              <Link
                to="/"
                className={navClassName(na("home"))}
                aria-current={na("home") ? "page" : undefined}
              >
                {t("home")}
              </Link>
              <Link
                to="/browse"
                className={navClassName(na("browseAll"))}
                aria-current={na("browseAll") ? "page" : undefined}
              >
                {t("all")}
              </Link>
              <Link
                to="/#categories"
                className={navClassName(na("categories"))}
                aria-current={na("categories") ? "page" : undefined}
              >
                {t("categories")}
              </Link>
              <Link
                to="/browse?sort=latest"
                className={navClassName(na("browseLatest"))}
                aria-current={na("browseLatest") ? "page" : undefined}
              >
                {t("latest")}
              </Link>
              <Link
                to="/browse?sort=recommended"
                className={navClassName(na("browseRecommended"))}
                aria-current={na("browseRecommended") ? "page" : undefined}
              >
                {t("official")}
              </Link>
              <Link
                to="/browse?sort=popular"
                className={navClassName(na("browsePopular"))}
                aria-current={na("browsePopular") ? "page" : undefined}
              >
                {t("popular")}
              </Link>
              <Link
                to="/wallet"
                className={navClassName(na("wallet"))}
                aria-current={na("wallet") ? "page" : undefined}
              >
                {t("wallet")}
              </Link>
            </nav>

            <div className="flex min-w-0 flex-1 items-center justify-end gap-2 min-[1200px]:flex-none">
              <div className="hidden h-10 min-w-0 flex-1 items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] py-2 pl-3 pr-3 shadow-inner md:flex min-[1200px]:w-44 min-[1200px]:flex-none lg:pr-4 xl:w-52">
                <SearchIcon size={16} className="shrink-0 text-[#c6c7cf]" />
                <input
                  value={q}
                  onChange={(e) => setQ(e.target.value)}
                  onKeyDown={(e) => e.key === "Enter" && goSearch()}
                  placeholder={t("searchPlaceholder")}
                  className="min-w-0 flex-1 rounded-md bg-transparent text-sm text-neutral-200 outline-none placeholder:text-[#777985] focus-visible:ring-2 focus-visible:ring-ark-gold/60 focus-visible:ring-offset-2 focus-visible:ring-offset-[#1a1b20]"
                />
              </div>
              <LanguageDropdown
                lang={lang}
                setLang={setLang}
                ariaLabel={t("langLabel")}
                className="hidden h-10 w-36 md:block lg:w-40"
              />
              <button
                type="button"
                className="inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-ark-line bg-[#1a1b20] text-neutral-200 outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg min-[1200px]:hidden"
                onClick={() => setOpen((v) => !v)}
                aria-label="menu"
              >
                {open ? <X size={18} /> : <Menu size={18} />}
              </button>
            </div>
          </div>
        </div>

        {open ? (
          <div className="grid gap-2 border-t border-ark-line bg-ark-nav px-4 py-3 min-[440px]:px-5 sm:px-6 md:px-9 min-[1200px]:hidden">
            <div className="mb-1 flex items-center gap-2 rounded-full border border-ark-line bg-[#1a1b20] px-3 py-2">
              <SearchIcon size={16} className="shrink-0 text-[#c6c7cf]" />
              <input
                value={q}
                onChange={(e) => setQ(e.target.value)}
                onKeyDown={(e) => e.key === "Enter" && goSearch()}
                placeholder={t("searchPlaceholder")}
                className="flex-1 bg-transparent text-sm outline-none placeholder:text-[#777985]"
              />
            </div>
            <LanguageDropdown
              lang={lang}
              setLang={setLang}
              ariaLabel={t("langLabel")}
              className="mb-1"
            />
            <Link
              to="/"
              className={navClassName(na("home"))}
              aria-current={na("home") ? "page" : undefined}
              onClick={() => setOpen(false)}
            >
              {t("home")}
            </Link>
            <Link
              to="/browse"
              className={navClassName(na("browseAll"))}
              aria-current={na("browseAll") ? "page" : undefined}
              onClick={() => setOpen(false)}
            >
              {t("all")}
            </Link>
            <Link
              to="/#categories"
              className={navClassName(na("categories"))}
              aria-current={na("categories") ? "page" : undefined}
              onClick={() => setOpen(false)}
            >
              {t("categories")}
            </Link>
            <Link
              to="/browse?sort=latest"
              className={navClassName(na("browseLatest"))}
              aria-current={na("browseLatest") ? "page" : undefined}
              onClick={() => setOpen(false)}
            >
              {t("latest")}
            </Link>
            <Link
              to="/browse?sort=recommended"
              className={navClassName(na("browseRecommended"))}
              aria-current={na("browseRecommended") ? "page" : undefined}
              onClick={() => setOpen(false)}
            >
              {t("official")}
            </Link>
            <Link
              to="/browse?sort=popular"
              className={navClassName(na("browsePopular"))}
              aria-current={na("browsePopular") ? "page" : undefined}
              onClick={() => setOpen(false)}
            >
              {t("popular")}
            </Link>
            <Link
              to="/wallet"
              className={navClassName(na("wallet"))}
              aria-current={na("wallet") ? "page" : undefined}
              onClick={() => setOpen(false)}
            >
              {t("wallet")}
            </Link>
            <Link
              to="/about"
              className={navClassName(na("about"))}
              aria-current={na("about") ? "page" : undefined}
              onClick={() => setOpen(false)}
            >
              {t("footerAbout")}
            </Link>
          </div>
        ) : null}
      </header>

      <main className="mx-auto w-full max-w-[1280px] flex-1 px-4 py-6 min-[440px]:px-5 sm:px-6 md:px-9 md:py-10 xl:px-0">
        <Outlet />
      </main>

      <footer className="mt-auto border-t border-ark-line bg-ark-nav/90 mb-20 md:mb-0">
        <div className="mx-auto flex max-w-[1280px] flex-wrap gap-x-6 gap-y-2 px-4 py-6 text-sm text-neutral-400 min-[440px]:px-5 sm:px-6 md:px-9 xl:px-0">
          <Link
            to="/about"
            className="rounded-sm outline-none hover:text-ark-gold2 focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
          >
            {t("footerAbout")}
          </Link>
          <Link
            to="/wallet"
            className="rounded-sm outline-none hover:text-ark-gold2 focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
          >
            {t("profile")}
          </Link>
          {import.meta.env.VITE_DISABLE_ADMIN !== "true" ? (
            <Link
              to={`${adminUiPrefix}/login`}
              className="rounded-sm outline-none hover:text-ark-gold2 focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg"
            >
              {t("footerAdminLogin")}
            </Link>
          ) : null}
        </div>
      </footer>

      <nav className="md:hidden fixed bottom-0 inset-x-0 z-40 border-t border-ark-line bg-ark-nav/95 backdrop-blur">
        <div className="grid grid-cols-4 gap-1 px-1 py-2 text-center text-[11px]">
          <BottomNavIcon
            to="/"
            label={t("home")}
            icon="home"
            active={pathname === "/"}
          />
          <BottomNavIcon
            to="/browse"
            label={t("all")}
            icon="document"
            active={
              pathname === "/browse" && !new URLSearchParams(search).get("sort")
            }
          />
          <BottomNavIcon
            to="/wallet"
            label={t("wallet")}
            icon="profile"
            active={pathname === "/wallet"}
          />
          <BottomNavIcon
            to="/browse?sort=latest"
            label={t("latest")}
            icon="update"
            active={
              pathname === "/browse" &&
              new URLSearchParams(search).get("sort") === "latest"
            }
          />
        </div>
      </nav>
    </div>
  );
}

const NAVBAR_ICON_BASE = "/assets/ark-library/navbar";

function BottomNavIcon({
  to,
  label,
  icon,
  active,
}: {
  to: string;
  label: string;
  icon: "home" | "document" | "profile" | "update";
  active: boolean;
}) {
  const src = active
    ? `${NAVBAR_ICON_BASE}/${icon}-active.svg`
    : `${NAVBAR_ICON_BASE}/${icon}-inactive.svg`;
  return (
    <Link
      to={to}
      className={[
        "flex flex-col items-center gap-1 rounded-lg py-1 outline-none focus-visible:ring-2 focus-visible:ring-ark-gold/80 focus-visible:ring-offset-2 focus-visible:ring-offset-ark-bg",
        active ? "text-ark-gold" : "text-neutral-400",
      ].join(" ")}
    >
      <img
        src={src}
        alt=""
        className={[
          "mx-auto h-7 w-7 object-contain",
          active ? "opacity-100" : "opacity-55",
        ].join(" ")}
        width={28}
        height={28}
        loading="lazy"
        decoding="async"
      />
      <span className="leading-tight">{label}</span>
    </Link>
  );
}
