import { useEffect, useState } from "react";
import { NavLink } from "react-router-dom";
import { useTranslation } from "react-i18next";
import {
  BookMarked,
  Boxes,
  PanelLeft,
  PanelLeftClose,
  Search,
  Tags,
  Users,
} from "lucide-react";
import type { LucideIcon } from "lucide-react";

import { cn } from "@/lib/utils";
import { Tooltip } from "@/components/ui/tooltip";
import { useMediaQuery } from "@/lib/use-media-query";
import { useConfig } from "../config/config-context";

const STORAGE_KEY = "sidebar-collapsed";

type NavItem = {
  to: string;
  /** i18n key under `nav.*`. */
  label: string;
  Icon: LucideIcon;
};

const NAV_ITEMS: readonly NavItem[] = [
  { to: "/objects", label: "nav.objects", Icon: Boxes },
  { to: "/vocabularies", label: "nav.vocabularies", Icon: BookMarked },
  { to: "/authorities", label: "nav.authorities", Icon: Users },
  { to: "/search", label: "nav.search", Icon: Search },
  { to: "/fields", label: "nav.fields", Icon: Tags },
];

function readStored(): boolean {
  if (typeof window === "undefined") return false;
  return window.localStorage.getItem(STORAGE_KEY) === "true";
}

function navLinkClass(collapsed: boolean) {
  return ({ isActive }: { isActive: boolean }) =>
    cn(
      "flex items-center gap-2 rounded-md px-2 py-1 outline-none",
      "focus-visible:ring-3 focus-visible:ring-ring/50",
      collapsed && "justify-center",
      isActive && "bg-accent font-medium",
    );
}

export function Sidebar() {
  const { t } = useTranslation();
  const { app_name } = useConfig();
  const narrow = useMediaQuery("(max-width: 768px)");
  const [stored, setStored] = useState(readStored);

  // On narrow viewports the rail is always collapsed regardless of the stored
  // preference; the toggle only takes effect when wide.
  const collapsed = narrow || stored;

  useEffect(() => {
    if (typeof window !== "undefined") {
      window.localStorage.setItem(STORAGE_KEY, String(stored));
    }
  }, [stored]);

  const toggle = () => setStored((prev) => !prev);

  return (
    <aside
      className={cn(
        "flex shrink-0 flex-col border-r bg-muted p-3 transition-[width]",
        collapsed ? "w-14" : "w-44",
      )}
    >
      <div className="mb-4 flex items-center justify-between">
        {!collapsed && <span className="font-semibold">{app_name}</span>}
        <button
          type="button"
          onClick={toggle}
          disabled={narrow}
          aria-expanded={!collapsed}
          aria-label={t(collapsed ? "nav.expandSidebar" : "nav.collapseSidebar")}
          title={t(collapsed ? "nav.expandSidebar" : "nav.collapseSidebar")}
          className={cn(
            "flex items-center justify-center rounded-md p-1 outline-none",
            "hover:bg-accent focus-visible:ring-3 focus-visible:ring-ring/50",
            "disabled:pointer-events-none disabled:opacity-50",
          )}
        >
          {collapsed ? (
            <PanelLeft className="size-4" />
          ) : (
            <PanelLeftClose className="size-4" />
          )}
        </button>
      </div>
      <nav className="space-y-1 text-sm">
        {NAV_ITEMS.map(({ to, label, Icon }) => {
          const text = t(label);

          if (collapsed) {
            return (
              <Tooltip key={to} content={text} side="right">
                <NavLink
                  to={to}
                  aria-label={text}
                  title={text}
                  className={navLinkClass(true)}
                >
                  <Icon className="size-4" aria-hidden="true" />
                </NavLink>
              </Tooltip>
            );
          }

          return (
            <NavLink key={to} to={to} className={navLinkClass(false)}>
              <Icon className="size-4" aria-hidden="true" />
              <span>{text}</span>
            </NavLink>
          );
        })}
      </nav>
    </aside>
  );
}
