import { createContext, useMemo } from 'react';

let fallbackLocalStorageData: { [key: string]: string } = {};

const fallbackLocalStorage = {
  getItem: (key: string) => {
    return fallbackLocalStorageData[key];
  },
  setItem: (key: string, value: string) => {
    fallbackLocalStorageData[key] = value;
  },
  removeItem: (key: string) => {
    delete fallbackLocalStorageData[key];
  },
  key: (index: number) => {
    return Object.keys(fallbackLocalStorageData)[index];
  },
  clear: () => {
    fallbackLocalStorageData = {};
  },
  length: Object.keys(fallbackLocalStorageData).length,
};

const localStorageOrFallback = typeof localStorage !== 'undefined' ? localStorage : fallbackLocalStorage;

export const getLocalStorage = () => {
  const listKeys = () => {
    const result: string[] = [];
    for (let i = 0; i < localStorageOrFallback.length; i++) {
      const key = localStorageOrFallback.key(i);
      if (key) {
        result.push(key);
      }
    }
    return result;
  };
  return {
    getItem: (key: string): string | null => {
      let item = localStorageOrFallback.getItem(key);
      if (item === null) item = localStorageOrFallback.getItem(key);
      return item;
    },
    setItem: (key: string, value: string) => {
      localStorageOrFallback.setItem(key, value);
    },
    removeItem: (key: string) => {
      localStorageOrFallback.removeItem(key);
    },
    key: (index: number) => {
      const keys = listKeys();
      return keys[index];
    },
    keys: listKeys,
    clear: () => {
      for (let key in localStorageOrFallback) {
        if (key) localStorageOrFallback.removeItem(key);
      }
    },
  };
};

const useLocalStorage = () => {
  const localStorage = useMemo(() => getLocalStorage(), []);
  return useMemo(() => ({ localStorage }), [localStorage]);
};

export type AccountLocalStorage = ReturnType<typeof getLocalStorage>;

export const AccountLocalStorageContext = createContext<ReturnType<typeof useLocalStorage>>(null as any);

export default useLocalStorage;
