const storageType = 'localStorage'

var data = {}

const infoEl = document.getElementById('info')
const formEl = document.getElementById('search')

// Register event listeners
formEl.addEventListener('submit', (event) => {
  event.preventDefault()
  if ('instances' in data && data.instances.length > 0) {
    // Random instance
    const n = Math.floor(Math.random() * data.instances.length)
    const instanceURL = data.instances[n]
    // Assign URL
    const params = new URLSearchParams({
      q: formEl.query.value
    })
    const url = `${instanceURL}?${params.toString()}`
    location.assign(url)
  }
})

function locallyGetInstances () {
  if (!(storageType in window)) return []
  const item = window[storageType].getItem('instances')
  try {
    return JSON.parse(item)
  } catch (_err) {
    return []
  }
}

function locallySetInstances () {
  if (!(storageType in window)) return
  if (!('instances' in data)) return
  if (data.instances.length === 0) return
  window[storageType].setItem(
    'instances',
    JSON.stringify(data.instances)
  )
}

async function remotelyGetInstances () {
  const instances = await fetch('https://searx.space/data/instances.json')
    .then((req) => req.json())
    .then((json) => Object.entries(json.instances))
    .then((entries) => entries.filter(([_url, details]) => {
      if (details.network_type !== 'normal') return
      if (details.uptime == null) return
      if (details.uptime.uptimeDay !== 100) return
      return true
    }))
    .then((entries) => entries.map(([url]) => url))
    .catch((err) => {
      console.error(err)
      return []
    })
  window[storageType].setItem('timestamp', Date.now().toString())
  return instances
}

// Get local instances
data.instances = locallyGetInstances()

// Fetch remote instances if necessary
const timestamp = +window[storageType].getItem('timestamp')
if (Date.now() > timestamp + 3_600_000 /* 1 hour */) {
  const remoteInstances = await remotelyGetInstances()
  if (remoteInstances.length > 0) {
    data.instances = remoteInstances
    locallySetInstances()
  }
}

if (data.instances.length > 0) {
  infoEl.textContent = `${data.instances.length} instances`
} else {
  infoEl.classList.add('error')
  infoEl.textContent = '0 instances'
}