import { __decorate, __metadata } from "tslib";
import '@material/web/icon/icon.js';
import '@material/web/button/elevated-button.js';
import './ownership-transfer-popup';
import './role-selector';
import gql from 'graphql-tag';
import { css, html, LitElement } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { connect } from 'pwa-helpers/connect-mixin';
import { client, gqlContext } from '@operato/graphql';
import { i18next } from '@operato/i18n';
import { openPopup } from '@operato/layout';
import { store } from '@operato/shell';
import { OxPrompt } from '@operato/popup/ox-prompt.js';
import { ButtonContainerStyles } from '@operato/styles';
import { InheritedValueType } from '@operato/data-grist';
let UserRoleEditor = class UserRoleEditor extends connect(store)(LitElement) {
    constructor() {
        super(...arguments);
        this.user = {};
        this.activate = false;
        this.domainRoles = [];
        this.grantedRoles = {};
        this.userRoles = [];
        this.isSuperOwner = false;
        this.isDomainOwner = false;
    }
    render() {
        const user = this.user || {};
        const domainRoles = this.domainRoles || [];
        const grantedRoles = this.grantedRoles || {};
        let currentDomainName = 'roles';
        if (domainRoles === null || domainRoles === void 0 ? void 0 : domainRoles.length) {
            currentDomainName = domainRoles[0].domain.name;
        }
        return html `
      ${this.activate
            ? html `
            <ul detail>
              ${user.userType === 'user'
                ? html `
                    <li>
                      <span>
                        ${user.username || user.email} (<md-icon>email</md-icon>
                        ${user.email})
                      </span>
                    </li>
                  `
                : ''}
            </ul>

            <role-selector .user=${this.user} .roles=${domainRoles} .userRoles=${this.userRoles}></role-selector>

            ${Object.keys(grantedRoles).map(partnerName => html `
                <role-selector
                  .roleCategory=${partnerName}
                  .user=${this.user}
                  .roles=${this.grantedRoles[partnerName]}
                  .userRoles=${this.userRoles}
                >
                </role-selector>
              `)}
          `
            : ''}

      <div class="button-container">
        ${this.isRoleEditable()
            ? html ` <md-elevated-button
              @click=${() => {
                const { availableRoles, selectedRoles } = Array.from(this.renderRoot.querySelectorAll('role-selector')).reduce((roles, roleSelector) => {
                    roles.availableRoles = roles.availableRoles.concat(roleSelector.roles.map(r => {
                        delete r.domain;
                        return r;
                    }));
                    roles.selectedRoles = roles.selectedRoles.concat(roleSelector.selectedRoles().map(r => {
                        //@ts-ignore
                        delete r.domain;
                        return r;
                    }));
                    return roles;
                }, { availableRoles: [], selectedRoles: [] });
                this.onSave(user, availableRoles, selectedRoles);
            }}
              >${String(i18next.t('button.save'))}</md-elevated-button
            >`
            : ''}
        ${user.userType === 'user'
            ? html `
              ${this.isTransferable(user) && this.userRoles && this.userRoles.length > 0
                ? html `
                    <md-elevated-button danger @click=${() => this.onTransfer(user)}
                      >${String(i18next.t('button.transfer owner'))}</md-elevated-button
                    >
                  `
                : ''}
              ${this.isPasswordResettable(user)
                ? html `<md-elevated-button danger @click=${() => this.onResetPassword(user)}
                    >${String(i18next.t('title.reset password'))}</md-elevated-button
                  >`
                : ''}
            `
            : ''}
        ${this.isRemovable(user)
            ? html `
              <md-elevated-button danger @click=${() => this.onDelete(user)}
                >${String(i18next.t('button.delete user'))}</md-elevated-button
              >
            `
            : ''}
        ${this.isActivatable(user)
            ? html `<md-elevated-button danger @click=${() => this.onActivate(user)}
              >${String(i18next.t('button.activate'))}</md-elevated-button
            >`
            : ''}
        ${this.isInactivatable(user)
            ? html `<md-elevated-button danger @click=${() => this.onInactivate(user)}
              >${String(i18next.t('button.deactivate'))}</md-elevated-button
            >`
            : ''}
      </div>
    `;
    }
    isRemovable(user) {
        return this.isDomainOwner && user.email !== this.me.email && !user.owner;
    }
    isTransferable(user) {
        return this.activate && (this.isSuperOwner || this.isDomainOwner) && !user.owner;
    }
    isRoleEditable() {
        var _a;
        return this.activate && (((_a = this.domainRoles) === null || _a === void 0 ? void 0 : _a.length) || Object.keys(this.grantedRoles || {}).length);
    }
    isPasswordResettable(user) {
        return (this.isSuperOwner || this.isDomainOwner) && user.email !== this.me.email;
    }
    isActivatable(user) {
        return (this.isSuperOwner || this.isDomainOwner) && !this.activate;
    }
    isInactivatable(user) {
        return ((this.isSuperOwner || this.isDomainOwner) &&
            user.id !== this.domainOwner.id &&
            user.userType !== 'admin' &&
            this.activate);
    }
    async updated(changedProps) {
        var _a;
        if (changedProps.has('user')) {
            this.fetchAvailableRoles();
            if ((_a = this.user) === null || _a === void 0 ? void 0 : _a.email) {
                this.userRoles = await this.fetchRolesOnUser(this.user.email);
            }
            else {
                this.userRoles = [];
            }
        }
    }
    async fetchRolesOnUser(email) {
        var _a;
        const response = await client.query({
            query: gql `
        query ($email: EmailAddress!) {
          user(email: $email) {
            id
            name
            email
            roles {
              id
              name
              description
              domain {
                id
              }
            }
          }
        }
      `,
            variables: { email },
            context: gqlContext()
        });
        if (!response.errors) {
            return ((_a = response.data.user) === null || _a === void 0 ? void 0 : _a.roles) || [];
        }
    }
    async fetchAvailableRoles() {
        var _a;
        const response = await client.query({
            query: gql `
        query roles($inherited: InheritedValueType) {
          roles(inherited: $inherited) {
            items {
              id
              domain {
                name
              }
              name
              description
            }
            total
          }
          grantedRoles {
            id
            role {
              id
              name
              description
              domain {
                name
              }
            }
          }
        }
      `,
            variables: {
                inherited: InheritedValueType.Include
            },
            context: gqlContext()
        });
        if (!((_a = response.errors) === null || _a === void 0 ? void 0 : _a.length)) {
            this.domainRoles = response.data.roles.items || [];
            this.grantedRoles = response.data.grantedRoles.reduce((grantedRoles, grantedRole) => {
                const { role } = grantedRole;
                const { domain } = role;
                if (grantedRoles[domain.name]) {
                    grantedRoles[domain.name].push(role);
                }
                else {
                    grantedRoles[domain.name] = [role];
                }
                return grantedRoles;
            }, {});
        }
        else {
            this.domainRoles = [];
            this.grantedRoles = [];
        }
    }
    async onSave(user, availableRoles, selectedRoles) {
        if (user === null || user === void 0 ? void 0 : user.id) {
            const response = await client.mutate({
                mutation: gql `
          mutation ($username: String!, $availableRoles: [ObjectRef!]!, $selectedRoles: [ObjectRef!]!) {
            updateUserRoles(username: $username, availableRoles: $availableRoles, selectedRoles: $selectedRoles) {
              id
              name
              roles {
                id
                description
              }
            }
          }
        `,
                variables: { username: user.username || user.email, availableRoles, selectedRoles },
                context: gqlContext()
            });
            if (!response.errors) {
                this.showToast(i18next.t('text.data_updated_successfully'));
                this.dispatchUserUpdated();
            }
        }
    }
    async onActivate(user) {
        const response = await client.mutate({
            mutation: gql `
        mutation activateUser($username: String!) {
          activateUser(username: $username)
        }
      `,
            variables: { username: user.username || user.email },
            context: gqlContext()
        });
        if (!response.errors) {
            this.showToast(i18next.t('text.user activated successfully'));
            this.dispatchUserUpdated();
        }
    }
    async onInactivate(user) {
        const response = await client.mutate({
            mutation: gql `
        mutation inactivateUser($username: String!) {
          inactivateUser(username: $username)
        }
      `,
            variables: { username: user.username || user.email },
            context: gqlContext()
        });
        if (!response.errors) {
            this.showToast(i18next.t('text.user inactivated successfully'));
            this.dispatchUserUpdated();
        }
    }
    async onDelete(user) {
        if (user.owner) {
            await OxPrompt.open({
                type: 'warning',
                title: i18next.t('text.cannot_delete'),
                text: i18next.t('text.x_cannot_delete', {
                    x: i18next.t('label.domain-owner')
                }),
                confirmButton: { text: i18next.t('button.confirm') }
            });
            return;
        }
        if (await OxPrompt.open({
            title: i18next.t('text.are_you_sure'),
            text: i18next.t('text.are_you_sure_to_x_user', {
                x: i18next.t('button.delete')
            }),
            confirmButton: { text: i18next.t('button.delete') },
            cancelButton: { text: i18next.t('button.cancel') }
        })) {
            const response = await client.mutate({
                mutation: gql `
          mutation deleteDomaineUser($username: String!) {
            deleteDomainUser(username: $username)
          }
        `,
                variables: { username: user.username || user.email },
                context: gqlContext()
            });
            if (!response.errors) {
                await OxPrompt.open({
                    type: 'success',
                    title: i18next.t('text.completed'),
                    confirmButton: { text: i18next.t('button.confirm') }
                });
                this.dispatchUserUpdated();
            }
        }
    }
    async onTransfer(user) {
        openPopup(html `
        <ownership-transfer-popup
          .user=${user}
          @ownershipTransferred="${this.dispatchOwnershipTransferred.bind(this)}"
        ></ownership-transfer-popup>
      `, {
            size: 'small',
            title: `${i18next.t('title.owner_transfer')}`
        });
    }
    async onResetPassword(user) {
        if (await OxPrompt.open({
            title: i18next.t('text.are_you_sure'),
            text: i18next.t('text.are_you_sure_to_x', { x: i18next.t('title.reset password') }),
            confirmButton: { text: i18next.t('button.confirm') },
            cancelButton: { text: i18next.t('button.cancel') }
        })) {
            const response = await client.mutate({
                mutation: gql `
          mutation resetPasswordToDefault($username: String!) {
            resetPasswordToDefault(username: $username)
          }
        `,
                variables: { username: user.username || user.email },
                context: gqlContext()
            });
            if (!response.errors) {
                await OxPrompt.open({
                    type: 'success',
                    title: i18next.t('text.completed'),
                    text: i18next.t('text.password reset succeed'),
                    confirmButton: { text: i18next.t('button.confirm') }
                });
            }
        }
    }
    dispatchUserUpdated() {
        this.dispatchEvent(new CustomEvent('userUpdated'));
    }
    dispatchOwnershipTransferred() {
        this.dispatchEvent(new CustomEvent('ownershipTransferred'));
    }
    showToast(message) {
        document.dispatchEvent(new CustomEvent('notify', { detail: { message, option: { timer: 1000 } } }));
    }
    stateChanged(state) {
        var _a;
        this.me = ((_a = state.auth) === null || _a === void 0 ? void 0 : _a.user) || {};
        this.isSuperOwner = this.me.super || false;
        this.isDomainOwner = this.me.email === this.domainOwner.email || false;
    }
};
UserRoleEditor.styles = [
    ButtonContainerStyles,
    css `
      :host {
        display: flex;
        flex-direction: column;

        border: 1px solid var(--md-sys-color-primary);
        font: normal 15px var(--theme-font);
        color: var(--md-sys-color-secondary);
      }
      ul {
        flex: 1;
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: 20px;

        overflow: auto;
        margin: 0;
        padding: var(--spacing-medium);
        list-style: none;
        border: 1px dashed rgba(0, 0, 0, 0.1);
        border-width: 1px 0;
      }
      input[readonly] {
        border: none;
        background-color: transparent;
        color: var(--md-sys-color-secondary);
        font: var(--input-font);
      }
      li {
        padding: var(--spacing-small);
      }
      [detail] {
        background-color: var(--md-sys-color-surface);
      }
      [detail] md-icon {
        --md-icon-size: var(--fontsize-default);
        vertical-align: middle;
        color: var(--md-sys-color-primary);
      }
      [detail] li {
        display: flex;
      }
      [detail] li input {
        flex: 1;
      }

      md-elevated-button {
        margin: 5px;
      }

      md-outlined-button {
        background-color: var(--md-sys-color-surface-variant);
      }

      @media screen and (max-width: 480px) {
        ul {
          grid-template-columns: 1fr;
        }
      }
    `
];
__decorate([
    property({ type: Object }),
    __metadata("design:type", Object)
], UserRoleEditor.prototype, "user", void 0);
__decorate([
    property({ type: Boolean }),
    __metadata("design:type", Boolean)
], UserRoleEditor.prototype, "activate", void 0);
__decorate([
    property({ type: Object }),
    __metadata("design:type", Object)
], UserRoleEditor.prototype, "domainOwner", void 0);
__decorate([
    state(),
    __metadata("design:type", Array)
], UserRoleEditor.prototype, "domainRoles", void 0);
__decorate([
    state(),
    __metadata("design:type", Object)
], UserRoleEditor.prototype, "grantedRoles", void 0);
__decorate([
    state(),
    __metadata("design:type", Array)
], UserRoleEditor.prototype, "userRoles", void 0);
__decorate([
    state(),
    __metadata("design:type", Boolean)
], UserRoleEditor.prototype, "isSuperOwner", void 0);
__decorate([
    state(),
    __metadata("design:type", Boolean)
], UserRoleEditor.prototype, "isDomainOwner", void 0);
UserRoleEditor = __decorate([
    customElement('user-role-editor')
], UserRoleEditor);
//# sourceMappingURL=user-role-editor.js.map