"use client";

import { createContext, useContext, useState, useCallback, useEffect, type ReactNode } from "react";

interface SidebarContextValue {
  collapsed: boolean;
  toggleCollapsed: () => void;
  mobileOpen: boolean;
  setMobileOpen: (open: boolean) => void;
  isMobile: boolean;
}

const SidebarContext = createContext<SidebarContextValue | undefined>(undefined);

/** Breakpoint below which we treat the viewport as "mobile" (matches CSS max-width: 767px). */
const MOBILE_MAX_WIDTH = 767;

export function SidebarProvider({ children }: { children: ReactNode }): React.JSX.Element {
  const [collapsed, setCollapsed] = useState(false);
  const [mobileOpen, setMobileOpen] = useState(false);
  const [isMobile, setIsMobile] = useState(false);

  // Initialise and track mobile breakpoint using matchMedia
  useEffect((): (() => void) => {
    const mql = window.matchMedia(`(max-width: ${String(MOBILE_MAX_WIDTH)}px)`);

    const handleChange = (e: MediaQueryListEvent): void => {
      setIsMobile(e.matches);
      // Close mobile sidebar when viewport grows out of mobile range
      if (!e.matches) {
        setMobileOpen(false);
      }
    };

    // Set initial value synchronously
    setIsMobile(mql.matches);

    mql.addEventListener("change", handleChange);
    return (): void => {
      mql.removeEventListener("change", handleChange);
    };
  }, []);

  const toggleCollapsed = useCallback((): void => {
    setCollapsed((prev) => !prev);
  }, []);

  const value: SidebarContextValue = {
    collapsed,
    toggleCollapsed,
    mobileOpen,
    setMobileOpen,
    isMobile,
  };

  return <SidebarContext.Provider value={value}>{children}</SidebarContext.Provider>;
}

export function useSidebar(): SidebarContextValue {
  const context = useContext(SidebarContext);
  if (context === undefined) {
    throw new Error("useSidebar must be used within SidebarProvider");
  }
  return context;
}
