import { createContext, useCallback, useContext, useEffect, useState } from 'react';

const SESSION_KEY = 'warehouse_management_system_session';

interface SessionState {
  currentUser: { id: string; username: string; email: string; role: string; permissions: string[] } | null;
  notifications: { unreadCount: number };
  navigationMenus: Array<{ id: string; label: string; icon: string; route: string; children: Array<{ id: string; label: string; route: string }> }>;
  systemSettings: Record<string, string>;
}

const DEFAULT_SESSION: SessionState = {
  currentUser: null,
  notifications: { "unreadCount": 0 },
  navigationMenus: [],
  systemSettings: {},
};

function readSession(): SessionState {
  try {
    const raw = sessionStorage.getItem(SESSION_KEY);
    if (!raw) return DEFAULT_SESSION;
    return { ...DEFAULT_SESSION, ...JSON.parse(raw) } as SessionState;
  } catch {
    return DEFAULT_SESSION;
  }
}

function writeSession(state: Partial<SessionState>): void {
  try {
    const prev = readSession();
    sessionStorage.setItem(SESSION_KEY, JSON.stringify({ ...prev, ...state }));
  } catch { /* quota exceeded or SSR */ }
}
function getOrCreateSessionId(): string {
  let id = sessionStorage.getItem('__sid__');
  if (!id) {
    id = crypto.randomUUID();
    sessionStorage.setItem('__sid__', id);
  }
  return id;
}

interface AppContextType {
  currentUser: { id: string; username: string; email: string; role: string; permissions: string[] } | null;
  setCurrentUser: (value: { id: string; username: string; email: string; role: string; permissions: string[] } | null) => void;
  notifications: { unreadCount: number };
  setNotifications: (value: { unreadCount: number }) => void;
  navigationMenus: Array<{ id: string; label: string; icon: string; route: string; children: Array<{ id: string; label: string; route: string }> }>;
  setNavigationMenus: (value: Array<{ id: string; label: string; icon: string; route: string; children: Array<{ id: string; label: string; route: string }> }>) => void;
  systemSettings: Record<string, string>;
  setSystemSettings: (value: Record<string, string>) => void;
  sessionId: string;
  clearSession: () => void;
}

const AppContext = createContext<AppContextType | null>(null);

export function AppProvider({ children }: { children: React.ReactNode }) {
  const [sessionId] = useState<string>(getOrCreateSessionId);
  const [currentUser, setCurrentUserRaw] = useState<{ id: string; username: string; email: string; role: string; permissions: string[] } | null>(() => readSession().currentUser);
  const [notifications, setNotificationsRaw] = useState<{ unreadCount: number }>(() => readSession().notifications);
  const [navigationMenus, setNavigationMenusRaw] = useState<Array<{ id: string; label: string; icon: string; route: string; children: Array<{ id: string; label: string; route: string }> }>>(() => readSession().navigationMenus);
  const [systemSettings, setSystemSettingsRaw] = useState<Record<string, string>>(() => readSession().systemSettings);

  const setCurrentUser = useCallback((value: { id: string; username: string; email: string; role: string; permissions: string[] } | null) => {
    setCurrentUserRaw(value);
  }, []);

  const setNotifications = useCallback((value: { unreadCount: number }) => {
    setNotificationsRaw(value);
  }, []);

  const setNavigationMenus = useCallback((value: Array<{ id: string; label: string; icon: string; route: string; children: Array<{ id: string; label: string; route: string }> }>) => {
    setNavigationMenusRaw(value);
  }, []);

  const setSystemSettings = useCallback((value: Record<string, string>) => {
    setSystemSettingsRaw(value);
  }, []);

  useEffect(() => {
    writeSession({ currentUser, notifications, navigationMenus, systemSettings });
  }, [currentUser, notifications, navigationMenus, systemSettings]);
  const clearSession = useCallback(() => {
    sessionStorage.removeItem(SESSION_KEY);
    sessionStorage.removeItem('__sid__');
    setCurrentUserRaw(null);
    setNotificationsRaw({ "unreadCount": 0 });
    setNavigationMenusRaw([]);
    setSystemSettingsRaw({});
  }, []);

  return (
    <AppContext.Provider value={{ currentUser, setCurrentUser, notifications, setNotifications, navigationMenus, setNavigationMenus, systemSettings, setSystemSettings, sessionId, clearSession }}>
      {children}
    </AppContext.Provider>
  );
}

export function useAppContext(): AppContextType {
  const ctx = useContext(AppContext);
  if (!ctx) throw new Error('useAppContext must be used within AppProvider');
  return ctx;
}
