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-button/sig-control-button.js";
import "../sig-control-listview/sig-control-listview.js";
import "../sig-control-titlebar/sig-control-titlebar.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 LasalRuntimeSigControlRoleList extends Usermanager(LasalRuntimeSigElement) {

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

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

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

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

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

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

        .clearfix:after {
            
            @apply --clearfix
        }

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

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

        .form {
            overflow: hidden;
            flex: 1 1 100%;
        }

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

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

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

        .button {
            position: unset;
        }

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

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

        .button.left {
            margin-right: var(--theme-sig-control-role-list-button-margin, 10px);
            float: left;
        }
        
        .button.disabled {
            opacity: var(--theme-sig-control-role-list-button-disabled-opacity, .4);
            pointer-events: none !important;
        }

        .roles {
            flex: 1 1 100%;
            position: relative;
            min-height: 32px;
            overflow: auto;
        }

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

        .message {
            color: inherit;
            text-decoration: inherit;
            text-align: center;
            line-height: 40px;
            height: 100%;
        }

        :host([hidebuttons]) .buttons,
        :host([hidetitle]) .title,
            :host([hiderolelist]) .roles {
            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-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-list clearfix">
            <div class="content">
                <div class="title">
                    <sig-control-titlebar id="titlebar" value="[[texts.caption]]"
                        shadowactive="[[titlebarshadowactive]]" applybordereffect="[[applybordereffect]]">
                    </sig-control-titlebar>
                </div>
                <div class="form">
                    <div class="inner">
                        <div id="roles" class="roles">
                            <sig-control-listview id="listview" class="rolelist"></sig-control-listview>
                        </div>
                    </div>
                </div>
                <div id="buttons" class="buttons clearfix">
                    <template is="dom-if" if="[[_hasNoButtons(isloggedin, window)]]">
                        <div class="message">
                        [[texts.pleaseLoginToSeeAllOptions]]
                        </div>
                    </template>
                    <template is="dom-if" if="[[_showButtons(isloggedin)]]">
                        <template is="dom-if" if="[[window]]">
                            <sig-control-button id="viewrole" sigbtntext=[[texts.view]] class="button default right"
                                on-up="_viewRole"></sig-control-button>
                    </template>
                    <template is="dom-if" if="[[_showButtons(permissions.updateRole)]]">
                        <sig-control-button id="updaterole" sigbtntext=[[texts.edit]] class="button default right"
                                on-up="_updateRole"></sig-control-button>
                        </template>
                    <template is="dom-if" if="[[_showButtons(permissions.createRole)]]">
                        <sig-control-button id="createrole" sigbtntext=[[texts.new]] class="button default right"
                                on-up="_createRole"></sig-control-button>
                    </template>
                    <template is="dom-if" if="[[_showButtons(permissions.deleteRole)]]">
                        <sig-control-button id="deleterole" sigbtntext=[[texts.delete]] class="button default right"
                                on-up="_deleteRole"></sig-control-button>
                    </template>
                </template>
                </div>
            </div>
        </div>
        `;
    }

    static get properties() {
        let props = {
            isloggedin: {
                type: Boolean,
                value: false,
                observer: '_isLoggedin'
            },
            activeuser: {
                type: Object,
                value: null,
                observer: '_updateRolePermissions'
            },
            hidetitle: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            hideheader: {
                type: Boolean,
                value: false,
                observer: '_init'
            },
            hiderolelist: {
                type: Boolean,
                value: false,
                reflectToAttribute: true,
            },
            hidebuttons: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            titlebarshadowactive: {
                type: Boolean,
                value: false,
                reflectToAttribute: true
            },
            titletext: {
                type: String,
                value: '',
                observer: '_switchLang'
            }
        }
        return props;
    }

    constructor() {
        super();
        this.umApi = window.sigApi.userManager;
        this.wmApi = window.sigApi.windowManager;
        this.evtsApi = window.sigApi.events;
        this.evtmApi = window.sigApi.eventMediator;
        this.tmApi = window.sigApi.textManager;
        this.utilsApi = window.sigApi.sigUtils;
        this.controlTextList = this.getControlTextListName();
        this.firstRenderDone = false;
        this.iswindow = false;
        this.permissions = {};
        this.data = null;
        this.config = null;
        this.longpressdelay = 250;
        this.selectedroles = null;
        this.markedroles = null;
        this.target = null;
        this.window = null;
        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');
        }
    }

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

    disconnectedCallback() {
        super.disconnectedCallback();
        this.umApi = null;
        this.wmApi = null;
        this.evtsApi = null;
        this.evtmApi = null;
        this.tmApi = null;
        this.utilsApi = null;
        this.permissions = null;
        this.data = null;
        this.config = null;
        this.selectedroles = null;
        this.markedroles = null;
        this.target = null;
        this.window = null;
        this.activeuser = null;
        this.texts = null;
    }

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

    _isLoggedin(newval, oldval) {
        if (newval) {
            const uid = this.utilsApi.getUID();
            this.umApi.getActiveUser(uid).then((result) => {
                this.activeuser = result.user;
            }).catch(error => {
                return error;
            });
        }
    }

    _roleCreated(majorId, minorId, msg) {
        this._renderRoleList();
    }

    _roleUpdated(majorId, minorId, msg) {
        this._renderRoleList();
    }

    _roleDeleted(majorId, minorId, msg) {
        this._renderRoleList();
    }

    _showButtons(_value) {
        return (this.isdesignmode) ? true : _value;
    }

    _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;
        this.activeuser = null;
    }

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

    async _renderRoleList(clearActiveRow = false) {
        if (this.disconnected) return;
        let result = {}
        if (!this.isdesignmode) {
            const uid = this.utilsApi.getUID();
            result = await this.umApi.getRoleList(uid).catch(error => {
                return error;
            });
        } else {
            result.roles = [{
                id: 0,
                name: 'role0',
                info: 'Selected',
                timeout: 0,
                active: true
            },
            {
                id: 1,
                name: 'role1',
                info: 'Selected marked',
                timeout: 20,
                active: true,
                marked: true
            },
            {
                id: 2,
                name: 'role2',
                info: 'Alternate (odd)',
                timeout: 60
            },
            {
                id: 3,
                name: 'role3',
                info: 'Normal (even)',
                timeout: 60
            },
            {
                id: 3,
                name: 'role4',
                info: 'Marked',
                timeout: 60,
                marked: true
            }];
        }
        if (this._hasNoErrors(result)) {
            this.data = {
                "cols": [
                    {
                        "id": "id",
                        "name": this.texts.id,
                        "type": "text",
                        "css": {
                            "text-align": "center"
                        },
                        "default": "&nbsp;",
                        "visible": true,
                        "sortable": false
                    },
                    {
                        "id": "name",
                        "name": this.texts.roleName,
                        "type": "text",
                        "default": "&nbsp;",
                        "visible": true,
                        "sortable": false
                    },
                    {
                        "id": "info",
                        "name": this.texts.info,
                        "type": "text",
                        "default": "&nbsp;",
                        "visible": true,
                        "sortable": false
                    },
                    {
                        "id": "timeout",
                        "name": this.texts.timeout,
                        "type": "text",
                        "default": "&nbsp;",
                        "visible": true,
                        "sortable": false
                    }],
                "data": {
                    "nodes": result.roles
                }
            }
            this.config = {
                updateSelectionCallback: (data, pane) => {
                    this._updateSelection(data, pane);
                },
                updateActiveRowCallback: (data, pane) => {
                    this._updateActiveRow(data, pane);
                },
                clickCallback: (data, pane) => {
                    this._click(data, pane);
                },
                doubleClickCallback: (data, pane) => {
                    this._doubleClick(data, pane);
                },
                longPressCallback: (data, pane) => {
                    this._longPress(data, pane);
                },
                onEnterCallback: (data, pane) => {
                    this._viewRole(true);
                },
                onRenderReadyCallback: (data, pane) => {
                    if (!this.firstRenderDone) this.firstRenderDone = true;
                    this._setButtonState();
                },
                data: this.data,
                name: "rolelist",
                self: this
            };
            this.$.listview.config = this.config;
            if (clearActiveRow) { this.$.listview._clearActiveRow(true); }
        } else {
            console.error(result);
        }
    }

    _updateSelection(roles, pane) {
        this.markedroles = roles;
    }

    _updateActiveRow(role, pane) {
        this.selectedroles = role;
        this._setButtonState(role);
    }

    _click(role, pane) {
        this._viewRole();
    }

    _doubleClick(role, pane) {
        this._viewRole(true);
    }

    _longPress(role, pane) {
    }

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

    async _updateRolePermissions() {
        if (this.disconnected) return;
        if (this.isloggedin && this.activeuser) {
            const uid = this.utilsApi.getUID();
            const result = await this.umApi.getUserPermissions(this.activeuser, uid).catch(
                error => {
                    return error;
                });
            if (this._hasNoErrors(result)) {
                this.permissions = result.permissions;
                this._setButtonState(this.selecteduser);
            } else {
                console.error(result);
                this.permissions = {};
            }
        } else {
            this.permissions = {};
        }
        this._renderRoleList();
    }

    async _deleteRole() {
        if (this.disconnected) return;
        if (this.permissions.deleteRole) {
            const count = this._getMarkedCount();
            const confirm = await this._showConfirm(this._getTextObj('doYouRealyWantToDeleteRoles', [count]), this._getTextObj('caption'), 1).then(result => {
                return true;
            }).catch(error => {
                this._log(error);
                return false;
            });
            if (confirm) {
                const uid = this.utilsApi.getUID();
                const result = await this.umApi.deleteRole(this.markedroles, undefined, undefined, undefined, uid).catch(
                    error => {
                        return error;
                    });
                if (this._hasNoErrors(result)) {
                    return true;
                } else {
                    if (result.status === window.sigApi.SIG_CONST.ERROR_ROLE_IN_USE) {
                        const confirm = await this._showConfirm(this._getTextObj('doYouRealyWantToDeleteRolesInUse', [count]), this._getTextObj('caption'), 1).then(result => {
                            return true;
                        }).catch(error => {
                            this._log(error);
                            return false;
                        });
                        if (confirm) {
                            const uid = this.utilsApi.getUID();
                            const result = await this.umApi.deleteRole(this.markedroles, undefined, undefined, undefined, uid, true).catch(
                                error => {
                                    return error;
                                });
                        }
                    } else {
                        await this._showAlert(result.errortxt, this._getTextObj('alertTitle', [result.status])).catch(error => {
                            this._log(error);
                        });
                        return false;
                    }
                }
            }
        } else {
            await this._showAlert(this._getTextObj('noPermissionToDeleteRoles'), this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
        }
    }

    async _viewRole(evt) {
        if (this.disconnected) return;
        if (this.selectedroles) {
            if (evt) { this._openWindow() };
            this.evtmApi.publish(this.evtsApi.getInternalEvent('SEND_USER_DATA'), { type: 'role', source: this.id, target: this._getTargetList(), data: { mode: 'view', role: this.selectedroles } });
        } else {
            await this._showAlert(this._getTextObj('pleaseSelectRoleFirst'), this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
        }
    }

    async _updateRole(evt) {
        if (this.disconnected) return;
        if (this.permissions.updateRole && this.selectedroles && this.selectedroles.readOnly !== true) {
            this._openWindow();
            this.evtmApi.publish(this.evtsApi.getInternalEvent('SEND_USER_DATA'), { type: 'role', source: this.id, target: this._getTargetList(), data: { mode: 'update', role: this.selectedroles } });
        } else if (!this.selectedroles) {
            await this._showAlert(this._getTextObj('pleaseSelectRoleFirst'), this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
        } else {
            await this._showAlert(this._getTextObj('noPermissionToUpdateTheRole'), this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
        }
    }

    async _createRole(evt) {
        if (this.disconnected) return;
        if (this.permissions.createRole) {
            this._openWindow();
            this.evtmApi.publish(this.evtsApi.getInternalEvent('SEND_USER_DATA'), { type: 'role', source: this.id, target: this._getTargetList(), data: { mode: 'create' } });
        } else {
            await this._showAlert(this._getTextObj('noPermissionToCreateRole'), this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
        }
    }

    async _importRoles() {
        if (this.disconnected) return;
        if (this.permissions.importRoles) {
            await this._showAlert('Import roles needs implementation', this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
        } else {
            await this._showAlert(this._getTextObj('noPermissionToImportRoles'), this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
        }
    }

    async _exportRoles() {
        if (this.disconnected) return;
        if (this.permissions.importRoles) {
            await this._showAlert('Export roles needs implementation', this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
        } else {
            await this._showAlert(this._getTextObj('noPermissionToExportRoles'), this._getTextObj('caption')).catch(error => {
                this._log(error);
            });
        }
    }

    async _openWindow() {
        if (this.disconnected) return;
        if (this.window || this.window === 0) {
            await this.wmApi.openWindow(this.window).catch(error => {
                this._log(error);
            });
        }
    }

    _getTargetList() {
        if (this.target) {
            return this.target.split(',');
        }
        return null;
    }

    _hasNoButtons(isloggedin, window) {
        return (!isloggedin && !this.isdesignmode) ? true : false;
    }

    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];
        }
        if (this.firstRenderDone) {
            this._renderRoleList();
        }
    }

    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 list',
                id: 'ID',
                roleName: 'Role name',

                info: 'Info',
                timeout: 'Timeout',

                export: 'Export',
                import: 'Import',

                reset: 'Reset',
                delete: 'Delete',
                new: 'New',
                edit: 'Edit',
                view: 'View',
                pleaseLoginToSeeAllOptions: 'Please login to see all options',
                none: 'none',
                notAvailable: 'not available'
            }
        }
    }

    evtHandlerViewRole() {
        this._viewRole(true);
    }

    evtHandlerUpdateRole() {
        this._updateRole();
    }

    evtHandlerCreateRole() {
        this._createRole();
    }

    evtHandlerDeleteRole() {
        this._deleteRole();
    }

    evtHandlerImportRoles() {
    }

    evtHandlerExportRoles() {
    }

    evtHandlerMoveCursorDown() {
        this.$.listview.moveCursorDown();
    }

    evtHandlerMoveCursorUp() {
        this.$.listview.moveCursorUp();
    }

    evtHandlerMoveCursorPageDown() {
        this.$.listview.moveCursorPageDown();
    }

    evtHandlerMoveCursorPageUp() {
        this.$.listview.moveCursorPageUp();
    }

    _getMarkedCount() {
        if (this.markedroles !== null) {
            return this.markedroles.length;
        }
        return 0;
    }

    _setButtonState(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 'updaterole':
                case 'deleterole':
                    if (hasAccess && role && role.id > 3) enableButton = true;
                    break;
                case 'viewrole':
                    if (role) enableButton = true;
                    break;
                case 'createrole':
                    enableButton = true;
                    break;
                default:
                    if (hasAccess) enableButton = true;
                    break;
            }
            if (enableButton) this._enableButton(button);
            else this._disableButton(button);
        });
    }
}
customElements.define(LasalRuntimeSigControlRoleList.is, LasalRuntimeSigControlRoleList);