<template>
  <div style="height: 100%">
    <q-splitter :model-value="150" unit="px" class="w-full" style="height: 100%">
      <template #before>
        <q-tabs v-model="selectedTabRef" vertical no-caps>
          <q-tab name="processDefine" icon="bi-share" :label="$t('lcdp.bpm.tabs.processDefine')" />
          <q-tab name="processInstance" icon="bi-sliders" :label="$t('lcdp.bpm.tabs.processInstance')" />
          <q-tab name="task" icon="bi-receipt" :label="$t('lcdp.bpm.tabs.task')" />
          <q-tab name="tools" icon="bi-wrench-adjustable" :label="$t('lcdp.bpm.tabs.tools')" />
        </q-tabs>
      </template>
      <template #after>
        <q-tab-panels v-model="selectedTabRef" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up" keep-alive style="height: 100%">
          <q-tab-panel name="processDefine" class="pl-2 pb-0" style="height: 100%; padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
            <w-grid
              ref="processDefineGridRef"
              :title="$t('lcdp.bpm.processDefine.grid.title')"
              :checkbox-selection="true"
              :data-url="Environment.apiContextPath('/api/flowable/process')"
              :pageable="true"
              :pagination="{ sortBy: 'lastModifyDate', descending: true }"
              :query-form-cols-num="4"
              :query-form-fields="[
                { name: 'key', label: $t('code'), type: 'text' },
                { name: 'name', label: $t('name'), type: 'text' },
                { name: 'status', label: $t('status'), queryOperator: 'equals', type: 'select', clearable: true, options: Options.enum(ProcessStatusEnum) },
              ]"
              :toolbar-actions="[
                'query',
                'separator',
                'refresh',
                'separator',
                'add',
                'clone',
                {
                  extend: 'edit',
                  enableIf: (arg) => {
                    if (arg.selected) {
                      if ('SKETCH' === arg.selected.status) {
                        return true;
                      }
                    }
                    return false;
                  },
                },
                {
                  extend: 'remove',
                  enableIf: (arg) => {
                    if (arg.selected) {
                      if ('SKETCH' === arg.selected.status) {
                        return true;
                      }
                    }
                    return false;
                  },
                },
                'separator',
                {
                  name: 'design',
                  label: $t('lcdp.bpm.processDefine.grid.toolbar.design'),
                  icon: 'bi-brush',
                  enableIf: (arg) => {
                    if (arg.selected) {
                      if ('SKETCH' === arg.selected.status) {
                        return true;
                      }
                    }
                    return false;
                  },
                  click: (arg) => {
                    if (arg.selected) {
                      let title = $t('lcdp.bpm.designer.dialog.title.prefix');
                      title += ' - ' + arg.selected.name;
                      title += arg.selected.version ? ' (' + arg.selected.version + ')' : '';
                      processDesignerDialogRef.open(title, arg.selected.id);
                    }
                  },
                },
                {
                  name: 'deployment',
                  label: $t('lcdp.bpm.processDefine.grid.toolbar.deployment'),
                  icon: 'bi-arrow-up-circle',
                  enableIf: (arg) => {
                    if (arg.selected) {
                      if ('SKETCH' === arg.selected.status) {
                        return true;
                      }
                    }
                    return false;
                  },
                  click: (arg) => {
                    DialogManager.confirm($t('lcdp.bpm.processDefine.grid.toolbar.deployment.tip'), () => {
                      axios.post(Environment.apiContextPath('api/flowable/process/deploy/') + arg.selected.id).then(() => {
                        processDefineGridRef.refresh();
                        NotifyManager.success();
                      });
                    });
                  },
                },
                'separator',
                {
                  name: 'createProcessInstance',
                  label: $t('lcdp.bpm.processDefine.grid.toolbar.createProcessInstance'),
                  icon: 'bi-file-plus',
                  enableIf: (arg) => {
                    if (arg.selected) {
                      if ('RELEASE' === arg.selected.status) {
                        return true;
                      }
                    }
                    return false;
                  },
                  click: (arg) => {
                    if (arg.selected) {
                      createProcessInstanceDialogRef.open(arg.selected.key, arg.selected.name);
                    }
                  },
                },
                {
                  name: 'queryProcessInstance',
                  label: $t('lcdp.bpm.processDefine.grid.toolbar.queryProcessInstance'),
                  icon: 'bi-list-ul',
                  enableIf: (arg) => {
                    if (arg.selected) {
                      if ('SKETCH' != arg.selected.status) {
                        return true;
                      }
                    }
                    return false;
                  },
                  click: (arg) => {
                    if (arg.selected) {
                      selectedTabRef = 'processInstance';
                      nextTick(() => {
                        processInstanceGridRef.getQueryForm().setFieldValue('deployedId', arg.selected.deployedId);
                        processInstanceGridRef.refresh();
                      });
                    }
                  },
                },
                'separator',
                'view',
                'separator',
                'export',
              ]"
              :columns="[
                { width: 150, name: 'key', label: $t('code') },
                {
                  width: '100%',
                  name: 'name',
                  label: $t('name'),
                  format: (value, row) => {
                    return Formater.dictionary(ProcessCategoryDictionaries)(row.key);
                  },
                },
                { width: 60, name: 'version', label: $t('version') },
                { width: 60, name: 'status', label: $t('status'), format: Formater.enum(ProcessStatusEnum) },
                { width: 250, name: 'deployedId', label: $t('lcdp.bpm.processDefine.grid.entity.deployId') },
                {
                  width: 90,
                  name: 'canClaimTask',
                  label: $t('lcdp.bpm.processDefine.grid.entity.canClaimTask'),
                  format: Formater.yesNo(),
                },
                { width: 100, name: 'lastModifier', label: $t('lastModifier') },
                { width: 110, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
              ]"
              :editor="{
                dialog: {
                  width: '600px',
                },
                form: {
                  colsNum: 1,
                  fields: [
                    {
                      name: 'category',
                      label: $t('category'),
                      type: 'select',
                      defaultValue: 'SAMPLE',
                      options: Options.dictionary(ProcessCategoryDictionaries),
                      'onUpdate:modelValue': (value) => {
                        const form = processDefineGridRef.getEditorForm();
                        form.setFieldValue('key', value);
                        form.setFieldValue('name', Formater.dictionary(ProcessCategoryDictionaries)(value));
                      },
                    },
                    {
                      name: 'key',
                      label: $t('code'),
                      type: 'text',
                      defaultValue: 'SAMPLE',
                      readonlyIf: () => {
                        return true;
                      },
                    },
                    {
                      name: 'name',
                      label: $t('name'),
                      type: 'text',
                      required: true,
                      defaultValue: Formater.dictionary(ProcessCategoryDictionaries)('SAMPLE'),
                      readonlyIf: () => {
                        return true;
                      },
                    },
                    { name: 'description', label: $t('description'), type: 'textarea', rows: 1 },
                    { name: 'xml', label: $t('xml'), type: 'textarea' },
                    { name: 'status', label: $t('status'), type: 'text', defaultValue: 'SKETCH', hidden: true },
                    { name: 'canClaimTask', label: $t('lcdp.bpm.processDefine.grid.entity.canClaimTask'), type: 'checkbox', defaultValue: true, rule: [] },
                  ],
                },
              }"
              :viewer="{
                panel: {
                  columnNum: 1,
                  fields: [
                    { name: 'id', label: $t('id') },
                    { name: 'category', label: $t('category') },
                    { name: 'key', label: $t('code') },
                    { name: 'name', label: $t('name'), format: Formater.none() },
                    { name: 'description', label: $t('description') },
                    { name: 'version', label: $t('version') },
                    { name: 'status', label: $t('status'), format: Formater.enum(ProcessStatusEnum) },
                    { name: 'deployedId', label: $t('lcdp.bpm.deployId') },
                    { name: 'canClaimTask', label: $t('lcdp.bpm.processDefine.grid.entity.canClaimTask'), format: Formater.none() },
                    { name: 'lastModifier', label: $t('lastModifier') },
                    { name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.none() },
                  ],
                },
              }"
            ></w-grid>
          </q-tab-panel>
          <q-tab-panel name="processInstance" class="pl-2 pb-0" style="height: 100%; padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
            <w-grid
              ref="processInstanceGridRef"
              :title="$t('lcdp.bpm.processInstance.grid.title')"
              :checkbox-selection="false"
              :data-url="Environment.apiContextPath('/api/flowable/process/query/instance')"
              :auto-fetch-data="false"
              :pageable="true"
              :pagination="{}"
              :query-form-cols-num="3"
              :query-form-fields="[
                { name: 'key', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionKey'), type: 'text' },
                { name: 'name', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionName'), type: 'text' },
                { name: 'deployedId', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionId'), type: 'text' },
              ]"
              :toolbar-actions="[
                'query',
                'separator',
                'refresh',
                'separator',
                {
                  name: 'queryTask',
                  label: $t('lcdp.bpm.processInstance.grid.toolbar.queryTask'),
                  icon: 'bi-list-ul',
                  enableIf: (arg) => {
                    return arg.selected;
                  },
                  click: (arg) => {
                    if (arg.selected) {
                      selectedTabRef = 'task';
                      nextTick(() => {
                        taskGridRef.getQueryForm().setFieldValue('processInstanceId', arg.selected.id);
                        taskGridRef.refresh();
                      });
                    }
                  },
                },
                {
                  name: 'variables',
                  label: $t('lcdp.bpm.task.grid.toolbar.variables'),
                  icon: 'bi-record',
                  enableIf: (arg) => {
                    return arg.selected;
                  },
                  click: (arg) => {
                    if (arg.selected) {
                      variableDialogRef.open(arg.selected.id);
                    }
                  },
                },
                'separator',
                'view',
                'separator',
                'export',
              ]"
              :columns="[
                { name: 'processDefinitionKey', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionKey') },
                { name: 'processDefinitionName', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionName') },
                { name: 'id', label: $t('id'), hidden: true },
                { name: 'businessKey', label: $t('lcdp.bpm.processInstance.grid.entity.bussinessKey') },
                { name: 'startTime', label: $t('lcdp.bpm.processInstance.grid.entity.startTime') },
                { name: 'startUserId', label: $t('lcdp.bpm.processInstance.grid.entity.startUserId') },
                { name: 'suspended', label: $t('lcdp.bpm.processInstance.grid.entity.suspended') },
                { name: 'processDefinitionId', label: $t('lcdp.bpm.processInstance.grid.entity.processDefinitionId'), hidden: true },
              ]"
              :editor="{
                dialog: {
                  width: '600px',
                },
                form: {
                  colsNum: 1,
                  fields: [],
                },
              }"
              :viewer="{
                panel: {
                  columnNum: 1,
                  fields: [],
                },
              }"
            ></w-grid>
          </q-tab-panel>
          <q-tab-panel name="task" class="pl-2 pb-0" style="height: 100%; padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
            <w-grid
              ref="taskGridRef"
              :title="$t('lcdp.bpm.task.grid.title')"
              :checkbox-selection="false"
              :data-url="Environment.apiContextPath('/api/flowable/process/query/task')"
              :auto-fetch-data="false"
              :pageable="true"
              :pagination="{ sortBy: 'createTime', descending: true }"
              :query-form-cols-num="3"
              :query-form-fields="[
                { name: 'processInstanceId', label: $t('lcdp.bpm.task.grid.entity.processInstanceId'), type: 'text', queryOperator: 'equals' },
              ]"
              :toolbar-actions="[
                'query',
                'separator',
                'refresh',
                'separator',
                [
                  {
                    label: $t('operation'),
                    icon: 'bi-cursor',
                  },
                  {
                    name: 'complete',
                    label: $t('lcdp.bpm.task.grid.toolbar.complete'),
                    icon: 'bi-caret-right',
                    enableIf: function (arg) {
                      return arg.selected;
                    },
                    click: (arg) => {
                      if (arg.selected) {
                        completeTaskDialogRef.open(arg.selected.id);
                      }
                    },
                  },
                  {
                    name: 'claim',
                    label: $t('lcdp.bpm.task.grid.toolbar.claim'),
                    icon: 'bi-clipboard-check',
                    enableIf: function (selecteds) {
                      return selecteds && selecteds.length > 0 && !selecteds[0].assignee;
                    },
                    click: (arg) => {
                      if (arg.selected) {
                        DialogManager.confirm($t('lcdp.bpm.task.grid.toolbar.claim.tip'), () => {
                          axios.post(Environment.apiContextPath('/api/flowable/process/operation/claim/') + arg.selected.id).then(() => {
                            taskGridRef.refresh();
                            NotifyManager.success();
                          });
                        });
                      }
                    },
                  },
                  {
                    name: 'unclaim',
                    label: $t('lcdp.bpm.task.grid.toolbar.unclaim'),
                    icon: 'bi-clipboard-x',
                    enableIf: function (arg) {
                      return arg.selected && arg.selected.assignee;
                    },
                    click: (arg) => {
                      if (arg.selected) {
                        DialogManager.confirm($t('lcdp.bpm.task.grid.toolbar.unclaim.tip'), () => {
                          axios.post(Environment.apiContextPath('/api/flowable/process/operation/unClaim/') + arg.selected.id).then(() => {
                            taskGridRef.refresh();
                            NotifyManager.success();
                          });
                        });
                      }
                    },
                  },
                  {
                    name: 'jump',
                    label: $t('lcdp.bpm.task.grid.toolbar.jump'),
                    icon: 'bi-sign-turn-right',
                    enableIf: function (arg) {
                      return arg.selected;
                    },
                    click: (arg) => {
                      if (arg.selected) {
                        jumpTaskDialogRef.open(arg.selected.id);
                      }
                    },
                  },
                  {
                    name: 'terminate',
                    label: $t('lcdp.bpm.task.grid.toolbar.terminate'),
                    icon: 'bi-stop',
                    enableIf: function (arg) {
                      return arg.selected;
                    },
                    click: (arg) => {
                      if (arg.selected) {
                        DialogManager.confirm($t('lcdp.bpm.task.grid.toolbar.terminate.tip'), () => {
                          axios.post(Environment.apiContextPath('/api/flowable/process/operation/terminateProcessInstance/') + arg.selected.id).then(() => {
                            taskGridRef.refresh();
                            NotifyManager.success();
                          });
                        });
                      }
                    },
                  },
                ],
                {
                  name: 'variables',
                  label: $t('lcdp.bpm.task.grid.toolbar.variables'),
                  icon: 'bi-record',
                  enableIf: function (arg) {
                    return arg.selected;
                  },
                  click: (arg) => {
                    if (arg.selected) {
                      variableDialogRef.open(arg.selected.processInstanceId);
                    }
                  },
                },
                'separator',
                'view',
                'separator',
                'export',
              ]"
              :columns="[
                { name: 'id', label: $t('id') },
                { name: 'name', label: $t('name') },
                { name: 'owner', label: $t('lcdp.bpm.task.grid.entity.owner') },
                { name: 'assignee', label: $t('lcdp.bpm.task.grid.entity.assignee') },
                { name: 'createTime', label: $t('lcdp.bpm.task.grid.entity.createTime') },
                { name: 'claimTime', label: $t('lcdp.bpm.task.grid.entity.claimTime') },
                { name: 'processInstanceId', label: $t('lcdp.bpm.task.grid.entity.processInstanceId') },
              ]"
              :editor="{
                dialog: {
                  width: '600px',
                },
                form: {
                  colsNum: 1,
                  fields: [],
                },
              }"
              :viewer="{
                panel: {
                  columnNum: 1,
                  fields: [],
                },
              }"
            ></w-grid>
          </q-tab-panel>
          <q-tab-panel name="tools">
            <div class="flex 'justify-center' gap-4">
              <q-btn :label="$t('lcdp.bpm.tools.action.cleanRuntimeData')" color="primary" no-caps @click="cleanRuntimeData"></q-btn>
              <q-btn :label="$t('lcdp.bpm.tools.action.cleanHistoryData')" color="primary" no-caps @click="cleanHistoryData"></q-btn>
            </div>
          </q-tab-panel>
        </q-tab-panels>
      </template>
    </q-splitter>

    <ProcessDesigner ref="processDesignerDialogRef">
      <iframe ref="processDesignerIframeRef" src="#" style="width: 100%; height: 100%"></iframe>
    </ProcessDesigner>

    <CreateProcessInstanceDialog ref="createProcessInstanceDialogRef"></CreateProcessInstanceDialog>
    <VariableDialog ref="variableDialogRef"></VariableDialog>
    <CompleteTaskDialog ref="completeTaskDialogRef" @after-task-completed="afterTaskCompleted"></CompleteTaskDialog>
    <JumpTaskDialog ref="jumpTaskDialogRef"></JumpTaskDialog>
  </div>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment, DialogManager, NotifyManager, axios, EnumTools, DictionaryTools, Formater, Options } from 'platform-core';
import ProcessDesigner from './ProcessDesigner.vue';
import CreateProcessInstanceDialog from './CreateProcessInstanceDialog.vue';
import VariableDialog from './VariableDialog.vue';
import CompleteTaskDialog from './CompleteTaskDialog.vue';
import JumpTaskDialog from './JumpTaskDialog.vue';

const { t } = useI18n();
const selectedTabRef = ref('processDefine');
const processDefineGridRef = ref();
const processInstanceGridRef = ref();
const taskGridRef = ref();
const variableDialogRef = ref();
const completeTaskDialogRef = ref();
const jumpTaskDialogRef = ref();

const processDesignerDialogRef = ref();
const processDesignerIframeRef = ref();
const createProcessInstanceDialogRef = ref();

const afterTaskCompleted = () => {
  NotifyManager.success();
  taskGridRef.value.refresh();
};

const cleanRuntimeData = () => {
  DialogManager.confirm(t('lcdp.bpm.tools.action.cleanRuntimeData.tip'), () => {
    axios.post(Environment.apiContextPath('/api/flowable/tools/cleanRuntimeData')).then(() => {
      NotifyManager.success();
    });
  });
};

const cleanHistoryData = () => {
  DialogManager.confirm(t('lcdp.bpm.tools.action.cleanHistoryData.tip'), () => {
    axios.post(Environment.apiContextPath('/api/flowable/tools/cleanHistoryData')).then(() => {
      NotifyManager.success();
    });
  });
};

const ProcessStatusEnum = await EnumTools.fetch('io.sc.platform.flowable.enums.ProcessStatus');
const ProcessCategoryDictionaries = await DictionaryTools.fetch('WORK_FLOW');
</script>
