import '@material/web/button/elevated-button.js'
import './role-selector.js'

import gql from 'graphql-tag'
import { css, html, LitElement } from 'lit'
import { customElement, property, query } from 'lit/decorators.js'

import { client, gqlContext } from '@operato/graphql'
import { i18next, localize } from '@operato/i18n'
import { OxPrompt } from '@operato/popup/ox-prompt.js'
import { ButtonContainerStyles } from '@operato/styles'

import { RoleSelector } from './role-selector'

@customElement('partner-role-editor')
class PartnerRoleEditor extends localize(i18next)(LitElement) {
  static styles = [
    ButtonContainerStyles,
    css`
      :host {
        display: flex;
        flex-direction: column;

        border: 1px solid var(--md-sys-color-primary);
        padding: var(--spacing-medium);
        font: normal 15px var(--theme-font);
        color: var(--md-sys-color-secondary);
      }

      md-elevated-button {
        margin-right: var(--spacing-small);
      }
    `
  ]

  @property({ type: Object }) customer: any
  @property({ type: Array }) roles: any[] = []
  @property({ type: Array }) grantingRoles: any[] = []

  @query('role-selector') roleSelector!: RoleSelector

  render() {
    const roles = this.roles || []
    const grantingRoles = this.grantingRoles || []

    return html`
      <role-selector .roles="${roles}" .userRoles="${grantingRoles}"></role-selector>

      <div class="button-container">
        <md-elevated-button @click=${this.onSave}>${i18next.t('button.save')}</md-elevated-button>
        <md-elevated-button @click=${this.onTerminateContract} danger
          >${i18next.t('button.terminate contract')}</md-elevated-button
        >
      </div>
    `
  }

  updated(changes) {
    if (changes.has('customer')) {
      this.refreshRoles()
    }
  }

  async refreshRoles() {
    const response = await client.query({
      query: gql`
        query roles($customerId: String!) {
          roles {
            items {
              id
              name
              description
            }
            total
          }
          grantingRoles(customerId: $customerId) {
            id
            role {
              id
              name
              description
            }
          }
        }
      `,
      variables: { customerId: this.customer.id },
      context: gqlContext()
    })

    if (!response.errors?.length) {
      this.roles = response.data.roles.items
      this.grantingRoles = response.data.grantingRoles.map(grantingRole => grantingRole.role)
    } else {
      this.roles = []
      this.grantingRoles = []
    }
  }

  async onSave() {
    const roles = this.roleSelector.selectedRoles()

    const response = await client.mutate({
      mutation: gql`
        mutation grantRoles($customerId: String!, $roles: [RolePatch!]!) {
          grantRoles(customerId: $customerId, roles: $roles)
        }
      `,
      variables: { customerId: this.customer.id, roles },
      context: gqlContext()
    })

    if (!response.errors?.length) {
      this.showToast(i18next.t('text.data_updated_successfully'))
    }
  }

  async onTerminateContract() {
    if (
      await OxPrompt.open({
        title: i18next.t('text.are_you_sure'),
        text: i18next.t('text.are_you_sure_to_terminate_contract'),
        confirmButton: { text: i18next.t('button.terminate contract') },
        cancelButton: { text: i18next.t('button.cancel') }
      })
    ) {
      const response = await client.mutate({
        mutation: gql`
          mutation terminateContract($partnerName: String!) {
            terminateContract(partnerName: $partnerName)
          }
        `,
        variables: { partnerName: this.customer.name },
        context: gqlContext()
      })

      if (!response.errors?.length) {
        const answer = this.dispatchEvent(new CustomEvent('contractTerminated'))

        if (answer) {
          await OxPrompt.open({
            type: 'success',
            title: i18next.t('text.completed'),
            confirmButton: { text: i18next.t('button.confirm') }
          })
        }
      }
    }
  }

  showToast(message) {
    document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }))
  }
}
