"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { ChevronDown, ChevronLeft, ChevronRight } from "lucide-react";
import { useTranslations } from "next-intl";
import { Link, usePathname } from "@/i18n/routing";
import { canSeeNavGroup, canSeeNavItem } from "@/lib/auth-permissions";
import { permissionsOf } from "@/lib/permissions";
import {
  NAV_GROUPS,
  NAV_GROUPS_STORAGE_KEY,
  findNavGroupForPath,
  type NavGroupDef,
  type NavGroupId,
  type NavItemDef,
} from "@/lib/sidebar-nav";
import { useAuthStore } from "@/lib/stores/auth.store";
import { cn } from "@/lib/utils";

type OpenGroupsState = Partial<Record<NavGroupId, boolean>>;

const SIDEBAR_COLLAPSED_STORAGE_KEY = "meezi.sidebar.collapsed";

function readStoredCollapsed(): boolean {
  if (typeof window === "undefined") return false;
  try {
    return localStorage.getItem(SIDEBAR_COLLAPSED_STORAGE_KEY) === "1";
  } catch {
    return false;
  }
}

function readStoredOpenGroups(): OpenGroupsState {
  if (typeof window === "undefined") return {};
  try {
    const raw = localStorage.getItem(NAV_GROUPS_STORAGE_KEY);
    if (!raw) return {};
    return JSON.parse(raw) as OpenGroupsState;
  } catch {
    return {};
  }
}

function buildDefaultOpenGroups(): OpenGroupsState {
  const stored = readStoredOpenGroups();
  const defaults: OpenGroupsState = {};
  for (const g of NAV_GROUPS) {
    // Default ALL groups closed on first visit; only restore if user explicitly saved state.
    defaults[g.id] = stored[g.id] ?? false;
  }
  return defaults;
}

function persistOpenGroups(next: OpenGroupsState): void {
  try {
    localStorage.setItem(NAV_GROUPS_STORAGE_KEY, JSON.stringify(next));
  } catch {
    /* ignore quota */
  }
}

function NavLink({
  item,
  label,
  active,
  collapsed,
}: {
  item: NavItemDef;
  label: string;
  active: boolean;
  collapsed: boolean;
}) {
  const Icon = item.icon;
  return (
    <Link
      href={item.href}
      title={collapsed ? label : undefined}
      aria-label={collapsed ? label : undefined}
      className={cn(
        "group flex items-center rounded-lg py-2 text-sm transition-colors cursor-pointer",
        collapsed ? "justify-center px-0" : "px-3",
        active
          ? "bg-accent text-accent-foreground font-medium"
          : "text-muted-foreground hover:bg-accent/50 hover:text-foreground"
      )}
    >
      <Icon
        className={cn(
          "h-4 w-4 shrink-0",
          collapsed ? "" : "me-2.5",
          active ? "text-primary" : "text-muted-foreground group-hover:text-foreground"
        )}
      />
      {!collapsed && <span className="min-w-0 truncate">{label}</span>}
    </Link>
  );
}

function NavGroupSection({
  group,
  title,
  open,
  onToggle,
  pathname,
  role,
  branchId,
  permissions,
  tItem,
  collapsed,
}: {
  group: NavGroupDef;
  title: string;
  open: boolean;
  onToggle: () => void;
  pathname: string;
  role: string | undefined;
  branchId: string | null | undefined;
  permissions: Set<string> | null;
  tItem: (key: string) => string;
  collapsed: boolean;
}) {
  const visibleItems = group.items.filter((item) =>
    canSeeNavItem(item.key, role, branchId, permissions)
  );
  if (visibleItems.length === 0) return null;

  // Collapsed: drop the group header, show items as a flat icon-only list
  // with a subtle divider between groups.
  if (collapsed) {
    return (
      <div className="mb-1 space-y-0.5 border-t border-border/60 pt-1 first:border-t-0 first:pt-0">
        {visibleItems.map((item) => {
          const active =
            pathname === item.href || pathname.startsWith(`${item.href}/`);
          return (
            <NavLink
              key={item.key}
              item={item}
              label={tItem(item.key)}
              active={active}
              collapsed
            />
          );
        })}
      </div>
    );
  }

  return (
    <div className="mb-1">
      <button
        type="button"
        onClick={onToggle}
        aria-expanded={open}
        className="flex w-full items-center gap-2 rounded-lg px-2 py-1.5 text-start transition-colors hover:bg-accent/50 cursor-pointer"
      >
        <ChevronDown
          className={cn(
            "h-3 w-3 shrink-0 text-muted-foreground/60 transition-transform duration-200",
            open && "rotate-180"
          )}
          aria-hidden
        />
        <span className="min-w-0 flex-1 truncate text-[10px] font-semibold uppercase tracking-[0.08em] text-muted-foreground/70">
          {title}
        </span>
      </button>
      <div
        className={cn(
          "grid transition-[grid-template-rows] duration-200",
          open ? "grid-rows-[1fr]" : "grid-rows-[0fr]"
        )}
      >
        <div className="overflow-hidden">
          <div className="space-y-0.5 pb-1 pt-0.5">
            {visibleItems.map((item) => {
              const active =
                pathname === item.href || pathname.startsWith(`${item.href}/`);
              return (
                <NavLink
                  key={item.key}
                  item={item}
                  label={tItem(item.key)}
                  active={active}
                  collapsed={false}
                />
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

export function Sidebar({ side }: { side: "left" | "right" }) {
  const t = useTranslations("nav");
  const tGroups = useTranslations("nav.groups");
  const tBrand = useTranslations("brand");
  const pathname = usePathname();
  const user = useAuthStore((s) => s.user);
  const hasHydrated = useAuthStore((s) => s._hasHydrated);
  const role = user?.role;
  const branchId = user?.branchId ?? null;
  const permissions = useMemo(() => permissionsOf(user), [user]);

  const [openGroups, setOpenGroups] = useState<OpenGroupsState>(buildDefaultOpenGroups);
  const [collapsed, setCollapsed] = useState<boolean>(readStoredCollapsed);

  const toggleCollapsed = useCallback(() => {
    setCollapsed((prev) => {
      const next = !prev;
      try {
        localStorage.setItem(SIDEBAR_COLLAPSED_STORAGE_KEY, next ? "1" : "0");
      } catch {
        /* ignore quota */
      }
      return next;
    });
  }, []);

  // Chevron points "inward" (toward the panel) to collapse, "outward" to expand.
  // For a left-docked sidebar inward = left; for a right-docked one inward = right.
  const CollapseIcon =
    side === "left"
      ? collapsed
        ? ChevronRight
        : ChevronLeft
      : collapsed
        ? ChevronLeft
        : ChevronRight;

  const visibleGroups = useMemo(
    () =>
      NAV_GROUPS.filter((g) => {
        if (!canSeeNavGroup(g.id, role, branchId)) return false;
        return g.items.some((item) => canSeeNavItem(item.key, role, branchId, permissions));
      }),
    [role, branchId, permissions]
  );

  /** Accordion: opening a group collapses all others. */
  const setGroupOpen = useCallback((groupId: NavGroupId, open: boolean) => {
    setOpenGroups((_prev) => {
      const next: OpenGroupsState = {};
      for (const g of NAV_GROUPS) {
        // If opening: only the clicked group becomes true; everything else closes.
        // If closing: just close the clicked group, leave others as-is.
        next[g.id] = open ? g.id === groupId : g.id === groupId ? false : (_prev[g.id] ?? false);
      }
      persistOpenGroups(next);
      return next;
    });
  }, []);

  // When navigating to a new path, open only the group that contains that path (accordion).
  useEffect(() => {
    const activeGroup = findNavGroupForPath(pathname);
    if (!activeGroup) return;
    setOpenGroups((prev) => {
      if (prev[activeGroup]) return prev; // already open, nothing to do
      // Accordion: open active group, close all others
      const next: OpenGroupsState = {};
      for (const g of NAV_GROUPS) {
        next[g.id] = g.id === activeGroup;
      }
      persistOpenGroups(next);
      return next;
    });
  }, [pathname]);

  return (
    <aside
      className={cn(
        "flex shrink-0 flex-col bg-background overflow-hidden",
        "transition-[width] duration-200 ease-in-out",
        collapsed ? "w-14" : "w-56",
        "border-border",
        side === "right" ? "border-s" : "border-e"
      )}
    >
      {/* Logo */}
      <div
        className={cn(
          "flex h-14 shrink-0 items-center border-b border-border",
          collapsed ? "justify-center px-0" : "gap-2.5 px-4"
        )}
      >
        <div className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-primary/10">
          <svg viewBox="0 0 24 24" className="h-4 w-4 fill-primary" aria-hidden>
            <path d="M3 6h18v2H3V6zm2 4h14v2H5v-2zm-2 4h18v2H3v-2zm4 4h10v2H7v-2z" />
          </svg>
        </div>
        {!collapsed && (
          <span className="min-w-0 truncate text-sm font-bold tracking-tight text-foreground">
            {tBrand("name")}
          </span>
        )}
      </div>

      {/* Nav */}
      <nav
        className="flex-1 overflow-y-auto p-3 space-y-1
          [&::-webkit-scrollbar]:w-1
          [&::-webkit-scrollbar-track]:bg-transparent
          [&::-webkit-scrollbar-thumb]:rounded-full
          [&::-webkit-scrollbar-thumb]:bg-border"
        aria-label={t("aria")}
      >
        {!hasHydrated ? (
          /* Skeleton — shown for ~50ms until Zustand rehydrates from localStorage.
             Prevents the flash where all groups are briefly visible before
             permission-based filtering kicks in for branch-scoped accounts. */
          collapsed ? (
            <div className="space-y-1.5">
              {Array.from({ length: 6 }).map((_, i) => (
                <div key={i} className="flex justify-center">
                  <div className="h-8 w-8 animate-pulse rounded-lg bg-muted" />
                </div>
              ))}
            </div>
          ) : (
            <div className="space-y-3 px-1 pt-1">
              {[40, 32, 40, 32, 40].map((w, i) => (
                <div key={i} className="space-y-1.5">
                  <div className="h-2 w-20 animate-pulse rounded bg-muted" />
                  {Array.from({ length: i % 2 === 0 ? 3 : 2 }).map((_, j) => (
                    <div
                      key={j}
                      className="h-8 animate-pulse rounded-lg bg-muted"
                      style={{ width: `${w + j * 4}%` }}
                    />
                  ))}
                </div>
              ))}
            </div>
          )
        ) : (
          visibleGroups.map((group) => {
            const isOpen = openGroups[group.id] ?? group.defaultOpen;
            return (
              <NavGroupSection
                key={group.id}
                group={group}
                title={tGroups(group.id)}
                open={isOpen}
                onToggle={() => setGroupOpen(group.id, !isOpen)}
                pathname={pathname}
                role={role}
                branchId={branchId}
                permissions={permissions}
                tItem={(key) => t(key)}
                collapsed={collapsed}
              />
            );
          })
        )}
      </nav>

      {/* Footer — user info + collapse toggle */}
      <div className="shrink-0 border-t border-border">
        {/* User badge */}
        {user && (
          <div
            className={cn(
              "flex items-center py-3",
              collapsed ? "justify-center px-0" : "gap-2 px-4"
            )}
          >
            <div
              className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary/10"
              title={collapsed ? (user.actor ?? user.userId) : undefined}
            >
              <span className="text-[11px] font-semibold text-primary">
                {(user.actor ?? user.role).charAt(0).toUpperCase()}
              </span>
            </div>
            {!collapsed && (
              <div className="min-w-0 flex-1">
                <p className="truncate text-xs font-medium text-foreground">
                  {user.actor ?? user.userId}
                </p>
                <p className="truncate text-[10px] text-muted-foreground">
                  {user.role}
                </p>
              </div>
            )}
          </div>
        )}

        {/* Collapse toggle */}
        <button
          type="button"
          onClick={toggleCollapsed}
          title={collapsed ? t("expandSidebar") : t("collapseSidebar")}
          aria-label={collapsed ? t("expandSidebar") : t("collapseSidebar")}
          className={cn(
            "flex w-full items-center gap-2 border-t border-border/50 py-2.5 text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground cursor-pointer",
            collapsed ? "justify-center px-0" : "px-4"
          )}
        >
          <CollapseIcon className="h-4 w-4 shrink-0" aria-hidden />
          {!collapsed && (
            <span className="text-xs">{t("collapseSidebar")}</span>
          )}
        </button>
      </div>
    </aside>
  );
}
