import { customElement, property } from 'lit/decorators.js'
import { html, PropertyValues } from 'lit'
import { PktElement } from '@/base-elements/element'
import { consentStrings } from './strings'
import '../button'
import '../icon'

let consentScriptPromise: Promise<void> | null = null

function loadConsentScript(): Promise<void> {
  if (consentScriptPromise) return consentScriptPromise

  consentScriptPromise = new Promise((resolve, reject) => {
    if (document.querySelector('#oslo-consent-script')) {
      resolve()
      return
    }
    const script = document.createElement('script')
    script.src = 'https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.js'
    script.id = 'oslo-consent-script'
    script.onload = () => resolve()
    script.onerror = reject
    document.head.appendChild(script)

    const styles = document.createElement('link')
    styles.href = 'https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.css'
    styles.type = 'text/css'
    styles.rel = 'stylesheet'
    styles.id = 'oslo-consent-styles'
    document.head.appendChild(styles)
  })

  return consentScriptPromise
}
// Extend the Window interface to include googleAnalyticsId
declare global {
  interface Window {
    cookieBanner_devMode?: boolean
    cookieBanner_cookieDomain?: string | null
    cookieBanner_cookieSecure?: string | null
    cookieBanner_cookieExpiryDays?: string | null
    cookieBanner_googleAnalyticsId?: string | null
    cookieBanner_hotjarId?: string | null
    cookieBanner?: any
    __cookieEvents?: any
  }
}

export interface IPktConsent {
  devMode?: boolean
  cookieDomain?: string | null
  cookieSecure?: string | null
  cookieExpiryDays?: string | null
  hotjarId?: string | null
  googleAnalyticsId?: string | null
  i18nLanguage?: string
  triggerType?: 'button' | 'link' | 'footerlink' | 'icon' | null
  triggerText?: string | null
}

@customElement('pkt-consent')
export class PktConsent extends PktElement<IPktConsent> implements IPktConsent {
  private _cookieEventHandler?: (consent: any) => void

  @property({ type: Boolean }) devMode: boolean = false

  @property({ type: String }) hotjarId: string | null = null
  @property({ type: String }) googleAnalyticsId: string | null = null
  @property({ type: String }) cookieDomain: string | null = null
  @property({ type: String }) cookieSecure: string | null = null
  @property({ type: String }) cookieExpiryDays: string | null = null

  @property({ type: String }) triggerType: 'button' | 'link' | 'footerlink' | 'icon' | null =
    'button'
  @property({ type: String }) triggerText: string | null = null
  @property({ type: String }) i18nLanguage: string = 'nb'

  constructor() {
    super()
  }

  connectedCallback() {
    super.connectedCallback()
    this.triggerText =
      this.triggerText ||
      consentStrings.i18n[this.i18nLanguage as keyof typeof consentStrings.i18n].contentPresentation
        .buttons.settings
  }

  disconnectedCallback() {
    super.disconnectedCallback()
    if (this._cookieEventHandler) {
      window.__cookieEvents?.off('CookieManager.setCookie', this._cookieEventHandler)
    }
  }

  returnJsonOrObject(obj: any) {
    let returnObj
    try {
      returnObj = JSON.parse(obj)
    } catch (e) {
      returnObj = obj
    }
    return returnObj
  }

  emitCookieConsents(consent: any) {
    const consents = this.returnJsonOrObject(consent.value)

    const consentDetails = consents.items.reduce((acc: any, item: any) => {
      acc[item.name] = item.consent
      return acc
    }, {})

    this.dispatchEvent(
      new CustomEvent('toggle-consent', {
        detail: consentDetails,
        bubbles: true,
        cancelable: false,
      }),
    )
  }

  protected async firstUpdated(_changedProperties: PropertyValues): Promise<void> {
    window.cookieBanner_googleAnalyticsId = this.googleAnalyticsId
    window.cookieBanner_hotjarId = this.hotjarId
    if (this.cookieDomain) window.cookieBanner_cookieDomain = this.cookieDomain
    if (this.cookieSecure) window.cookieBanner_cookieSecure = this.cookieSecure
    if (this.cookieExpiryDays) window.cookieBanner_cookieExpiryDays = this.cookieExpiryDays
    if (this.devMode) window.cookieBanner_devMode = this.devMode

    await loadConsentScript()
    this.triggerInit()
  }

  triggerInit() {
    window.document.dispatchEvent(
      new Event('CookieBannerReady', {
        bubbles: true,
        cancelable: true,
      }),
    )

    window.cookieBanner.cookieConsent.validateConsentCookie().then((response: boolean) => {
      if (response) {
        const cookie = window.cookieBanner.cookieConsent.getConsentCookie()
        const consents = { value: cookie }
        window.setTimeout(() => this.emitCookieConsents(consents), 0)

        if (this._cookieEventHandler) {
          window.__cookieEvents.off('CookieManager.setCookie', this._cookieEventHandler)
        }
        this._cookieEventHandler = (consent: any) => {
          this.emitCookieConsents(consent)
        }
        window.__cookieEvents.on('CookieManager.setCookie', this._cookieEventHandler)
      }
    })
  }

  openModal(e: Event) {
    e.preventDefault()
    if (!window.cookieBanner?.cookieConsent) {
      this.triggerInit()
    }
    setTimeout(() => window.cookieBanner.openCookieModal())
  }

  render() {
    if (this.triggerType === 'link') {
      return html`<a href="#" class="pkt-link" @click=${this.openModal}>${this.triggerText}</a>`
    }
    if (this.triggerType === 'footerlink') {
      return html`<a href="#" class="pkt-footer__link" @click=${this.openModal}>
        <pkt-icon name="chevron-right" class="pkt-footer__link-icon"></pkt-icon>
        ${this.triggerText}
      </a>`
    }
    if (this.triggerType === 'icon') {
      return html`<pkt-button
        skin="tertiary"
        variant="icon-only"
        iconName="cookie"
        @click=${this.openModal}
      >
        >${this.triggerText}</pkt-button
      >`
    }
    return html`<pkt-button @click=${this.openModal}>${this.triggerText}</pkt-button>`
  }
}
