import forEach from 'lodash/forEach'
import size from 'lodash/size'

import type { History } from 'history'

import { history } from 'config/history'

/**
 * Имплементит Storage API (https://developer.mozilla.org/ru/docs/Web/API/Storage)
 */
class QueryParamStorage implements Storage {
  /**
   * через history обновляем url строку
   */
  history: History

  /**
   * хранит все состояние query param
   */
  urlParams: URLSearchParams

  constructor(historyArg: History) {
    this.history = historyArg
    this.urlParams = new URLSearchParams(this.history.location.search)
    this.history.listen((location, action) => {
      if (action !== 'REPLACE') {
        this.urlParams = new URLSearchParams(location.search)
      }
    })
  }

  get entries() {
    const entries = this.urlParams.entries()
    return Array.from(entries)
  }

  updateHistory() {
    history.replace(`?${this.urlParams.toString()}`)
  }

  clear() {
    forEach(this.entries, ([key]) => {
      this.urlParams.delete(key)
    })
    this.updateHistory()
  }

  getItem(key: string) {
    return this.urlParams.get(key)
  }

  key(index: number) {
    const keys = this.urlParams.keys()
    return Array.from(keys)[index]
  }

  removeItem(key: string) {
    this.urlParams.delete(key)
    this.updateHistory()
  }

  setItem(key: string, value: string) {
    if (JSON.parse(value)) {
      this.urlParams.set(key, value)
      this.updateHistory()
    } else {
      this.removeItem(key)
    }
  }

  get length() {
    return size(this.entries)
  }
}

export const queryParamStorage = new QueryParamStorage(history)
