import { LasalRuntimeSigElement, SigPolymer } from '../../sigmatek/sig-element/sig-element.js';
import { Usermanager } from "../sig-control-user-mixin/sig-control-user-mixin.js";
import "../sig-control-input/sig-control-input.js";
import "../sig-control-button/sig-control-button.js";
import "../sig-control-listview/sig-control-listview.js";
import "../sig-control-titlebar/sig-control-titlebar.js";
import "../sig-control-input/sig-control-input-css.js";
import "../sig-control-button/sig-control-button-css.js";
import "../sig-control-titlebar/sig-control-titlebar-css.js";
import "../sig-control-listview/sig-control-listview-css.js";
import "../sig-control-scrollbar/sig-control-scrollbar-css.js";

export class LasalRuntimeSigControlRoleDetail extends Usermanager(LasalRuntimeSigElement) {

    static get is() {
        return "sig-control-role-detail";
    }

    static get importMeta() { return import.meta; }

    static get template() {
        return SigPolymer.html`
                 <style
            include="sig-element-css sig-control-input-css sig-control-button-css sig-control-listview-css sig-control-titlebar-css sig-control-scrollbar-css">
            :host {
                
                color: var(--theme-sig-control-role-detail-color, rgba(255, 255, 255, 1));
                background-color: var(--theme-sig-control-role-detail-background-color, rgba(204,204,204,1.0));

                border-width: var(--theme-sig-control-role-detail-border-width, 0);
                border-color: var(--theme-sig-control-role-detail-border-color, transparent);
                border-style: var(--theme-sig-control-role-detail-border-style, none);
                border-radius: var(--theme-sig-control-role-detail-border-radius, 0);

                
                display: block;
                position: absolute;
                overflow: var(--theme-sig-control-role-detail-overflow, hidden);
            }

            :host * {
                
                @apply --notextselect;
                margin: 0;
                padding: 0;
            }

            .clearfix:after {
                
                @apply --clearfix
            }

            .sig-control-role-detail {
                
                position: relative;
                width: 100%;
                height: 100%;
                
                text-decoration: inherit;
            }

            .label {
                height: auto;
                display: block;
                font-size: var(--theme-sig-control-role-detail-label-font-size, 11px);
                color: var(--theme-sig-control-role-detail-label-color, rgba(215, 215, 215, 1));
                text-align: left;
            }

            .inputs {
                clear: both;
                display: none;
                flex: 0 1 auto;
                height: auto;
            }

            .floatleft {
                float: left;
                width: calc(50% - 5px);
                margin: 0 0 10px 0 !important;
                padding: 0 5px 0 0 !important;
                height: auto;
            }

            .floatright {
                float: right;
                width: 50%;
                height: auto;
            }

            .clear {
                clear: both;
                height: auto;
            }

            .input {
                width: 100%;
                height: 30px;
                position: unset;
                background-color: white;
                margin-bottom: 10px !important;
            }

            .input.last {
                margin-bottom: 0;
            }

            .buttons {
                clear: both;
                border-top: 1px solid var(--theme-sig-control-role-detail-button-horizontal-separator-color, rgba(255, 255, 255, 1));
                height: auto;
                padding: 0 10px !important;
            }

            .button {
                position: unset;
            }

            .button.default {
                margin: var(--theme-sig-control-role-detail-button-margin, 10px) 0;
            }

            .button.right {
                margin-left: var(--theme-sig-control-role-detail-button-margin, 10px);
                float: right;
            }

            .button.left {
                margin-right: var(--theme-sig-control-role-detail-button-margin, 10px);
                float: left;
            }

            .button.disabled {
                opacity: var(--theme-sig-control-role-detail-button-disabled-opacity, .4);
                pointer-events: none !important;
            }

            .permissions {
                display: none;
                flex: 1 1 100%;
                position: relative;
                min-height: 45px;
                overflow: auto;
            }

            .permissionlist {
                top: 0;
                left: 0;
                
                min-width: 100%;
                width: 100%;
                min-height: 100%;
                height: 100%;
            }

            .content {
                display: flex;
                flex-flow: column;
                align-items: stretch;
                height: 100%;
                background-color: var(--theme-sig-control-role-detail-background-color, rgba(204,204,204,1.0));
            }

            .form {
                overflow: auto;
                margin: 10px 10px !important;
                flex: 1 1 100%;
                width: calc(100% - 20px);
                height: 100%;
            }

            .inner {
                display: flex;
                flex-flow: column;
                align-items: stretch;
                height: 100%;
            }

            .title {
                height: auto;
                flex: 0 1 auto;
            }

            :host([mode="view"]) .inputs,
            :host([mode="update"]) .inputs,
            :host([mode="create"]) .inputs,
            :host([mode="view"]) .permissions,
            :host([mode="update"]) .permissions,
            :host([mode="create"]) .permissions,
            :host([isdesignmode]) .inputs,
            :host([isdesignmode]) .permissions {
                display: block !important;
            }

            .idle {
                width: 100%;
                height: 100%;
                color: inherit;
                padding: 20px 0 !important;
                text-align: center;
                display: none;
            }

            :host([mode="idle"]) .idle {
                display: block;
            }

            :host([isdesignmode]) .idle {
                display: none;
            }

            :host(:not([isdesignmode])) .inactive {
                pointer-events: none !important;
                opacity: .8;
                height: auto;
            }

            .hidden {
                display: none;
            }


            :host([hidebuttons]) .buttons,
            :host([hidetitle]) .title,
            :host([hidepermissionlist]) .permissions,
            :host([hideinputs]) .inputs,
            :host([hidelabels]) .label,
            :host([hidepermissionlist]) label.list {
                display: none !important;
            }

            :host sig-control-button {

                height: var(--theme-sig-element-height, 40px);
                width: var(--theme-sig-element-width, 90px); 
                
                
                --theme-sig-control-button-padding: 2px;
            }

            :host sig-control-input {
               
                height: var(--theme-sig-element-height, 26px);
            
                --theme-sig-control-input-placeholder-color: var(--theme-sig-control-role-detail-input-placeholder-color, rgba(142, 142, 142, 1));
                --theme-sig-control-input-field-position: relative;

            }

            :host sig-control-titlebar {
                position: unset;
                display: block;
                width:100%;
                
                height: var(--theme-sig-element-height, 26px);
            }

            :host sig-control-listview {
                position: unset;
            }

         
        </style>
        <div class="sig-control-role-detail clearfix">
            <div class="content">
                <div class="title">
                    <sig-control-titlebar id="titlebar" value="[[texts.caption]]"
                        shadowactive="[[titlebarshadowactive]]" applybordereffect="[[applybordereffect]]">
                    </sig-control-titlebar>
                </div>
                <div id="form" class="form">
                    <div id="inner" class="inner">
                        <div id="idle" class="idle">
                            [[texts.pleaseSelectRoleFirst]]
                            <template is="dom-if" if="[[permissions.createRole]]">
                                [[texts.orAddRole]]
                            </template>
                        </div>

                        <div id="inputs" class="inputs">
                            <div class="clear">
                                <sig-control-input id="id" class="input default hidden" placeholder="ID"
                                    titletext="[[texts.kbEnterRoleId]]" shadowactive="[[inputfieldshadowactive]]"
                                    shadowpressedactive="[[inputfieldshadowactive]]">
                                </sig-control-input>
                                <label class="label">[[texts.roleName]]</label>
                                <sig-control-input id="rolename" class="input default" placeholder=[[texts.roleName]]
                                    titletext="[[texts.kbEnterRoleName]]" shadowactive="[[inputfieldshadowactive]]"
                                    shadowpressedactive="[[inputfieldshadowactive]]">
                                </sig-control-input>
                                <label class="label">[[texts.description]]</label>
                                <sig-control-input id="info" class="input default" placeholder=[[texts.description]]
                                    titletext="[[texts.kbEnterDescription]]" shadowactive="[[inputfieldshadowactive]]"
                                    shadowpressedactive="[[inputfieldshadowactive]]">
                                </sig-control-input>
                                <label class="label">[[texts.timeout]]</label>
                                <sig-control-input id="timeout" class="input default" placeholder=[[texts.timeout]]
                                    titletext="[[texts.kbEnterTimeout]]" shadowactive="[[inputfieldshadowactive]]"
                                    type="numeric" ignoremin ignoremax shadowpressedactive="[[inputfieldshadowactive]]">
                                </sig-control-input>
                                <label class="label">[[texts.accessLevel]]</label>
                                <sig-control-input id="accesslevel" class="input default"
                                    placeholder=[[texts.accessLevel]] titletext="[[texts.kbEnterAccessLevel]]"
                                    shadowactive="[[inputfieldshadowactive]]"
                                    shadowpressedactive="[[inputfieldshadowactive]]">
                                </sig-control-input>
                                <label class="label">[[texts.accessLevelRead]]</label>
                                <sig-control-input id="accesslevelread" class="input default"
                                    placeholder=[[texts.accessLevelRead]] titletext="[[texts.kbEnterAccessLevelRead]]"
                                    shadowactive="[[inputfieldshadowactive]]"
                                    shadowpressedactive="[[inputfieldshadowactive]]">
                                </sig-control-input>
                                <label class="label">[[texts.accessNumber]]</label>
                                <sig-control-input id="accessnumber" class="input default"
                                    placeholder=[[texts.accessNumber]] titletext="[[texts.kbEnterAccessNumber]]"
                                    shadowactive="[[inputfieldshadowactive]]"
                                    shadowpressedactive="[[inputfieldshadowactive]]"
                                    type="numeric" ignoremin ignoremax>
                                </sig-control-input>
                                <div class="clear">
                                    <label class="label list">[[texts.permissions]]</label>
                                </div>
                            </div>
                        </div>

                        <div class="permissions">
                            <sig-control-listview id="listview" class="permissionlist"></sig-control-listview>
                        </div>
                    </div>
                </div>

                <div id="buttons" class="buttons clearfix">
                    <template is="dom-if" if="[[!hidebuttons]]">

                        <template is="dom-if"
                            if="[[_isValidButton('save','updateRole; createRole', permissions, mode, timestamp)]]">
                            <sig-control-button id="saverole" sigbtntext="[[texts.save]]" class="button default right"
                                on-up="_saveRole"></sig-control-button>
                        </template>
                        <template is="dom-if" if="[[_isValidButton('cancel', 'none', permissions, mode, timestamp)]]">
                            <sig-control-button id="cancel" sigbtntext="[[texts.cancel]]" class="button default left"
                                on-up="_cancel"></sig-control-button>
                        </template>
                        <template is="dom-if"
                            if="[[_isValidButton('edit', 'updateRole', permissions, mode, timestamp)]]">
                            <sig-control-button id="editrole" sigbtntext="[[texts.edit]]" class="button default right"
                                on-up="_editRole"></sig-control-button>
                        </template>
                        <template is="dom-if"
                            if="[[_isValidButton('new', 'createRole', permissions, mode, timestamp)]]">
                            <sig-control-button id="newrole" sigbtntext="[[texts.new]]" class="button default right"
                                on-up="_newRole"></sig-control-button>
                        </template>

                    </template>
                </div>

            </div>
        </div>`;
    }

    static get properties() {
        let props = {
            isloggedin: {
                type: Boolean,
                value: false,
                observer: '_toggleIsLoggedin'
            },
            activeuser: {
                type: Object,
                value: null,
                observer: '_updateUserPermissions'
            },
            hidetitle: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            hidebuttons: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            hideinputs: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            hidepermissionlist: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            hidelabels: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            mode: {
                type: String,
                value: 'idle', 
                observer: '_updateMode',
                reflectToAttribute: true
            },
            isEditing: {
                type: Boolean,
                value: false,
                observer: '_toggleForm'
            },
            role: {
                type: Object,
                value: null,
                observer: '_updateForm'
            },
            inputfieldshadowactive: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            titlebarshadowactive: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            titletext: {
                type: String,
                value: '',
                observer: '_switchLang'
            },
            listviewisactive: {
                type: Boolean,
                value: false,
                observer: '_toggleListView'
            }
        }
        return props;
    }

    constructor() {
        super();
        this.umApi = window.sigApi.userManager;
        this.wmApi = window.sigApi.windowManager;
        this.tmApi = window.sigApi.textManager;
        this.utilsApi = window.sigApi.sigUtils;
        this.constApi = (window.sigApi && window.sigApi.SIG_CONST) ? window.sigApi.SIG_CONST : null;
        this.controlTextList = this.getControlTextListName();
        this.allowedButtons = [];
        this.iswindow = false;
        this.permissions = {};
        this.data = null;
        this.config = null;
        this.closeafterupdate = false;
        this.closeaftercreate = false;
        this.closeaftercancel = false;
        this.backuprole = null;
        this.source = null;
        this.timestamp = Date.now();
        this.selectedPermission = null;
        this.markedPermissions = null;
        this.clearPermissions = false;
        this.applybordereffect = false;
        this.texts = {};

        if (!this.isdesignmode) {
            this.sigAddEventListener('LANGUAGE_CHG', (majorId, minorId, msg) => {
                this._switchLang(majorId, minorId, msg);
            }, 'runtimeEvent');

            this.sigAddEventListener('ROLE_CREATED', (majorId, minorId, msg) => {
                this._roleCreated(majorId, minorId, msg);
            }, 'runtimeEvent');

            this.sigAddEventListener('ROLE_UPDATED', (majorId, minorId, msg) => {
                this._roleUpdated(majorId, minorId, msg);
            }, 'runtimeEvent');

            this.sigAddEventListener('ROLE_DELETED', (majorId, minorId, msg) => {
                this._roleDeleted(majorId, minorId, msg);
            }, 'runtimeEvent');

            this.sigAddEventListener('USER_LOGGED_IN', (majorId, minorId, msg) => {
                this._userLoggedIn(majorId, minorId, msg);
            }, 'runtimeEvent');

            this.sigAddEventListener('USER_LOGGED_OUT', (majorId, minorId, msg) => {
                this._userLoggedOut(majorId, minorId, msg);
            }, 'runtimeEvent');

            this.sigAddEventListener('SEND_USER_DATA', (majorId, minorId, msg) => {
                this._receivedData(majorId, minorId, msg);
            }, 'runtimeEvent');
        }
    }

    connectedCallback() {
        super.connectedCallback();
        this._init();
    }

    disconnectedCallback() {
        super.disconnectedCallback();
        this.umApi = null;
        this.wmApi = null;
        this.tmApi = null;
        this.utilsApi = null;
        this.allowedButtons = null;
        this.permissions = null;
        this.data = null;
        this.config = null;
        this.backuprole = null;
        this.source = null;
        this.selectedPermission = null;
        this.markedPermissions = null;
        this.activeuser = null;
        this.texts = null;
    }

    _init() {
        this.isloggedin = this.umApi.isUserLoggedIn();
        this._switchLang();
        this._setRoleListProps();
        SigPolymer.afterNextRender(this, function (params) {
            if (this.context) this.iswindow = (this.context.type === 'window') ? true : false;
            if (this.iswindow) {
                this.$.listview.disableautodeactivate = true;

                this.sigAddEventListener('jspanelbeforeclose', (evt) => {
                    if (evt.detail === this.context.instanceId) {
                        this._clearForm();
                        this._switchMode('idle');
                    }
                }, 'jsEvent', document);
            }

            this._applFontObjects();
            if (this.isdesignmode) this.listviewisactive = true;
        });
    }

    _hasNoErrors(result) {
        return (result.status || result.message || result.stack) ? false : true;
    }

    async _switchLang(majorId, minorId, msg) {
        if (this.tmApi) {
            const texts = await this.tmApi.getTextsAsync(this._getTextsObject());
            if (this.titletext !== '') texts[this.controlTextList].caption = this.titletext;
            this.texts = texts[this.controlTextList];
        }
        this._renderPermissionList();
    }

    designerOnLanguageChanged() {
        this._switchLang();
    }

    async designerOnObjectStoreUpdate(data) {
        const textListChanged = await this.tmApi.isTextListUpdate(data, this.controlTextList);
        if (textListChanged) this._switchLang();
    }

    _getTextsObject() {
        return {
            [this.controlTextList]: {
                caption: 'Role detail',
                id: 'ID',
                roleName: 'Rolename',
                description: 'Description',
                roles: 'Roles',
                permissions: 'Permissions',
                timeout: 'Timeout',
                accessLevel: 'Access logic writing',
                accessLevelRead: 'Access logic reading',
                accessNumber: 'Accessnumber',
                edit: 'Edit',
                view: 'View',
                save: 'Save',
                cancel: 'Cancel',
                new: 'New',
                pleaseLoginToSeeAllOptions: 'Please login to see all options',
                pleaseSelectRoleFirst: 'Please select a role first',
                orAddRole: 'or add a new one',
                kbEnterRoleId: 'Enter a role id',
                kbEnterRoleName: 'Enter a role name',
                kbEnterDescription: 'Enter a description',
                kbEnterTimeout: 'Enter a timout',
                kbEnterAccessLevel: 'Enter a accesslevel',
                kbEnterAccessLevelRead: 'Enter a read accesslevel',
                kbEnterAccessNumber: 'Enter a accessnumber'
            }
        }
    }

    _roleCreated(majorId, minorId, msg) {
        this.role = msg.role;
        this._renderPermissionList();
    }

    _roleUpdated(majorId, minorId, msg) {
        if (this.role !== null && this.role.id === msg.role.id && !this.isEditing) {
            this.role = msg.role;
            this._renderPermissionList();
        }
    }

    _roleDeleted(majorId, minorId, msg) {
        if ((this.role !== null && this.role.id === msg.id) || (this.role !== null && this.role.name === msg.name)) {
            this._clearRole();
            this._switchMode('idle');
        }
    }

    _userLoggedIn(majorId, minorId, msg) {
        const user = msg.user;
        if (this.isloggedin && user && this.activeuser.id !== user.id) this.isloggedin = false;
        this.isloggedin = true;
    }

    _userLoggedOut(majorId, minorId, msg) {
        this.isloggedin = false;
    }

    _setRoleListProps() {
        this.$.listview.disablekeys = false;
        this.$.listview.disablemultiselect = false;
        this.$.listview.hideheader = true;
        this.$.listview.activemarked = true;
    }

    async _renderPermissionList() {
        if (this.disconnected) return;
        let permissions = {};
        if (!this.isdesignmode) {
            const uid = this.utilsApi.getUID();
            if (this.isEditing && this.permissions.grantRole) {
                this.listviewisactive = true;
            }
            if (this.mode === 'create') {
                const result = await this.umApi.getDefaultPermissions(uid).catch(error => error);
                if (this._hasNoErrors(result)) permissions = result.permissions;
            }
            else if (this.role && this.role.id) {
                const result = await this.umApi.getRole(this.role.id).catch(error => error);
                if (this._hasNoErrors(result)) {
                    permissions = result.role.permissions;
                    this.role.permissions = permissions;
                }
                else {
                    console.debug('DEBUG ONLY: Role (ID) not found in DS - try to use role-object!');
                    if (this.role.permissions) permissions = this.role.permissions;
                }
            }
            else if (this.role && this.role.name) {
                const result = await this.umApi.getRoleDetail(this.role.name, uid).catch(error => error);
                if (this._hasNoErrors(result)) {
                    permissions = result.role.permissions;
                    this.role.permissions = permissions;
                    if (!this.role.id && result.role.id) this.role.id = result.role.id;
                }
                else {
                    console.debug('DEBUG ONLY: Role (NAME) not found in DS - try to use role-object!');
                    if (this.role.permissions) permissions = this.role.permissions;
                }
            }
        } else {
            permissions =
            {
                permission1: true,
                permission1: true,
                permission2: true,
                permission3: true
            };
        }
        let _listObj = [];
        Object.keys(permissions).forEach((permission, _listObjId) => {
            let _permission = null;
            if (this.isEditing && this.permissions.grantRole) _permission = { id: _listObjId, permissionName: permission, marked: permissions[permission] };
            else if (permissions[permission] === true) _permission = { id: _listObjId, permissionName: permission, marked: false };
            if (_permission) _listObj.push(_permission);
        });

        if (this.isdesignmode) {
            _listObj = [
                {
                    id: 0,
                    permissionName: 'permission0 - selected',
                    active: true
                },
                {
                    id: 1,
                    permissionName: 'permission1 - selected marked',
                    marked: true,
                    active: true
                },
                {
                    id: 2,
                    permissionName: 'permission2 - alternate (odd)'
                },
                {
                    id: 3,
                    permissionName: 'permission3 - normal (even)'
                },
                {
                    id: 4,
                    permissionName: 'permission4 - marked',
                    marked: true
                }];
        }

        this.data = {
            "cols": [{
                "id": "id",
                "name": "id",
                "type": "text",
                "default": "&nbsp;",
                "visible": false,
                "sortable": false
            },
            {
                "id": "marked",
                "name": "marked",
                "type": "symbol",
                "default": "&nbsp;",
                "visible": this.listviewisactive,
                "sortable": false,
                "formatDataCallback": this._formatMarked,
                "css": {
                    "width": "20px",
                    "min-width": "20px"
                }
            },
            {
                "id": "permissionName",
                "name": "permission",
                "type": "text",
                "default": "&nbsp;",
                "visible": true,
                "sortable": false
            }],
            "data": {
                "nodes": _listObj
            }
        }
        this.config = {
            updateSelectionCallback: (data, pane) => {
                this._updateSelection(data, pane);
            },
            updateActiveRowCallback: (data, pane) => {
                this._updateActiveRow(data, pane);
            },
            clickCallback: (data, pane) => {
                this._updateMarkedRow(data, pane);
            },
            data: this.data,
            name: "roledetail"
        };
        this.$.listview.config = this.config;
    }

    _updateSelection(permission, pane) {
        this.markedPermissions = permission;
        if (!this.markedPermissions) this.clearPermissions = true;
        else this.clearPermissions = false;
    }

    _updateActiveRow(permission, pane) {
        this.selectedPermission = permission;
        if (permission.marked) {
            permission.marked = false;
        }
    }

    _updateMarkedRow(row, pane) {
        this.$.listview._markRowById();
    }

    _clearInputs() {
        this.$.rolename.value = '';
        this.$.password.value = '';
        this.$.listview._clearActiveRow(true);
    }

    _closeWindow() {
        if (this.context.type === 'window') {
            const window = document.getElementById(this.context.instanceId);
            if (window instanceof HTMLElement) window.close();
        }
    }

    _updateMode(newval, oldval) {
        switch (newval) {
            case 'idle':
                this.isEditing = false;
                this.allowedButtons = ['new'];
                break;
            case 'view':
                this.isEditing = false;
                if (this.role.readOnly !== true) this.allowedButtons = ['edit'];
                else this.allowedButtons = [''];
                break;
            case 'update':
                this.isEditing = true;
                if (this.role.readOnly !== true) this.allowedButtons = ['save', 'cancel'];
                else this.allowedButtons = ['cancel'];
                break;
            case 'create':
                this.isEditing = true;
                this.allowedButtons = ['save', 'cancel'];
                break;
            default:
                this.isEditing = false;
                this.allowedButtons = ['nada'];
                break;
        }
    }

    _isValidButton(button, permission, permissions, mode) {
        if ((!this.isloggedin && !this.isdesignmode) || this.disconnected) return false;
        let _isPermitted = false;
        const _permArr = permission.split(';');
        if (this.allowedButtons.indexOf(button) >= 0) {
            const allowedPerms = _permArr.filter((_permission) => (permissions[_permission.trim()] || _permission === 'none'));
            if (allowedPerms.length > 0 || this.isdesignmode) _isPermitted = true;
        }
        if (_isPermitted) setTimeout(() => this._setButtonState(), 0);
        return _isPermitted;
    }

    _receivedData(majorId, minorId, msg) {
        this.clearPermissions = false;
        this.markedPermissions = null;
        if (this._isValidEvent(msg.type, msg.target, msg.source)) {

            if (!this.isEditing && msg.type === 'role') {
                switch (msg.data.mode) {
                    case 'view':
                        this._viewRole(msg.data.role);
                        break;
                    case 'update':
                        const hasAccess = (msg.data.role && msg.data.role.accessNumber !== undefined) ? this._checkAccess(msg.data.role.accessNumber) : false;
                        if (hasAccess) this._editRole(msg.data.role);
                        else this._viewRole(msg.data.role);
                        break;
                    case 'create':
                        this._newRole();
                        break;
                }
            }
        }
    }

    _updateForm(newval, oldval) {
        if (newval instanceof Object) {
            if (newval.id || newval.id === 0) this.$.id.value = newval.id
            if (newval.name !== null && newval.name !== undefined) this.$.rolename.value = newval.name;
            else this.$.rolename.value = "";
            if (newval.timeout !== null && newval.timeout !== undefined) this.$.timeout.value = newval.timeout;
            else this.$.timeout.value = "";
            if (newval.accessLevel !== null && newval.accessLevel !== undefined) this.$.accesslevel.value = newval.accessLevel;
            else this.$.accesslevel.value = "";
            if (newval.accessLevelRead !== null && newval.accessLevelRead !== undefined) this.$.accesslevelread.value = newval.accessLevelRead;
            else this.$.accesslevelread.value = "";
            if (newval.accessNumber !== null && newval.accessNumber !== undefined) this.$.accessnumber.value = newval.accessNumber;
            else this.$.accessnumber.value = "";
            if (newval.info !== null && newval.info !== undefined) this.$.info.value = newval.info;
            else this.$.info.value = "";
            this._renderPermissionList();
        } else {
            this._clearForm();
        }
    }

    async _toggleIsLoggedin(newval, oldval) {
        if (this.disconnected) return;
        if (newval) {
            if (this.activeuser === null) {
                const uid = this.utilsApi.getUID();
                const result = await this.umApi.getActiveUser(uid).catch(error => {
                    return error;
                });
                if (this._hasNoErrors(result)) {
                    this.activeuser = result.user;
                } else {
                    console.error(result);
                }
            }
        } else {
            this._clearRole();
            this._switchMode('idle');
            this.activeuser = null;
        }
    }

    _toggleForm(newval, oldval) {
        if (newval) {
            this.$.inputs.classList.remove('inactive');
            if (this.permissions.grantRole) {
                this.listviewisactive = true;
            } else {
                this.listviewisactive = false;
            }
        } else {
            this.$.inputs.classList.add('inactive');
            this.listviewisactive = false;
        }
    }

    _viewRole(role = null) {
        this.role = role;
        this._backupRole();
        this.mode = 'neutral';
        this._switchMode('view');
    }

    _editRole(role = null) {
        if (!(role instanceof Event)) this.role = role;
        this._backupRole();
        this._switchMode('update');
    }

    _newRole() {
        this._clearRole(true, false);
        this._prefillFields();
        this.clearPermissions = true;
        this._switchMode('create');
    }

    _prefillFields() {
        this.role = {
            timeout: 0,
            accessLevelRead: this.constApi.USER_ACCESS_LEVEL_READ,
            accessLevel: this.constApi.USER_ACCESS_LEVEL_WRITE,
            accessNumber: this.constApi.USER_ACCESS_NUMBER
        }
    }

    _saveRole() {
        this._saveForm();
    }

    _cancel() {
        if (this.backuprole !== null) {
            this._restoreRole();
            if (this.mode === 'update') {
                this.mode = 'neutral';
                this._switchMode('view');
            } else {
                this._switchMode('idle');
            }
        } else {
            this._switchMode('idle');
        }
        if (this.closeaftercancel) {
            this._closeWindow();
        }
    }

    _switchMode(mode) {
        this.mode = mode;
        this._renderPermissionList();
        if (this.mode === mode) {
            this.timestamp = Date.now();
        }
    }

    async _updateRole() {
        if (this.disconnected) return;
        const uid = this.utilsApi.getUID();
        const result = await this.umApi.updateRole(this.role, this.id, undefined, undefined, uid).catch(error => {
            return error;
        })

        if (this._hasNoErrors(result)) {
            this._backupRole();
        } else {
            await this._showAlert(result.errortxt, this._getTextObj('alertTitle', [result.status])).catch(error => {
                return error;
            });

            this._restoreRole();
        }
        this._switchMode('view');
        if (this.closeafterupdate) {
            this._closeWindow();
        }
    }

    async _createRole() {
        if (this.disconnected) return;
        const uid = this.utilsApi.getUID();
        const result = await this.umApi.createRole(this.role, this.id, undefined, undefined, uid).catch(error => {
            return error;
        })
        if (this._hasNoErrors(result)) {
            if (result.data[0]) this.role = result.data[0];
            this._backupRole();
        } else {
            await this._showAlert(result.errortxt, this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
            this._restoreRole();
        }
        this._switchMode('view');
        if (this.closeaftercreate) {
            this._closeWindow();
        }
    }

    _saveForm() {
        if (this.role === null) this.role = {};
        if (this.$.rolename.value) this.role.name = this.$.rolename.value;
        else {
            this._showAlert(this._getTextObj('roleCouldnotBeCreated'), this._getTextObj('caption')).catch(error => {
                this._log(error);
                return false;
            });
            return false;
        }
        if (!this.umApi.isValidRolename(this.role.name)) {
            this._showAlert(this._getTextObj('roleCouldnotBeCreated'), this._getTextObj('caption')).catch(error => {
                this._log(error);
                return error;
            });
            return false;
        }

        this.role.info = this.$.info.value;
        if (this.$.timeout.value) this.role.timeout = this.$.timeout.value;
        else this.role.timeout = 0;
        if (this.$.accesslevel.value) this.role.accessLevel = this.$.accesslevel.value;
        else {
            this._showAlert(this._getTextObj('roleCouldnotBeCreated'), this._getTextObj('caption')).catch(error => {
                this._log(error);
                return false;
            });
            return false;
        }
        if (!this.umApi.isValidAccessString(this.role.accessLevel)) {
            this._showAlert(this._getTextObj('roleCouldnotBeCreated'), this._getTextObj('caption')).catch(error => {
                this._log(error);
                return error;
            });
            return false;
        }
        if (this.$.accesslevelread.value) this.role.accessLevelRead = this.$.accesslevelread.value;
        else {
            this._showAlert(this._getTextObj('roleCouldnotBeCreated'), this._getTextObj('caption')).catch(error => {
                this._log(error);
                return false;
            });
            return false;
        }
        if (!this.umApi.isValidAccessString(this.role.accessLevelRead)) {
            this._showAlert(this._getTextObj('roleCouldnotBeCreated'), this._getTextObj('caption')).catch(error => {
                this._log(error);
                return error;
            });
            return false;
        }
        if (this.$.accessnumber.value) this.role.accessNumber = this.$.accessnumber.value;
        else {
            this._showAlert(this._getTextObj('roleCouldnotBeCreated'), this._getTextObj('caption')).catch(error => {
                this._log(error);
                return false;
            });
            return false;
        }
        if (!this.umApi.isValidAccessString(this.role.accessNumber)) {
            this._showAlert(this._getTextObj('roleCouldnotBeCreated'), this._getTextObj('caption')).catch(error => {
                this._log(error);
                return error;
            });
            return false;
        }

        if (!this._validateAccessNumberFormat(this.role.accessNumber)) {
            this._showAlert(this._getTextObj('accessNumberInvalid'), this._getTextObj('caption')).catch(error => {
                this._log(error);
                return error;
            });
            return;
        }
        this._setRolePermissions();
    }

    async _setRolePermissions() {
        if (this.disconnected) return;
        const uid = this.utilsApi.getUID();
        if (this.permissions.grantRole && (!this.role.permissions || this.clearPermissions === true)) {
            const result = await this.umApi.getDefaultPermissions(uid).catch(error => error);
            if (this._hasNoErrors(result)) {
                this.role.permissions = result.permissions;
            }
        }
        if (this.permissions.grantRole && (this.role.permissions && this.markedPermissions !== null)) {
            Object.keys(this.role.permissions).forEach(permission => {
                const _perm = this.markedPermissions.filter((_markedPermission) => _markedPermission.permissionName === permission)
                this.role.permissions[permission] = _perm[0] ? true : false;
            })
        }

        switch (this.mode) {
            case 'create':
                this._createRole();
                break;
            case 'update':
                this._updateRole();
                break;
        }

    }

    _clearForm() {
        this.role = {};
        this.$.rolename.id = undefined;
        this.$.rolename.value = undefined;
        this.$.info.value = undefined;
        this.$.timeout.value = undefined;
        this.$.accesslevel.value = undefined;
        this.$.accesslevelread.value = undefined;
        this.$.accessnumber.value = undefined;
        this._renderPermissionList();
    }

    _backupRole() {
        this.backuprole = Object.assign({}, this.role);
    }

    _restoreRole() {
        if (this.backuprole) {
            this.umApi.getRole(this.backuprole.id).then((obj) => {
                this.role = obj.role;
                this._renderPermissionList();
            });
        }
    }

    _clearRole(clearRole = true, clearBackupRole = true) {
        if (clearRole) { this.role = null; this.markedPermissions = null; }
        if (clearBackupRole) this.backuprole = null;
    }

    async _updateUserPermissions(newval, oldval) {
        if (this.disconnected) return;
        if (this.isloggedin && newval && newval !== null) {
            const uid = this.utilsApi.getUID();
            const result = await this.umApi.getUserPermissions(newval, uid).catch(
                error => {
                    return error;
                });
            if (this._hasNoErrors(result)) {
                this.permissions = result.permissions;
            } else {
                console.error(result);
                this.permissions = {};
            }
        } else {
            this.permissions = {};
        }
        this._renderPermissionList();
        this._setButtonState(this.role);
    }

    _isValidEvent(type, target, source) {
        let isValidSource = false,
            isValidTarget = false,
            isValidType = false;
        if (type && type === 'role') isValidType = true;
        if (this.source) {
            if (this.source === source) isValidSource = true;
        } else { 
            isValidSource = true;
        }
        if ((Array.isArray(target) && (target.indexOf(this.id) > -1) || target === null)) {
            isValidTarget = true;
        }
        return (isValidType && isValidTarget && isValidSource) ? true : false;
    }

    _formatMarked(marked, row) {
        return '&nbsp;';
    }

    _toggleListView(newval, oldval) {
        if (newval) {
            this.$.listview.readonly = false;
            this.$.listview.isactive = true;
            this.$.listview.classList.remove('inactive');
        } else {
            this.$.listview.readonly = true;
            this.$.listview.isactive = false;
            this.$.listview.classList.add('inactive');
        }
    }

    _setButtonState(role = this.role) {
        const buttons = this.shadowRoot.querySelectorAll('#buttons sig-control-button');
        const hasAccess = (role && role.accessNumber !== undefined) ? this._checkAccess(role.accessNumber) : false;
        buttons.forEach(button => {
            let enableButton = false;
            switch (button.id) {
                case 'newrole':
                case 'cancel':
                    enableButton = true;
                    break;
                case 'saverole':
                    if (this.mode === 'create' || hasAccess) enableButton = true;
                    break;
                case 'editrole':
                default:
                    if (hasAccess) enableButton = true;
                    break;
            }
            if (enableButton) this._enableButton(button);
            else this._disableButton(button);
        });
    }
}
customElements.define(LasalRuntimeSigControlRoleDetail.is, LasalRuntimeSigControlRoleDetail);