import { __decorate, __metadata } from "tslib";
import './things-scene-components.import';
import '@operato/board/ox-board-modeller.js';
import '@operato/oops';
import gql from 'graphql-tag';
import { css, html } from 'lit';
import { customElement, property, query } from 'lit/decorators.js';
import { connect } from 'pwa-helpers/connect-mixin.js';
import { BoardModeller } from '@operato/board/ox-board-modeller.js';
import { OxPropertyEditor } from '@operato/property-editor';
import { PageView, store } from '@operato/shell';
import { hasPrivilege } from '@things-factory/auth-base/dist-client';
import { client, gqlContext } from '@operato/graphql';
import { i18next } from '@operato/i18n';
import { OxPrompt } from '@operato/popup/ox-prompt.js';
import { provider } from '../board-provider';
import components from './things-scene-components-with-tools.import';
const NOOP = () => { };
let BoardModellerPage = class BoardModellerPage extends connect(store)(PageView) {
    constructor() {
        super();
        this.boardName = '';
        this.model = null;
        this.baseUrl = '';
        this.selected = [];
        this.mode = 1;
        this.hideProperty = false;
        this.overlay = null;
        this.scene = null;
        this.componentGroupList = BoardModeller.groups;
        this.fonts = [];
        this.board = null;
        components.forEach(({ templates = [], groups = [] }) => {
            groups.forEach(group => BoardModeller.registerGroup(group));
            BoardModeller.registerTemplate(templates);
        });
        /* 컴포넌트에서 정의된 에디터들을 MODELLER_EDITORS에 등록 */
        var addedEditors = {};
        for (let component in components) {
            let { editors } = components[component];
            editors &&
                editors.forEach(editor => {
                    let { type, element } = editor;
                    addedEditors[type] = element;
                });
        }
        OxPropertyEditor.register(addedEditors);
    }
    get context() {
        return {
            title: this.board ? this.boardName : this.preparing ? 'Fetching board...' : 'Board Not Found',
            help: 'board-modeller/modeller',
            widebleed: true
        };
    }
    get oopsNote() {
        return {
            icon: 'color_lens',
            title: 'EMPTY BOARD',
            description: 'There are no board to be designed'
        };
    }
    async refresh() {
        if (!this.boardId) {
            this.board = null;
            this.model = null;
            return;
        }
        try {
            this.preparing = true;
            this.updateContext();
            var response = await client.query({
                query: gql `
          query FetchBoardById($id: String!) {
            board(id: $id) {
              id
              name
              model
            }
          }
        `,
                variables: { id: this.boardId },
                context: gqlContext()
            });
            var board = response.data.board;
            if (!board) {
                this.board = null;
                throw 'board not found';
            }
            this.board = Object.assign(Object.assign({}, board), { model: JSON.parse(board.model) });
            this.boardName = this.board.name;
            this.model = Object.assign({}, this.board.model);
        }
        catch (ex) {
            document.dispatchEvent(new CustomEvent('notify', {
                detail: {
                    level: 'error',
                    message: ex,
                    ex
                }
            }));
        }
        finally {
            this.preparing = false;
            this.updateContext();
        }
    }
    async updated(changes) {
        var _a;
        if (changes.has('boardId')) {
            if (await hasPrivilege({ privilege: 'mutation', category: 'board' })) {
                this.refresh();
            }
            else {
                this.boardId = null;
                this.model = null;
                (_a = this.modeller) === null || _a === void 0 ? void 0 : _a.close();
            }
        }
    }
    pageUpdated(changes, lifecycle) {
        var _a;
        if (this.active) {
            this.boardId = lifecycle.resourceId;
        }
        else {
            this.boardId = null;
            this.model = null;
            (_a = this.modeller) === null || _a === void 0 ? void 0 : _a.close();
        }
    }
    stateChanged(state) {
        this.baseUrl = state.route.rootPath;
        this.fonts = state.font;
    }
    render() {
        var oops = !this.preparing && !this.model && this.oopsNote;
        return oops
            ? html ` <ox-oops-note icon=${oops.icon} title=${oops.title} description=${oops.description}></ox-oops-note> `
            : html `
          <ox-board-modeller
            .mode=${this.mode}
            @mode-changed=${e => {
                this.mode = e.detail.value;
            }}
            .model=${this.model}
            @model-changed=${e => {
                this.model = e.detail.value;
            }}
            .scene=${this.scene}
            @scene-changed=${e => {
                this.scene = e.detail.value;
            }}
            .selected=${this.selected}
            @selected-changed=${e => {
                this.selected = e.detail.value;
            }}
            .baseUrl=${this.baseUrl}
            .provider=${provider}
            @save-model=${e => this.saveBoard()}
            .componentGroupList=${this.componentGroupList}
            .fonts=${this.fonts}
            .hideProperty=${this.hideProperty}
          >
          </ox-board-modeller>
        `;
    }
    async updateBoard() {
        try {
            this.preparing = true;
            var { id, name, description, groupId } = this.board;
            var model = JSON.stringify(this.scene.model);
            await client.mutate({
                mutation: gql `
          mutation UpdateBoard($id: String!, $patch: BoardPatch!) {
            updateBoard(id: $id, patch: $patch) {
              id
            }
          }
        `,
                variables: {
                    id,
                    patch: { name, description, model, groupId }
                },
                context: gqlContext()
            });
            document.dispatchEvent(new CustomEvent('notify', {
                detail: {
                    level: 'info',
                    message: i18next.t('text.saved')
                }
            }));
        }
        catch (ex) {
            document.dispatchEvent(new CustomEvent('notify', {
                detail: {
                    level: 'error',
                    message: ex,
                    ex: ex
                }
            }));
        }
        finally {
            this.preparing = false;
        }
        this.updateContext();
    }
    async saveBoard() {
        var _a;
        await this.updateBoard();
        (_a = this.modeller) === null || _a === void 0 ? void 0 : _a.preserve();
    }
    async canDeactivate() {
        var _a;
        if ((_a = this.modeller) === null || _a === void 0 ? void 0 : _a.hasUnpreservedChanges()) {
            return await OxPrompt.open({
                title: i18next.t('text.are_you_sure'),
                text: i18next.t('prompt.sure to navigate away?'),
                confirmButton: { text: i18next.t('button.confirm') },
                cancelButton: { text: i18next.t('button.cancel') }
            });
        }
        return true;
    }
};
BoardModellerPage.styles = [
    css `
      :host {
        display: flex;
        flex-direction: column;

        overflow: hidden;
        position: relative;
      }

      ox-board-modeller {
        flex: 1;
      }

      ox-oops-note {
        display: block;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }
    `
];
__decorate([
    property({ type: String }),
    __metadata("design:type", Object)
], BoardModellerPage.prototype, "boardId", void 0);
__decorate([
    property({ type: String }),
    __metadata("design:type", String)
], BoardModellerPage.prototype, "boardName", void 0);
__decorate([
    property({ type: Object }),
    __metadata("design:type", Object)
], BoardModellerPage.prototype, "model", void 0);
__decorate([
    property({ type: String }),
    __metadata("design:type", String)
], BoardModellerPage.prototype, "baseUrl", void 0);
__decorate([
    property({ type: Array }),
    __metadata("design:type", Object)
], BoardModellerPage.prototype, "selected", void 0);
__decorate([
    property({ type: Number }),
    __metadata("design:type", Number)
], BoardModellerPage.prototype, "mode", void 0);
__decorate([
    property({ type: Boolean }),
    __metadata("design:type", Boolean)
], BoardModellerPage.prototype, "hideProperty", void 0);
__decorate([
    property({ type: String }),
    __metadata("design:type", Object)
], BoardModellerPage.prototype, "overlay", void 0);
__decorate([
    property({ type: Object }),
    __metadata("design:type", Object)
], BoardModellerPage.prototype, "scene", void 0);
__decorate([
    property({ type: Array }),
    __metadata("design:type", Array)
], BoardModellerPage.prototype, "componentGroupList", void 0);
__decorate([
    property({ type: Array }),
    __metadata("design:type", Object)
], BoardModellerPage.prototype, "fonts", void 0);
__decorate([
    property({ type: Array }),
    __metadata("design:type", Object)
], BoardModellerPage.prototype, "propertyEditor", void 0);
__decorate([
    property({ type: Boolean }),
    __metadata("design:type", Boolean)
], BoardModellerPage.prototype, "preparing", void 0);
__decorate([
    query('ox-board-modeller'),
    __metadata("design:type", BoardModeller)
], BoardModellerPage.prototype, "modeller", void 0);
BoardModellerPage = __decorate([
    customElement('board-modeller-page'),
    __metadata("design:paramtypes", [])
], BoardModellerPage);
export { BoardModellerPage };
//# sourceMappingURL=board-modeller-page.js.map