import { PanelLeftClose, PanelLeftOpen, Settings } from "lucide-react";
import { NavLink, useLocation } from "react-router";
import { useEffect, useMemo, useState, type MouseEvent } from "react";
import type { AuthInfo, PlatformNavItem } from "../types";
import { hasAnyScope, hasScope } from "../utils/permissions";
import { usePlatformLanguage } from "../i18n/LanguageContext";
import { useGuardedNavigate } from "../components/UnsavedChangesGuard";

const MODULE_NAV_STORAGE_KEY = "govoplan.lastModuleNav";
const RAIL_EXPANDED_STORAGE_KEY = "govoplan.iconRailExpanded";

function visibleNavItems(auth: AuthInfo | null | undefined, navItems: PlatformNavItem[]): PlatformNavItem[] {
  return [...navItems].
  sort((left, right) => (left.order ?? 100) - (right.order ?? 100)).
  filter((item) => {
    if (item.allOf?.length && !item.allOf.every((scope) => hasScope(auth, scope))) return false;
    if (item.anyOf?.length && !hasAnyScope(auth, item.anyOf)) return false;
    return true;
  });
}

export default function IconRail({
  compact = false,
  auth = null,
  navItems = []
}: {compact?: boolean;auth?: AuthInfo | null;navItems?: PlatformNavItem[];}) {
  const location = useLocation();
  const items = visibleNavItems(auth, navItems);
  const [rememberedTargets, setRememberedTargets] = useState<Record<string, string>>(() => loadRememberedTargets());
  const [expanded, setExpanded] = useState(() => loadRailExpanded());
  const topLevelItems = useMemo(() => items.map((item) => item.to), [items]);
  const { translateText } = usePlatformLanguage();
  const navigate = useGuardedNavigate();

  useEffect(() => {
    const currentRoot = topLevelItems.find((root) => modulePathActive(location.pathname, root));
    if (!currentRoot || location.pathname === currentRoot) return;
    const target = `${location.pathname}${location.search}${location.hash}`;
    setRememberedTargets((current) => {
      if (current[currentRoot] === target) return current;
      const next = { ...current, [currentRoot]: target };
      saveRememberedTargets(next);
      return next;
    });
  }, [location.hash, location.pathname, location.search, topLevelItems]);

  function toggleExpanded() {
    setExpanded((current) => {
      const next = !current;
      saveRailExpanded(next);
      return next;
    });
  }

  function handleNavClick(event: MouseEvent<HTMLAnchorElement>, target: string) {
    if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) return;
    event.preventDefault();
    navigate(target);
  }

  const railExpanded = !compact && expanded;

  return (
    <aside className={`icon-rail ${compact ? "compact" : ""} ${railExpanded ? "expanded" : ""}`}>
      <div className="icon-rail-header">
        <div className="brand-mark" title="i18n:govoplan-core.govoplan.a84c0a85">i18n:govoplan-core.g.a36a6718</div>
      </div>

      {!compact &&
      <>
          <nav className="icon-nav">
            {items.map(({ to, label, icon: Icon }) => {
            const target = rememberedTargets[to] ?? to;
            const active = modulePathActive(location.pathname, to);
            const renderedLabel = translateText(label);
            return (
              <NavLink key={to} to={target} className={`icon-nav-item ${active ? "active" : ""}`} title={renderedLabel} onClick={(event) => handleNavClick(event, target)}>
                  {Icon ? <Icon size={20} /> : <span className="icon-nav-fallback">{renderedLabel.slice(0, 1)}</span>}
                  <span className="icon-nav-label">{renderedLabel}</span>
                </NavLink>);

          })}
          </nav>
          <div className="icon-rail-bottom">
            <NavLink to="/settings" className={({ isActive }) => `icon-nav-item ${isActive ? "active" : ""}`} title={translateText("i18n:govoplan-core.settings.c7f73bb5")} onClick={(event) => handleNavClick(event, "/settings")}>
              <Settings size={20} />
              <span className="icon-nav-label">{translateText("i18n:govoplan-core.settings.c7f73bb5")}</span>
            </NavLink>
            <button
              type="button"
              className="icon-nav-item icon-rail-toggle"
              aria-label={railExpanded ? "Collapse navigation" : "Expand navigation"}
              title={railExpanded ? "Collapse navigation" : "Expand navigation"}
              onClick={toggleExpanded}>
              {railExpanded ? <PanelLeftClose size={20} aria-hidden="true" /> : <PanelLeftOpen size={20} aria-hidden="true" />}
              <span className="icon-nav-label">{railExpanded ? "Collapse" : "Expand"}</span>
            </button>
          </div>
        </>
      }
    </aside>);

}

function modulePathActive(pathname: string, root: string): boolean {
  if (root === "/") return pathname === "/";
  return pathname === root || pathname.startsWith(`${root}/`);
}

function loadRememberedTargets(): Record<string, string> {
  if (typeof window === "undefined") return {};
  try {
    const raw = window.localStorage.getItem(MODULE_NAV_STORAGE_KEY);
    const parsed = raw ? JSON.parse(raw) : {};
    if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
    return Object.fromEntries(
      Object.entries(parsed).filter((entry): entry is [string, string] => {
        const [root, target] = entry;
        return typeof root === "string" && typeof target === "string" && root.startsWith("/") && target.startsWith(`${root}/`);
      })
    );
  } catch {
    return {};
  }
}

function saveRememberedTargets(targets: Record<string, string>): void {
  if (typeof window === "undefined") return;
  try {
    window.localStorage.setItem(MODULE_NAV_STORAGE_KEY, JSON.stringify(targets));
  } catch {
    // Remembered navigation is a convenience only.
  }}

function loadRailExpanded(): boolean {
  if (typeof window === "undefined") return false;
  try {
    return window.localStorage.getItem(RAIL_EXPANDED_STORAGE_KEY) === "true";
  } catch {
    return false;
  }
}

function saveRailExpanded(expanded: boolean): void {
  if (typeof window === "undefined") return;
  try {
    window.localStorage.setItem(RAIL_EXPANDED_STORAGE_KEY, expanded ? "true" : "false");
  } catch {
    // Rail width is a presentation preference only.
  }
}
