/* global localStorage */
const STORAGE_KEY = '_evidon_proxy'
const DEFAULT_CONSENT = {
  functional: true,
  statistics: false,
  preferences: false,
  marketing: false,
}

export function setConsent (consent) {
  if (consent) {
    consent = { ...DEFAULT_CONSENT, date: new Date().toISOString(), ...consent }
    localStorage.setItem(STORAGE_KEY, JSON.stringify(consent))
  } else {
    localStorage.removeItem(STORAGE_KEY)
  }

  globalThis.dispatchEvent(new CustomEvent('consent', { detail: consent }))
}

export function getConsent () {
  // No consent granted.
  const consent = JSON.parse(localStorage.getItem(STORAGE_KEY))
  if (!consent) {
    return gcpHandler()
  }

  // Consent expired.
  const now = new Date()
  const referenceDate = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(),
    now.getSeconds(), now.getMilliseconds())
  if (new Date(consent.date) < referenceDate) {
    setConsent()
    return gcpHandler()
  }

  // Consent already granted or denied.
  return gcpHandler(consent)
}

// This works for the first consent collection.
// Changing consent requires a page reload anyway.
export async function waitForConsent (expectedConsent, inclusive = true) {
  return new Promise(resolve => {
    if (hasConsent(expectedConsent, inclusive)) {
      resolve(getConsent())
      return
    }

    globalThis.addEventListener('consent', () => {
      if (hasConsent(expectedConsent, inclusive)) {
        resolve(getConsent())
      }
    })
  })
}

function hasConsent (expectedConsent, inclusive) {
  const consent = getConsent() ?? {}
  const func = inclusive ? 'every' : 'some'
  return Object.keys(expectedConsent)[func](key => consent[key] === expectedConsent[key])
}

function gcpHandler (consent) {
  if (!consent) {
    return navigator.globalPrivacyControl ? DEFAULT_CONSENT : null
  }

  return consent
}
