import { defineStore } from 'pinia'

const searchEngines = {
  nix: {
    url: 'https://search.nixos.org/packages?channel=22.11&from=0&size=50&sort=relevance&type=packages&query=',
    bang: 'n',
    icon: '/search_engine/nix-snowflake.svg'
  },
  'duck-duck-go': {
    url: 'https://duckduckgo.com/?q=',
    bang: 'd',
    icon: '/search_engine/duck_duck_go.svg'
  },
  google: {
    url: 'https://www.google.com/search?q=',
    bang: 'g',
    icon: '/search_engine/google.svg'
  },
  youtube: {
    url: 'https://www.youtube.com/results?search_query=',
    bang: 'yt',
    icon: '/search_engine/youtube.svg'
  },
  rule34: {
    url: 'https://rule34.xxx/index.php?page=post&s=list&tags=',
    bang: 'r34',
    icon: '/search_engine/rule34.png'
  },
  bing: {
    url: 'https://www.bing.com/search?q=',
    bang: 'bi',
    icon: '/search_engine/bing.svg'
  },
  yahoo: {
    url: 'https://de.search.yahoo.com/search?p=',
    bang: 'ya',
    icon: '/search_engine/yahoo.svg'
  },
  yandex: {
    url: 'https://yandex.com/search/?text=',
    bang: 'y',
    icon: '/search_engine/yandex.svg'
  },
  brave: {
    url: 'https://search.brave.com/search?q=',
    bang: 'b',
    icon: '/search_engine/brave.svg'
  }
}

const bangToEngine = Object.keys(searchEngines).reduce((acc, engine) => {
  acc[searchEngines[engine].bang] = engine
  return acc
}, {})

export const useSearchStore = defineStore({
  id: 'search',
  state: () => ({
    searchEnginePriorities: Array.from(Object.keys(searchEngines)),
    searchInput: ''
  }),
  getters: {
    currentEngine: (state) => {
      if (bangToEngine[state.searchBang]) {
        return bangToEngine[state.searchBang]
      }

      return state.searchEnginePriorities[0]
    },
    currentEngineData: (state) => {
      return searchEngines[state.currentEngine]
    },
    searchBang: (state) => {
      // if the search input starts with an exclamation mark
      // we assume it's a bang and we want to change the search engine, so we return the contents behind the exclamation mark till the first space
      if (state.searchInput.startsWith('!')) {
        return state.searchInput.slice(1).split(' ')[0]
      }
      return ''
    },
    searchQuery: (state) => {
      return state.searchInput.trim()
    },
    url: (state) => {
      return state.currentEngineData.url + state.searchInput.replace(' ', '+')
    },

    searchEngineData: (state) => {
      let priorities

      if (bangToEngine[state.searchBang]) {
        priorities = [
          bangToEngine[state.searchBang],
          ...state.searchEnginePriorities.filter(
            (engine) => engine !== bangToEngine[state.searchBang]
          )
        ]
      } else {
        priorities = state.searchEnginePriorities
      }

      return priorities.map((engine) => {
        return [engine, searchEngines[engine]]
      })
    }
  },
  actions: {
    setSearchEngine(engine) {
      // get the first engine
      const firstEngine = this.searchEnginePriorities.shift()

      // remove the requested engine from the list
      const index = this.searchEnginePriorities.indexOf(engine)
      if (index <= -1) {
        return
      }
      this.searchEnginePriorities.splice(index, 1)

      // add the requested to the end of the list
      this.searchEnginePriorities.unshift(engine)

      // add the first engine to the list
      this.searchEnginePriorities.push(firstEngine)
    },
    nextSearchEngine() {
      const firstEngine = this.searchEnginePriorities.shift()
      this.searchEnginePriorities.push(firstEngine)
    },
    previousSearchEngine() {
      const lastEngine = this.searchEnginePriorities.pop()
      this.searchEnginePriorities.unshift(lastEngine)
    }
  }
})
