import { __decorate, __metadata } from "tslib";
import '@material/web/icon/icon.js';
import '@operato/data-grist/ox-grist.js';
import '@operato/data-grist/ox-sorters-control.js';
import '@operato/data-grist/ox-filters-form.js';
import '@operato/input/ox-select.js';
import '@operato/input/ox-input-select-buttons.js';
import '@operato/popup/ox-popup-list.js';
import '@operato/process'; /* for process-creation-popup */
import '@sted/process-modeller';
import '../viewpart/process-info';
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 { client, gqlContext } from '@operato/graphql';
import { DataGrist } from '@operato/data-grist';
import { i18next } from '@operato/i18n';
import { p13n } from '@operato/p13n';
import { openOverlay, openPopup } from '@operato/layout';
import { navigate, PageView, store } from '@operato/shell';
import { CommonGristStyles, CommonHeaderStyles } from '@operato/styles';
import { sleep } from '@operato/utils';
import InfiniteScrollable from '@operato/utils/mixins/infinite-scrollable.js';
import { notify } from '../utils/notify';
import { cloneProcess, releaseProcess, revertProcessVersion, createProcess, deleteProcess, evaluateEnergyConsumption, fetchProcessList, fetchProcessGroupList, updateProcess } from '../graphql';
let ProcessListPage = class ProcessListPage extends connect(store)(InfiniteScrollable(p13n(PageView))) {
    constructor() {
        super(...arguments);
        this.mode = 'CARD';
        this.groups = [];
    }
    get context() {
        return {
            search: {
                handler: (search) => {
                    this.grist.searchText = search;
                },
                placeholder: '공정디자인 리스트',
                value: this.grist.searchText
            },
            filter: {
                handler: () => {
                    this.grist.toggleHeadroom();
                }
            }
        };
    }
    render() {
        const mode = this.mode || 'CARD';
        const options = (this.groups || []).map(group => {
            return { display: group.description, value: group.id };
        });
        return html `
      <ox-grist
        .config=${this.config}
        .mode=${mode}
        auto-fetch
        .fetchHandler=${this.fetchHandler.bind(this)}
        .personalConfigProvider=${this.getPagePreferenceProvider('ox-grist')}
      >
        <div slot="headroom" class="header">
          <div class="filters">
            <ox-input-select-buttons
              .value=${this.groupId}
              .options=${options}
              @change=${e => {
            this.groupId = e.currentTarget.value;
        }}
              multiple
            ></ox-input-select-buttons>

            <div class="filler"></div>

            <div id="modes">
              <md-icon @click=${() => this.changeMode('GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>
              <md-icon @click=${() => this.changeMode('CARD')} ?active=${mode == 'CARD'}>apps</md-icon>
            </div>

            <button id="add" @click=${e => this.onCreateProcess()}><md-icon>add</md-icon>디자인 생성</button>
          </div>
        </div>

        <ox-grist-personalizer slot="setting"></ox-grist-personalizer>
      </ox-grist>
    `;
    }
    async changeMode(mode) {
        const pagePreferenceProvider = this.getPagePreferenceProvider('main');
        const pagePreference = pagePreferenceProvider.load() || {};
        await pagePreferenceProvider.save(Object.assign(Object.assign({}, pagePreference), { mode }));
        this.mode = mode;
    }
    async fetchHandler() {
        const { items: records, total } = await this.getProcesses(...arguments);
        this.updateContext();
        return {
            total,
            records
        };
    }
    get gristConfig() {
        return {
            list: {
                thumbnail: 'thumbnail',
                fields: ['name', 'description'],
                details: ['updatedAt']
            },
            columns: [
                {
                    type: 'gutter',
                    gutterName: 'dirty'
                },
                {
                    type: 'gutter',
                    gutterName: 'sequence'
                },
                {
                    type: 'gutter',
                    gutterName: 'button',
                    icon: 'dashboard',
                    iconOnly: false,
                    title: '리포트',
                    width: 80,
                    handlers: {
                        click: (columns, data, column, record, rowIndex) => {
                            this.onShowReport(record.id);
                        }
                    }
                },
                {
                    type: 'gutter',
                    gutterName: 'button',
                    icon: 'drive_file_rename_outline',
                    iconOnly: false,
                    title: '디자인 수정',
                    width: 110,
                    handlers: {
                        click: (columns, data, column, record, rowIndex) => {
                            this.onInfoProcess(record);
                        }
                    }
                },
                {
                    type: 'string',
                    name: 'id',
                    hidden: true
                },
                {
                    type: 'string',
                    name: 'name',
                    header: i18next.t('field.name'),
                    record: {
                        editable: false,
                        align: 'left'
                    },
                    width: 260,
                    filter: 'search',
                    sortable: true
                },
                {
                    type: 'string',
                    name: 'description',
                    header: i18next.t('field.description'),
                    record: {
                        editable: false,
                        align: 'left'
                    },
                    width: 460,
                    handlers: {
                        dblclick: (columns, data, column, record, rowIndex) => {
                            alert(`${column.name} ${record[column.name]}, row : ${rowIndex}`);
                        }
                    },
                    filter: 'search'
                },
                {
                    type: 'image',
                    name: 'thumbnail',
                    hidden: true,
                    record: {
                        editable: false,
                        renderer: function (value, column, record, rowIndex, owner) {
                            return html `
                <img src=${value} style="width: 100%; height: 100%;" /></a>
              `;
                        }
                    }
                },
                // {
                //   type: 'select-buttons',
                //   name: 'groupId',
                //   header: 'group',
                //   hidden: true,
                //   filter: {
                //     operator: 'in',
                //     options: () => {
                //       return this.groups.map(group => {
                //         return { display: group.description, value: group.id }
                //       })
                //     }
                //   }
                // },
                {
                    type: 'object',
                    name: 'updater',
                    header: i18next.t('field.updater'),
                    width: 150
                },
                {
                    type: 'datetime',
                    name: 'updatedAt',
                    header: i18next.t('field.updated-at'),
                    sortable: true,
                    width: 180
                },
                {
                    type: 'object',
                    name: 'creator',
                    header: i18next.t('field.creator'),
                    width: 150
                },
                {
                    type: 'datetime',
                    name: 'createdAt',
                    header: i18next.t('field.created-at'),
                    width: 180
                }
            ],
            rows: {
                appendable: false,
                selectable: {
                    multiple: true
                },
                handlers: {
                    click: (columns, data, column, record, rowIndex) => {
                        column.type != 'gutter' && navigate(`process-viewer/${record.id}`);
                    }
                },
                classifier: function (record, rowIndex) { }
            },
            sorters: [
                {
                    name: 'name',
                    desc: false
                }
            ],
            pagination: {
                pages: [20, 30, 50],
                limit: 30
            }
        };
    }
    updated(changes) {
        if (changes.has('groupId')) {
            this.refresh();
        }
    }
    pageUpdated(changes, lifecycle) {
        if (this.active) {
            this.grist.fetch();
        }
    }
    async pageInitialized() {
        this.config = this.gristConfig;
        const pagePreferenceProvider = this.getPagePreferenceProvider('main');
        const pagePreference = (await pagePreferenceProvider.load()) || {};
        this.mode = pagePreference['mode'] || 'CARD';
        this.refresh();
    }
    async onInfoProcess(process) {
        openOverlay('viewpart-info', {
            template: html `
        <process-info
          .process=${process}
          .groupId=${this.groupId}
          @clone-process=${(e) => this.onCloneProcess(e.detail)}
          @release-process=${(e) => this.onReleaseProcess(e.detail)}
          @revert-process-version=${(e) => this.onRevertProcessVersion(e.detail)}
          @update-process=${(e) => this.onUpdateProcess(e.detail)}
          @delete-process=${(e) => this.onDeleteProcess(e.detail)}
          @register-template=${(e) => this.onRegisterTemplate(e.detail)}
        ></process-info>
      `
        });
    }
    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 onShowReport(processId) {
        try {
            var { stedNodes, stedDataMap, smartGuides } = await evaluateEnergyConsumption(processId);
        }
        catch (error) {
            console.error(error);
        }
        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')
        });
    }
    async onCreateProcess() {
        if (this.popup) {
            delete this.popup;
        }
        /*
         * 기존 설정된 이미지가 선택된 상태가 되게 하기 위해서는 selector에 value를 전달해줄 필요가 있음.
         * 주의. value는 object일 수도 있고, string일 수도 있다.
         * string인 경우에는 해당 보드의 id로 해석한다.
         */
        var template = html `
      <process-creation-popup
        .groups=${this.groups}
        @create-process=${async (e) => {
            try {
                var { name, description, groupId, model, thumbnail } = e.detail;
                var process = {
                    name,
                    description,
                    groupId,
                    model,
                    thumbnail
                };
                if (!process.model) {
                    process.model = {
                        width: 1600,
                        height: 1200
                    };
                }
                const { createProcess: created } = (await createProcess(process)) || {};
                if (!created) {
                    return;
                }
                this.popup && this.popup.close();
                await sleep(100);
                navigate(`process-modeller/${created.id}`);
                notify('info', i18next.t('text.process created'));
            }
            catch (ex) {
                console.error(ex);
                notify('error', ex, ex);
            }
        }}
      ></process-creation-popup>
    `;
        this.popup = openPopup(template, {
            backdrop: true,
            size: 'large',
            title: i18next.t('title.create-process')
        });
    }
    async onUpdateProcess(process) {
        try {
            const data = await updateProcess(process);
            data && notify('info', 'saved');
            data && notify('info', i18next.t('text.process updated', { process: process.name }));
        }
        catch (ex) {
            notify('error', ex, ex);
        }
        this.refreshProcesses();
    }
    async onDeleteProcess(process) {
        try {
            const data = await deleteProcess(process.id);
            data && notify('info', i18next.t('text.process deleted', { process: process.name }));
        }
        catch (ex) {
            notify('error', ex, ex);
        }
        this.refreshProcesses();
    }
    async refresh() {
        this.groups = (await fetchProcessGroupList()).processGroups.items;
        if (this.groups) {
            await this.refreshProcesses();
        }
    }
    async getProcesses({ filters = [], page = 1, limit = 30, sortings = [] } = {}) {
        return (await fetchProcessList({
            filters: this.groupId && this.groupId.length > 0
                ? [
                    ...filters,
                    {
                        name: 'groupId',
                        operator: 'in',
                        value: this.groupId
                    }
                ]
                : filters,
            sortings,
            page,
            limit
        })).processes;
    }
    async refreshProcesses() {
        if (!this.groups) {
            await this.refresh();
            return;
        }
        this.grist.fetch();
        this.updateContext();
    }
    async onCloneProcess({ id, name, description, targetSubdomain, targetGroupId }) {
        try {
            const data = await cloneProcess({
                id,
                name,
                description,
                targetSubdomain,
                targetGroupId
            });
            data && notify('info', i18next.t('text.process cloned', { process: name }));
        }
        catch (ex) {
            notify('error', ex, ex);
        }
        this.refreshProcesses();
    }
    async onReleaseProcess(process) {
        try {
            const data = await releaseProcess(process);
            data && notify('info', i18next.t('text.process released', { process: process.name }));
        }
        catch (ex) {
            notify('error', ex, ex);
        }
        this.refreshProcesses();
    }
    async onRevertProcessVersion({ id, version }) {
        try {
            const process = await revertProcessVersion(id, version);
            process && notify('info', i18next.t('text.process reverted', { process: process.name, version }));
        }
        catch (ex) {
            notify('error', ex, ex);
        }
        this.refreshProcesses();
    }
    async onRegisterTemplate({ id, name, description, visibility }) {
        try {
            const { data } = await client.mutate({
                mutation: gql `
          mutation ($id: String!, $name: String!, $description: String!, $visibility: String!) {
            registerProcessAsTemplate(id: $id, name: $name, description: $description, visibility: $visibility) {
              id
            }
          }
        `,
                variables: {
                    id,
                    name,
                    description,
                    visibility
                }
            });
            data &&
                notify('info', i18next.t('text.info_register_successfully', { x: i18next.t('text.register-template') }), {
                    name
                });
        }
        catch (ex) {
            notify('error', ex, ex);
        }
    }
};
ProcessListPage.styles = [
    CommonGristStyles,
    CommonHeaderStyles,
    css `
      :host {
        display: flex;

        width: 100%;

        --grid-record-emphasized-background-color: red;
        --grid-record-emphasized-color: yellow;
      }

      #add {
        display: flex;
        align-items: center;
        gap: 4px;

        border-radius: var(--spacing-small);
        border: 0;
        padding: var(--spacing-small) var(--spacing-medium);

        color: var(--md-sys-color-on-tertiary);
        background-color: var(--md-sys-color-tertiary);
      }

      #add:hover {
        background-color: var(--md-sys-color-secondary);
      }

      .filler {
        flex: 1;
      }
    `
];
__decorate([
    property({ type: Object }),
    __metadata("design:type", Object)
], ProcessListPage.prototype, "config", void 0);
__decorate([
    property({ type: Object }),
    __metadata("design:type", Object)
], ProcessListPage.prototype, "data", void 0);
__decorate([
    property({ type: String }),
    __metadata("design:type", String)
], ProcessListPage.prototype, "mode", void 0);
__decorate([
    property({ type: String }),
    __metadata("design:type", String)
], ProcessListPage.prototype, "groupId", void 0);
__decorate([
    property({ type: Array }),
    __metadata("design:type", Array)
], ProcessListPage.prototype, "groups", void 0);
__decorate([
    query('ox-grist'),
    __metadata("design:type", DataGrist)
], ProcessListPage.prototype, "grist", void 0);
ProcessListPage = __decorate([
    customElement('process-list')
], ProcessListPage);
export { ProcessListPage };
//# sourceMappingURL=process-list-page.js.map