import { css, html, LitElement } from 'lit'
import Clipboard from 'clipboard'

import { notify } from '@things-factory/layout-base'
import { i18next, localize } from '@things-factory/i18n-base'
import '@things-factory/setting-base'
import { openPopup } from '@things-factory/layout-base'
import { subscribe, unsubscribe, getToken, isSupportingMessaging } from '../actions/notification-fcm'
import './notification-sender'

import '@material/mwc-formfield'
import '@material/mwc-switch'
import '@material/mwc-button'

export class NotificationSettingLet extends localize(i18next)(LitElement) {
  static get styles() {
    return [
      css`
        div[onoff] {
          display: flex;
          align-items: center;
          border-bottom: var(--border-dark-color);
          margin-bottom: var(--margin-default);
          padding-bottom: var(--padding-default);
        }

        div[info] {
          display: flex;
          flex-direction: column;
          position: relative;
        }

        label {
          font: var(--label-font);
          color: var(--label-color);
          text-transform: var(--label-text-transform);
        }

        [test] {
          margin-left: auto;
        }

        input {
          border: var(--border-dark-color);
          border-radius: var(--border-radius);
          margin: var(--input-margin);
          padding: var(--input-padding);
          font: var(--input-font);

          flex: 1;
        }

        [button-in-field] {
          position: absolute;
          top: 24px;
          right: 4px;
        }
      `
    ]
  }

  static get properties() {
    return {
      subscription: Object,
      supported: Boolean
    }
  }

  render() {
    const supported = !!this.supported

    return html`
      <setting-let>
        <i18n-msg slot="title" msgid="title.notification subscription"></i18n-msg>

        ${supported
          ? html`
        <div slot="content" onoff>
          <mwc-formfield label=${i18next.t('label.allow push message')}>
            <mwc-switch label="allow message" ?checked=${!!this.subscription} @change=${e =>
              this.onchange(e)}></mwc-switch>
          </mwc-formfield>
          <mwc-button test outlined label=${i18next.t('button.push message test')} @click=${e =>
              this.ontest()}></mwc-button>
        </div>
        
        <div slot="content" info>
          <label for="subscription-token"><i18n-msg msgid="label.subscription token"></i18n-msg></label>
          <input id="subscription-token" type="text" name="subscription-token" .value=${
            this.subscription || ''
          } readonly />
          <mwc-button dense unelevated button-in-field clipboard-copy @click=${e =>
            e.preventDefault()}><i18n-msg msgid="button.copy"></mwc-button>
        </div>
        `
          : html` <div slot="content">${i18next.t('text.push notification is not supported in your browser')}</div>`}
      </setting-let>
    `
  }

  firstUpdated() {
    const copybuttons = this.renderRoot.querySelectorAll('[clipboard-copy]')

    this.clipboard = new Clipboard(copybuttons, {
      target: trigger => trigger.parentElement.querySelector('input')
    })
  }

  async connectedCallback() {
    super.connectedCallback()

    const permission = 'Notification' in window && Notification.permission
    if (permission !== 'granted') {
      return
    }

    this.supported = await isSupportingMessaging()
    this.subscription = await getToken()
  }

  async onchange(e) {
    const target = e.target
    const on = target.checked

    if (!('Notification' in window)) {
      notify({
        level: 'error',
        message: i18next.t('This browser does not support desktop notification')
      })

      return
    }

    try {
      if (Notification.permission !== 'granted') {
        const permission = await Notification.requestPermission()
        if (permission === 'denied') {
          notify({
            level: 'error',
            message: i18next.t('text.web push notification unblock guide')
          })
        }
        return
      }

      if (Notification.permission === 'granted') {
        if (on) {
          const subscription = await getToken()

          if (subscription) {
            this.subscription = subscription
            notify({
              level: 'info',
              message: i18next.t('text.notification subscribed already')
            })
          } else {
            this.subscription = await subscribe()

            this.subscription &&
              notify({
                level: 'info',
                message: i18next.t('text.notification subscribe started')
              })
          }
        } else {
          if (this.subscription) {
            await unsubscribe()

            this.subscription = await getToken()

            notify({
              level: 'info',
              message: i18next.t('text.notification unsubscribed')
            })
          } else {
            notify({
              level: 'info',
              message: i18next.t('text.notification unsubscribed already')
            })
          }
        }
      } else {
        notify({
          level: 'error',
          message: i18next.t('text.notification subscribing failed')
        })
      }
    } catch (err) {
      notify({
        level: 'error',
        message: err
      })
    } finally {
      target.checked = !!this.subscription
    }
  }

  ontest() {
    openPopup(html` <notification-sender></notification-sender> `, {
      backdrop: true,
      size: 'large',
      title: i18next.t('title.notification-sender')
    })
  }
}

customElements.define('notification-setting-let', NotificationSettingLet)
