import { useCallback, useEffect, useLayoutEffect, useRef, useState, type PointerEvent } from "react";
import type { AuthPlatform } from "@/lib/auth";

/** Icon-only collapsed width — matches the current shell. */
export const SIDEBAR_ICON_WIDTH = 72;
/** Default expanded width — matches the current shell. */
export const SIDEBAR_DEFAULT_WIDTH = 248;
/** Narrowest expanded width that still fits labels without crowding icons. */
export const SIDEBAR_MIN_WIDTH = 196;
/** Widest width so the sidebar cannot dominate the page. */
export const SIDEBAR_MAX_WIDTH = 380;

const COOKIE_MAX_AGE = 60 * 60 * 24 * 365;

type SidebarLayoutPref = {
  width: number;
  collapsed: boolean;
};

function cookieName(platform: AuthPlatform) {
  return `amanah_sidebar_${platform}`;
}

function clampWidth(value: number) {
  return Math.min(SIDEBAR_MAX_WIDTH, Math.max(SIDEBAR_MIN_WIDTH, Math.round(value)));
}

function readPref(platform: AuthPlatform): SidebarLayoutPref {
  const fallback: SidebarLayoutPref = { width: SIDEBAR_DEFAULT_WIDTH, collapsed: false };
  if (typeof document === "undefined") return fallback;
  const match = document.cookie.match(new RegExp(`(?:^|; )${cookieName(platform)}=([^;]*)`));
  if (!match?.[1]) return fallback;
  try {
    const parsed = JSON.parse(decodeURIComponent(match[1])) as Partial<SidebarLayoutPref>;
    return {
      width:
        typeof parsed.width === "number" && Number.isFinite(parsed.width)
          ? clampWidth(parsed.width)
          : SIDEBAR_DEFAULT_WIDTH,
      collapsed: parsed.collapsed === true,
    };
  } catch {
    return fallback;
  }
}

function writePref(platform: AuthPlatform, pref: SidebarLayoutPref) {
  document.cookie = `${cookieName(platform)}=${encodeURIComponent(JSON.stringify(pref))}; path=/; max-age=${COOKIE_MAX_AGE}; SameSite=Lax`;
}

export function useResizableSidebar(platform: AuthPlatform) {
  const [pref, setPref] = useState<SidebarLayoutPref>({
    width: SIDEBAR_DEFAULT_WIDTH,
    collapsed: false,
  });
  const [resizing, setResizing] = useState(false);
  const dragRef = useRef<{ startX: number; startWidth: number } | null>(null);

  useLayoutEffect(() => {
    setPref(readPref(platform));
  }, [platform]);

  const setCollapsed = useCallback(
    (updater: boolean | ((current: boolean) => boolean)) => {
      setPref((current) => {
        const collapsed = typeof updater === "function" ? updater(current.collapsed) : updater;
        const next = { ...current, collapsed };
        writePref(platform, next);
        return next;
      });
    },
    [platform],
  );

  const onResizePointerDown = useCallback(
    (event: PointerEvent<HTMLElement>) => {
      event.preventDefault();
      event.stopPropagation();
      dragRef.current = {
        startX: event.clientX,
        startWidth: pref.collapsed ? SIDEBAR_ICON_WIDTH : pref.width,
      };
      setResizing(true);
    },
    [pref.collapsed, pref.width],
  );

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

    const previousCursor = document.body.style.cursor;
    const previousUserSelect = document.body.style.userSelect;
    document.body.style.cursor = "col-resize";
    document.body.style.userSelect = "none";

    const onMove = (event: globalThis.PointerEvent) => {
      const drag = dragRef.current;
      if (!drag) return;
      const nextWidth = drag.startWidth + (event.clientX - drag.startX);
      if (nextWidth < SIDEBAR_MIN_WIDTH) {
        if (drag.startWidth <= SIDEBAR_ICON_WIDTH) {
          setPref((current) => ({ ...current, collapsed: true }));
          return;
        }
        setPref((current) => ({ ...current, width: SIDEBAR_MIN_WIDTH, collapsed: false }));
        return;
      }
      setPref({ width: clampWidth(nextWidth), collapsed: false });
    };

    const onUp = () => {
      setResizing(false);
      dragRef.current = null;
      setPref((current) => {
        writePref(platform, current);
        return current;
      });
    };

    window.addEventListener("pointermove", onMove);
    window.addEventListener("pointerup", onUp);
    window.addEventListener("pointercancel", onUp);
    return () => {
      document.body.style.cursor = previousCursor;
      document.body.style.userSelect = previousUserSelect;
      window.removeEventListener("pointermove", onMove);
      window.removeEventListener("pointerup", onUp);
      window.removeEventListener("pointercancel", onUp);
    };
  }, [resizing, platform]);

  return {
    collapsed: pref.collapsed,
    displayedWidth: pref.collapsed ? SIDEBAR_ICON_WIDTH : pref.width,
    resizing,
    setCollapsed,
    onResizePointerDown,
  };
}
