<template>
  <div @click.stop="open">
    <InputModel
      :value="props.ruleConfig.name"
      :placeholder="t('配置规则流程')"
      style="width: 100%; min-width: 100px"
    />
    <ModalPanel
      :visible="visible"
      :width="900"
      :title="t('规则流程配置')"
      @submit="submit"
      @close="close"
    >
      <NodeHead :nodeName="t('规则流程信息')" class="ml-4 my-4" />
      <SelectRuleProcessTemplate :config="data.config" @setConfig="setConfig" />
      <!-- 参数配置 -->
      <a-table :columns="columns" :data-source="data.dataSource" :pagination="false">
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'name'"> {{ record.name }} </template>
          <template v-else-if="column.key === 'type'">
            {{ getTypeOptionName(record.type) }}
          </template>
          <template v-else-if="column.key === 'assignmentType'">
            <a-select
              v-model:value="record.assignmentType"
              style="width: 220px"
              :placeholder="t('请选择赋值类型')"
              :options="data.assignmentTypeList"
              allowClear
              @change="record.assignmentValue = ''"
            />
          </template>
          <template v-else-if="column.key === 'assignmentValue'">
            <a-tree-select
              v-model:value="record.assignmentValue"
              show-search
              style="width: 220px"
              :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
              :placeholder="t('点击选择表单数据')"
              allow-clear
              tree-default-expand-all
              :tree-data="data.dataInfo"
              @select="(_, node) => handleSelect(node, record)"
              v-if="record.assignmentType === AssignmentTypeToRuleType.FORM"
            />
            <a-input
              style="width: 220px"
              v-model:value="record.assignmentValue"
              :placeholder="
                record.assignmentType === AssignmentTypeToRuleType.VALUE
                  ? t('请填写值')
                  : t('请先选择赋值类型后再配置值')
              "
              v-else
            />
          </template>
        </template>
      </a-table>
    </ModalPanel>
  </div>
</template>

<script setup lang="ts">
import { inject, reactive, ref } from "vue";
import { NodeHead, ModalPanel } from "/@/components/ModalPanel/index";
import { InputModel } from "/@/components/ApiConfig";
import { SelectRuleProcessTemplate } from "/@/components/RuleProcess";
import { message } from "ant-design-vue";
import { cloneDeep } from "lodash-es";
import { useI18n } from "/@/hooks/web/useI18n";
import {
  RuleProcessConfig,
  RuleProcessConfigListModel,
} from "/@/components/RuleProcess/src/interface";
import { OperationType } from "/@/enums/workflowEnum";
import { isValidJSON } from "/@/utils/event/design";
import { AssignmentTypeToRuleType } from "/@/api/ruleProcess/model";
import { infoMap } from "/@/components/Designer";
const { t } = useI18n();
const widgetForm = inject("widgetForm") as any;
const emit = defineEmits(["change"]);
let props = withDefaults(
  defineProps<{
    ruleConfig: RuleProcessConfig;
    exampleStr?: string;
    needHideComponents?: Boolean;
    isGlobalParams?: Boolean;
    hasFormParams?: Boolean;
  }>(),
  {
    ruleConfig: () => {
      return {
        id: "",
        name: "",
        processParamConfigs: [],
      };
    },
    exampleStr: `{
        code: 0,
        msg: 'success',
        data: 'value',
      }`,
    needHideComponents: () => {
      return false;
    },
    isGlobalParams: () => {
      return false;
    },
    // 表单设计表单事件中、执行按钮执行事件中 需要表单数据
    // 桌面设计 执行按钮执行事件中 不需要表单数据 需要组件数据
    hasFormParams: () => {
      return true;
    },
  }
);
let typeOptions = [
  {
    id: OperationType.VALUE,
    name: t("值"),
  },
  {
    id: OperationType.VARIABLE,
    name: t("变量"),
  },
  {
    id: OperationType.API,
    name: "API",
  },
];

const columns = [
  {
    title: "参数名称",
    key: "name",
  },
  {
    title: "参数类型",
    key: "type",
  },
  {
    title: "赋值类型",
    key: "assignmentType",
    width: 220,
  },
  {
    title: "赋值配置",
    key: "assignmentValue",
    width: 220,
  },
];
let data: {
  assignmentTypeList: any;
  dataSource: unknown;
  dataInfo: any[];
  config: RuleProcessConfig;
} = reactive({
  config: cloneDeep(props.ruleConfig),
  dataSource: [],
  dataInfo: [],
  assignmentTypeList: [],
});

const visible = ref<boolean>(false);
function open() {
  if (props.hasFormParams) {
    data.assignmentTypeList = [
      {
        label: t("默认值"),
        value: AssignmentTypeToRuleType.DEFAULT,
      },
      {
        label: t("值"),
        value: AssignmentTypeToRuleType.VALUE,
      },
      {
        label: t("表单数据"),
        value: AssignmentTypeToRuleType.FORM,
      },
    ];
    data.dataInfo = [
      {
        title: t("表单数据"),
        value: "formData",
        disabled: true,
        children: [],
      },
      {
        title: "隐藏组件",
        value: "hiddenComponents",
        disabled: true,
        children: [],
      },
      {
        title: "当前信息",
        value: "currentInfo",
        disabled: true,
        children: infoMap,
      },
    ];
  } else {
    data.assignmentTypeList = [
      {
        label: t("默认值"),
        value: AssignmentTypeToRuleType.DEFAULT,
      },
      {
        label: t("值"),
        value: AssignmentTypeToRuleType.VALUE,
      },
      {
        label: t("组件数据"),
        value: AssignmentTypeToRuleType.FORM,
      },
    ];
    data.dataInfo = [
      {
        title: "当前信息",
        value: "currentInfo",
        disabled: true,
        children: infoMap,
      },
    ];
  }
  data.config = cloneDeep(props.ruleConfig);
  data.dataSource = data.config.processParamConfigs;
  if (props.hasFormParams && !!widgetForm?.value) {
    initFormData();
  }
  visible.value = true;
}
function close() {
  visible.value = false;
}
const filterComps = [
  "divider",
  "upload",
  "image",
  "qrcode",
  "button",
  "map",
  "opinion",
  "title",
  //'form-view',
];
const getSelectedList = (list, bindTable?, key?) => {
  list?.map((item) => {
    if (["tab", "grid", "card"].includes(item.type)) {
      for (const child of item.layout!) {
        getSelectedList(child.list);
      }
    } else if (item.type == "table-layout") {
      for (const child of item.layout!) {
        for (const chilLi of child.list) {
          getSelectedList(chilLi.children);
        }
      }
    } else if (item.type == "one-for-one") {
      getSelectedList(item.children, item.bindTable, item.key);
    } else if (item.type !== "form" && !filterComps.includes(item.type)) {
      let params: string[] = [];
      if (item.options.datasourceType == "api" && item.options.apiConfig.apiParams) {
        item.options.apiConfig.apiParams.forEach((p) => {
          p.tableInfo &&
            p.tableInfo.forEach((o) => {
              const value = isValidJSON(o.value);
              if (value) params.push(value.fieldKey);
            });
        });
      }
      // if (item.key !== props.formItem?.key && !params.includes(props.formItem?.key)) {
      let bindField = item.bindField;
      if (item.type == "time-range" || item.type == "date-range") {
        bindField = item.bindStartTime + "," + item.bindEndTime;
      }
      let obj = {
        bindField: bindField,
        bindTable: bindTable,
        tableKey: key,
        fieldKey: item.key,
      };
      data.dataInfo[0].children.push({
        title:
          item.label +
          (item.type == "user" || (item.type == "info" && item.options.infoType === 0)
            ? "-ID"
            : ""),
        value: JSON.stringify(obj),
      });
      if (item.type == "user" || (item.type == "info" && item.options.infoType === 0)) {
        let obj = {
          bindField: bindField,
          bindTable: bindTable,
          tableKey: key,
          fieldKey: item.key,
          options: {
            type: item.type,
            showName: true,
          },
        };
        data.dataInfo[0].children.push({
          title: item.label + "-名称",
          value: JSON.stringify(obj),
        });
      }
      // }
    }
  });
};
function initFormData() {
  data.dataInfo[0].children = [];
  widgetForm?.value?.hiddenComponent?.map((com) => {
    let obj = {
      bindField: com.bindField,
      bindTable: "",
      tableKey: "",
      fieldKey: com.key,
    };
    data.dataInfo[1].children.push({
      title: com.label,
      value: JSON.stringify(obj),
    });
  });
  if (widgetForm?.value?.list.length) {
    getSelectedList(widgetForm.value.list);
  }
}
function submit() {
  let json = { ...data.config, processParamConfigs: data.dataSource };
  emit("change", cloneDeep(json));
  close();
}
function setConfig(config: RuleProcessConfigListModel) {
  if (config.id) data.config.id = config.id;
  if (config.name) data.config.name = config.name;
  if (config.jsonContent) {
    let jsonObj = JSON.parse(config.jsonContent);
    if (jsonObj.processParamConfigs && Array.isArray(jsonObj.processParamConfigs)) {
      data.dataSource = jsonObj.processParamConfigs.map((ele) => {
        return {
          ...ele,
          assignmentType: data.assignmentTypeList[0].value,
          assignmentValue: "",
        };
      });
    }
  }
}
const handleSelect = ({ value }, record) => {
  if (!value) {
    message.error(t("请先选择该组件的绑定表及绑定字段"));
    record.assignment = null;
  }
};

function getTypeOptionName(type) {
  let arr = typeOptions.filter((ele) => {
    return ele.id == type;
  });
  if (arr.length > 0) {
    return arr[0].name;
  } else {
    return "";
  }
}
</script>

<style lang="less" scoped>
.padding {
  padding: 10px 20px;
}

.btn-item {
  position: absolute;
  bottom: 10px;
  left: 16px;
}

.editor-box {
  width: 300px;
  position: absolute;
  height: 350px;
  left: 140px;
  bottom: 13px;
  border: 1px solid #ccc;
  box-shadow: 0 0 6px 3px #ccc;

  .editor-close {
    position: absolute;
    top: -3px;
    right: 13px;
    font-size: 16px;
    cursor: pointer;
  }

  .editor-copy {
    position: absolute;
    bottom: 5px;
    right: 15px;
    cursor: pointer;
    z-index: 999;
    color: #5e95ff;
  }
}
</style>
