import { __decorate, __metadata } from "tslib";
import '@material/web/icon/icon.js';
import '@material/web/button/text-button.js';
import '@operato/process/ox-process-viewer.js';
import './things-scene-components.import';
import '../viewpart/process-report';
import '../viewpart/equipment-evaluator';
import '../viewpart/stream-info';
import gql from 'graphql-tag';
import { css, html } from 'lit';
import { customElement, query, state } from 'lit/decorators.js';
import { connect } from 'pwa-helpers/connect-mixin.js';
import { client, gqlContext } from '@operato/graphql';
import { i18next } from '@operato/i18n';
import { openPopup } from '@operato/layout';
import { OxProcessViewer } from '@operato/process/ox-process-viewer.js';
import { PageView, store } from '@operato/shell';
import { evaluateEnergyConsumption } from '../graphql/evaluate-energy-consumption';
import { provider } from '../process-provider';
const NOOP = () => { };
let ProcessViewerPage = class ProcessViewerPage extends connect(store)(PageView) {
    constructor() {
        super(...arguments);
        this._process = null;
        this._processId = '';
        this._baseUrl = '';
        this._showSpinner = false;
        this.showStreamEventHandler = this.showStreamInfo.bind(this);
        this.isProcessDone = false;
        this.equipmentEvaluatorListener = (e) => {
            try {
                if (!this.isProcessDone) {
                    throw new Error(i18next.t('text.need-to-evaluate-lv1'));
                }
                const equipment = e.detail;
                const { type, refid } = (equipment === null || equipment === void 0 ? void 0 : equipment.state) || {};
                var template = html `
        <equipment-evaluator .equipment=${equipment} .processId=${this._processId}></equipment-evaluator>
      `;
                openPopup(template, {
                    backdrop: true,
                    size: 'large',
                    title: `${i18next.t('title.equipment-evaluator')} - ${i18next.t(`component.${type}`)}(${(type +
                        ' ' +
                        refid).toUpperCase()})`
                });
            }
            catch (err) {
                document.dispatchEvent(new CustomEvent('notify', {
                    detail: {
                        level: 'error',
                        message: err,
                        err
                    }
                }));
            }
        };
    }
    get oopsNote() {
        return {
            icon: 'insert_chart_outlined',
            title: 'EMPTY BOARD',
            description: 'There are no process to be shown',
            click: NOOP
        };
    }
    get context() {
        return {
            /* can set the page title with the 'title' parameter. */
            title: this.lifecycle.params['title'] ||
                (this._process ? this._process.name : this._showSpinner ? 'Fetching process...' : 'Process Not Found')
        };
    }
    connectedCallback() {
        super.connectedCallback();
        document.addEventListener('show-equipment-evaluator', this.equipmentEvaluatorListener);
        document.addEventListener('show-stream-info', this.showStreamEventHandler);
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        document.removeEventListener('show-equipment-evaluator', this.equipmentEvaluatorListener);
        document.removeEventListener('show-stream-info', this.showStreamEventHandler);
    }
    render() {
        var oops = !this._showSpinner && !this._process && this.oopsNote;
        return oops
            ? html `
          <oops-note
            icon=${oops.icon}
            title=${oops.title}
            description=${oops.description}
            @click=${oops.click || NOOP}
          ></oops-note>
        `
            : html `
          <ox-process-viewer
            .process=${this._process}
            .provider=${provider}
            hide-fullscreen
            @run-process=${(e) => this.onProcessRun()}
          ></ox-process-viewer>
          <oops-spinner ?show=${this._showSpinner}></oops-spinner>
          <div commands>
            <md-elevated-button @click=${() => this.onShowReport()}>
              <md-icon slot="icon">analytics</md-icon>
              ${String(i18next.t('title.show-process-report'))}
            </md-elevated-button>
          </div>

          <slot></slot>
        `;
    }
    updated(changes) {
        var _a;
        if (changes.has('_processId')) {
            (_a = this.processViewer) === null || _a === void 0 ? void 0 : _a.closeScene();
            this.hidePopup();
            this.refresh();
        }
    }
    pageUpdated(changes, lifecycle) {
        var _a;
        if (this.active) {
            this._processId = lifecycle.resourceId;
        }
        else {
            this._processId = '';
            (_a = this.processViewer) === null || _a === void 0 ? void 0 : _a.closeScene();
        }
    }
    stateChanged(state) {
        this._baseUrl = state.app.baseUrl;
    }
    async fetchProcess(processId) {
        var response = await client.query({
            query: gql `
        query FetchProcessById($id: String!) {
          process(id: $id) {
            id
            name
            model
            diagram
          }
        }
      `,
            variables: { id: processId },
            context: gqlContext()
        });
        var process = response.data.process;
        return Object.assign(Object.assign({}, process), { model: JSON.parse(process.model) });
    }
    async refresh() {
        if (!this._processId) {
            return;
        }
        try {
            this._showSpinner = true;
            this.updateContext();
            const process = await this.fetchProcess(this._processId);
            if (!process) {
                this._process = null;
                throw 'process not found';
            }
            this._process = process;
        }
        catch (ex) {
            document.dispatchEvent(new CustomEvent('notify', {
                detail: {
                    level: 'error',
                    message: ex,
                    ex
                }
            }));
        }
        finally {
            this._showSpinner = false;
            this.updateContext();
        }
    }
    async onProcessRun() {
        var _a, _b;
        try {
            const processId = (_a = this.processViewer) === null || _a === void 0 ? void 0 : _a.currentProcessId;
            if (!processId) {
                throw new Error('process should not be empty.');
            }
            const { stedDataMap } = await evaluateEnergyConsumption(processId);
            if ((_b = this.processViewer) === null || _b === void 0 ? void 0 : _b._scene) {
                this.processViewer._scene.dataByRefid = stedDataMap;
            }
        }
        catch (err) {
            console.error(err);
        }
    }
    async onShowReport() {
        var _a, _b;
        try {
            this.isProcessDone = false;
            const processId = (_a = this.processViewer) === null || _a === void 0 ? void 0 : _a.currentProcessId;
            if (!processId) {
                throw new Error('process should not be empty.');
            }
            try {
                var { stedNodes, stedDataMap, smartGuides } = await evaluateEnergyConsumption(processId);
            }
            catch (error) {
                console.error(error);
            }
            if ((_b = this.processViewer) === null || _b === void 0 ? void 0 : _b._scene) {
                this.processViewer._scene.dataByRefid = stedDataMap;
            }
            // check if stedNodes is empty
            // ,which means the lv1 evaluation was falied before.
            if (!stedNodes) {
                return;
            }
            this.isProcessDone = true;
            const process = await this.fetchProcess(processId);
            /*
             * 기존 설정된 이미지가 선택된 상태가 되게 하기 위해서는 selector에 value를 전달해줄 필요가 있음.
             * 주의. value는 object일 수도 있고, string일 수도 있다.
             * string인 경우에는 해당 보드의 id로 해석한다.
             */
            var template = html `
        <process-report .stedNodes=${stedNodes} .smartGuides=${smartGuides} .process=${process}></process-report>
      `;
            openPopup(template, {
                backdrop: true,
                size: 'large',
                title: i18next.t('title.process-report')
            });
        }
        catch (err) {
            console.error(err);
        }
    }
    showStreamInfo(e) {
        const stream = e.detail;
        if (!this.popup) {
            const popup = document.createElement('stream-info');
            popup.addEventListener('close', e => {
                e.stopPropagation();
                this.hidePopup();
            });
            this.appendChild(popup);
            this.popup = popup;
        }
        this.popup.stream = stream;
    }
    hidePopup() {
        if (this.popup) {
            this.removeChild(this.popup);
            delete this.popup;
        }
    }
};
ProcessViewerPage.styles = [
    css `
      :host {
        display: flex;
        flex-direction: column;

        width: 100%; /* 전체화면보기를 위해서 필요함. */
        height: 100%;

        overflow: hidden;
        position: relative;
      }

      ::slotted(stream-info) {
        position: absolute;
        right: 10px;
        top: 10px;
        width: 200px;
        opacity: 0.9;
        box-shadow: 2px 2px 4px gray;
      }

      [commands] {
        position: absolute;
        right: 6px;
        top: 4px;
        display: flex;
        justify-content: flex-end;
      }

      ox-process-viewer {
        flex: 1;
      }

      oops-spinner {
        display: none;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }

      oops-spinner[show] {
        display: block;
      }

      oops-note {
        display: block;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }

      md-elevated-button {
        position: absolute;
        top: 4px;
        right: 6px;
      }
    `
];
__decorate([
    state(),
    __metadata("design:type", Object)
], ProcessViewerPage.prototype, "_process", void 0);
__decorate([
    state(),
    __metadata("design:type", String)
], ProcessViewerPage.prototype, "_processId", void 0);
__decorate([
    state(),
    __metadata("design:type", String)
], ProcessViewerPage.prototype, "_baseUrl", void 0);
__decorate([
    state(),
    __metadata("design:type", Boolean)
], ProcessViewerPage.prototype, "_showSpinner", void 0);
__decorate([
    query('ox-process-viewer'),
    __metadata("design:type", OxProcessViewer)
], ProcessViewerPage.prototype, "processViewer", void 0);
ProcessViewerPage = __decorate([
    customElement('process-viewer-page')
], ProcessViewerPage);
export { ProcessViewerPage };
//# sourceMappingURL=process-viewer-page.js.map