const { getUserId } = globalThis.ami

const instance = {
  consentApi: null,
  requestInformation: null,
  consentGroups: {
    C0001: { name: 'functional', id: null },
    C0002: { name: 'statistics', id: null },
    C0004: { name: 'preferences', id: null },
    C0005: { name: 'marketing', id: null }
  }
}

export async function getProviderData (src, disableList) {
  let res = await fetch(src)
  const otConfig = await res.json()

  const ruleset = otConfig.RuleSet[0]
  const rulesetId = ruleset.Id
  const pageLocale = document.documentElement.lang.toLowerCase()
  const pageLanguage = pageLocale.substring(0, pageLocale.lastIndexOf('-'))
  const availableLocales = ruleset.LanguageSwitcherPlaceholder
  const language = availableLocales[pageLocale] ?? availableLocales[pageLanguage] ?? availableLocales.default
  const configSrc = src.replace(/^(.*)\/([a-z0-9-]+)\.json$/, `$1/${rulesetId}/${language}.json`)

  res = await fetch(configSrc)
  const otData = await res.json()

  instance.consentApi = otData.CommonData.ConsentIntegration.ConsentApi
  instance.requestInformation = otData.CommonData.ConsentIntegration.RequestInformation

  const domainData = otData.DomainData
  const groups = []

  for (const group of domainData.Groups) {
    if (!group.ShowInPopup) {
      continue
    }

    const name = instance.consentGroups[group.OptanonGroupId]?.name
    if (!name) {
      console.warn(`Unsupported group: [${group.OptanonGroupId}] ${group.GroupName}.`)
      continue
    }

    instance.consentGroups[group.OptanonGroupId].id = group.PurposeId

    groups.push({
      name,
      title: group.GroupName,
      text: group.GroupDescription,
      alwaysActive: group.Status === 'always active',
      cookies: [
        // First party cookies.
        ...group.FirstPartyCookies.map(c => ({
          [domainData.CategoriesText]: c.Host,
          [domainData.CookiesText]: c.Name,
          [domainData.CookiesUsedText]: domainData.CookieFirstPartyText,
          [domainData.CookiesDescText]: c.description
        })),
        // Third party cookies.
        ...group.Hosts.reduce((acc, host) => {
          acc.push(...host.Cookies.map(c => ({
            [domainData.CategoriesText]: c.Host,
            [domainData.CookiesText]: c.Name,
            [domainData.CookiesUsedText]: domainData.CookieThirdPartyText,
            [domainData.CookiesDescText]: c.description
          })))
          return acc
        }, [])
      ]
    })
  }

  const cookies = disableList ? [] : groups.reduce((acc, group) => [...acc, ...group.cookies], [])

  return {
    banner: {
      title: domainData.BannerTitle,
      text: domainData.AlertNoticeText,
      buttonAccept: domainData.AlertAllowCookiesText,
      buttonReject: domainData.BannerShowRejectAllButton ? domainData.BannerRejectAllButtonText : null,
      buttonSettings: domainData.AlertMoreInfoText
    },
    settings: {
      title: domainData.MainText,
      categories: domainData.PreferenceCenterManagePreferencesText,
      text: domainData.MainInfoText,
      buttonConfirm: domainData.PreferenceCenterConfirmText,
      buttonReject: domainData.BannerRejectAllButtonText,
      buttonClose: domainData.AlertCloseText,
      buttonCookies: domainData.CookieListTitle,
      gcpText: domainData.PCOptOutSignalText
    },
    list: {
      title: domainData.CookieListTitle,
      text: domainData.CookieListDescription
    },
    groups,
    cookies
  }
}

export async function notifyProvider (consent = {}) {
  if (!instance.requestInformation) {
    return null
  }

  const [userId] = getUserId()
  const payload = {
    customPayload: { Interaction: 1, AddDefaultInteraction: true },
    dsDataElements: { UserAgent: navigator.userAgent },
    identifier: userId,
    identifierType: 'User ID',
    isAnonymous: true,
    purposes: Object.values(instance.consentGroups).map(g => {
      let choice = 'OPT_OUT'
      if (g.name === 'functional') {
        choice = 'NO_CHOICE'
      } else if (consent[g.name]) {
        choice = 'CONFIRMED'
      }

      return { Id: g.id, TransactionType: choice }
    }),
    requestInformation: instance.requestInformation,
    test: false
  }

  return fetch(instance.consentApi, { method: 'POST', body: JSON.stringify(payload) })
}
