interface StorageOptionsInterface<K = string> {
  local: boolean;
  getKeyHandler: (key: K) => string;
}

class Storage<T = string> {
  storeHandler: typeof window.localStorage | typeof window.sessionStorage;
  getKeyHandler: StorageOptionsInterface<T>['getKeyHandler'];
  constructor(options: Partial<StorageOptionsInterface<T>>) {
    const defaults = {
      local: true,
      getKeyHandler(key: T) {
        return `${key}`;
      },
    };
    const { local, getKeyHandler } = { ...defaults, ...options };
    this.storeHandler = local ? localStorage : sessionStorage;
    this.getKeyHandler = getKeyHandler;
  }
  get(targetKey: T) {
    const key = this.getKeyHandler(targetKey);
    const orignalStore = this.storeHandler.getItem(key);
    const { value } = JSON.parse(orignalStore || '{}');
    return value;
  }
  set(targetKey: T, value: any) {
    const key = this.getKeyHandler(targetKey);
    this.storeHandler.setItem(key, JSON.stringify({ key, value }));
  }
  move(targetKey: T) {
    const key = this.getKeyHandler(targetKey);
    this.storeHandler.removeItem(key);
  }
}

const store: Storage<string> = new Storage({
  getKeyHandler(key) {
    return `__${key}__`;
  },
});

export default store;

export const sessionStore: Storage<string> = new Storage({
  local: false,
  getKeyHandler(key) {
    return `__${key}__`;
  },
});
