import React, { createContext, useCallback, useContext, useEffect, useMemo } from 'react';
import Logger from '../../application/logging/logger';

interface SessionStorageContextType {
  setItem: (key: string, value: string) => void;
  getItem: (key: string) => string | null;
  isAvailable: boolean;
}

const SessionStorageContext = createContext<SessionStorageContextType | null>(null);

const logger = new Logger('sessionStorageContext');

export const SessionStorageProvider: React.FC<{
  children: React.ReactNode;
}> = ({ children }) => {
  const isAvailable = useMemo(() => {
    try {
      return typeof window !== 'undefined' && !!window.sessionStorage;
    } catch {
      return false;
    }
  }, []);

  useEffect(() => {
    if (!isAvailable) {
      logger.logError('sessionStorage is not available', undefined);
    }
  }, [isAvailable]);

  const setItem = useCallback(
    (key: string, value: string) => {
      if (!isAvailable) return;
      sessionStorage.setItem(key, value);
      window.dispatchEvent(new StorageEvent('storage', { key, newValue: value }));
    },
    [isAvailable],
  );

  const getItem = useCallback(
    (key: string) => {
      if (!isAvailable) return null;
      return sessionStorage.getItem(key);
    },
    [isAvailable],
  );

  const value = useMemo(
    () => ({
      setItem,
      getItem,
      isAvailable,
    }),
    [setItem, getItem, isAvailable],
  );

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

export const useSessionStorage = () => {
  const context = useContext(SessionStorageContext);
  if (!context) {
    throw new Error('useSessionStorage must be used within a SessionStorageProvider');
  }
  return context;
};
