<script setup lang="ts">
import { Subject } from 'rxjs';
import { IActionParam, IParam, ControlAction, TreeControl, IContext } from '@core';
import { FileTextOutlined } from '@ant-design/icons-vue';
import { ctrlState } from './{{spinalCase ctrl.codeName}}-tree-state';

interface Props {
  name:string,
  parent: IParam;
  context: IContext;
  selectFirstDefault?: boolean;
  isBranchAvailable?: boolean;
  viewParams?: IParam;
  controlAction: ControlAction;
  showBusyIndicator?: boolean;
  multiple?: boolean;
  viewSubject: Subject<IActionParam>;
  selectedData?: IParam[];
}

const props = withDefaults(defineProps<Props>(), {
  viewSubject: () => new Subject<IActionParam>(),
  showBusyIndicator: true,
  selectFirstDefault: false,
  isBranchAvailable: false,
  multiple: false
})

// emit声明
interface CtrlEmit {
  (name: "ctrlEvent", value: IActionParam): void;
}
const emit = defineEmits<CtrlEmit>();

//  获取自定义图标
const getCustomIcon = (scriptCode: any) => {
  let icon: string = '';
  const code = scriptCode.replace(new RegExp('return', 'g'), `icon =`);
  eval(code);
  return icon;
}

//  获取自定义文本
const getCustomText = (scriptCode: any) => {
  let text: string = '';
  const code = scriptCode.replace(new RegExp('return', 'g'), `text =`);
  eval(code);
  return text;
}

// 安装功能模块，提供状态和能力方法
const { name, state, load, refresh, onTreeNodeSelect, onContextMenuClick, onRightClick, onCheck, getCounterData } = new TreeControl(ctrlState, props, emit).moduleInstall();

// 暴露内部状态及能力
defineExpose({ name, state, load, refresh });
</script>

<template>
  <a-tree
    class="app-tree{{#if ctrl.psSysCss}} {{ctrl.psSysCss.cssName}}{{/if}}"
    :blockNode="true"
    :tree-data="state.items"
    :load-data="load"
    :fieldNames="{ title: 'text', key: 'id' }"
    :checkable="state.isMultiple"
    :multiple="state.isMultiple"
    show-icon
    v-model:expandedKeys="state.expandedKeys"
    v-model:selectedKeys="state.selectedKeys"
    v-model:checkedKeys="state.selectedKeys"
    @select="onTreeNodeSelect"
    @rightClick="onRightClick"
    @check="onCheck">
      <template #icon="node">
        <span class="app-tree-node__icon">
          <template v-if="node.iconCustomCode && node.iconScriptCode">
            <span :domPropsInnerHtml="getCustomIcon(node.iconScriptCode)"></span>
          </template>
          <template v-else-if="node.iconcls">
            <i :class="node.iconcls"></i>
          </template>
          <template v-else-if="node.icon">
            <img :src="node.icon" style='width:14px;height:14px;vertical-align: bottom;'/>
          </template>
          <template v-else-if="state.outputIconDefault">
            <FileTextOutlined />
          </template>
        </span>
      </template>
      <template #title="node">
      {{#if (and ctrl.psAppCounterRef ctrl.psAppCounterRef.psAppCounter)}}
        <a-dropdown :trigger="['contextmenu']">
          <span
            :class="['app-tree-node__text', node.cssName]"
            :title="node.tooltip ? node.tooltip : node.text">
            <a-badge v-if="node.counterId" class="node__text-badge" :count="getCounterData(node.counterId)">
              <template v-if="node.textCustomCode && node.textScriptCode">
                <span :domPropsInnerHtml="getCustomText(node.textScriptCode)"></span>
              </template>
              <template v-else-if="node.html">
                <span :domPropsInnerHtml="node.html"></span>
              </template>
              <template v-else>
                <span>\{{node.text}}</span>
              </template>
            </a-badge>
            <template v-else>
              <template v-if="node.textCustomCode && node.textScriptCode">
                <span :domPropsInnerHtml="getCustomText(node.textScriptCode)"></span>
              </template>
              <template v-else-if="node.html">
                <span :domPropsInnerHtml="node.html"></span>
              </template>
              <template v-else>
                <span>\{{node.text}}</span>
              </template>
            </template>
          </span>
          <template #overlay v-if="state.contextMenus[node.nodeType] && state.contextMenus[node.nodeType].length">
            <a-menu class="tree-node__context-menu" @click="(event) => onContextMenuClick(node, event)">
              <AppTreeContextMenuItem
                v-for="(item, index) in state.contextMenus[node.nodeType]"
                :key="index"
                :menu="item"
                :context="state.context"
                :viewParams="state.viewParams"
              />
            </a-menu>
          </template>
        </a-dropdown>
      {{else}}
        <a-dropdown :trigger="['contextmenu']">
          <span
            :class="['app-tree-node__text', node.cssName]"
            :title="node.tooltip ? node.tooltip : node.text">
            <template v-if="node.textCustomCode && node.textScriptCode">
              <span :domPropsInnerHtml="getCustomText(node.textScriptCode)"></span>
            </template>
            <template v-else-if="node.html">
              <span :domPropsInnerHtml="node.html"></span>
            </template>
            <template v-else>
              <span>\{{node.text}}</span>
            </template>
          </span>
          <template #overlay v-if="state.contextMenus[node.nodeType] && state.contextMenus[node.nodeType].length">
            <a-menu class="tree-node__context-menu" @click="(event) => onContextMenuClick(node, event)">
              <AppTreeContextMenuItem
                v-for="(item, index) in state.contextMenus[node.nodeType]"
                :key="index"
                :menu="item"
                :context="state.context"
                :viewParams="state.viewParams"
              />
            </a-menu>
          </template>
        </a-dropdown>
      {{/if}}
      </template>
    </a-tree>
</template>

<style lang="scss" scoped>
.app-tree-node {
  text-align: left;
}
</style>