<template>
  <span @click.stop="open"
    ><slot></slot>
    <ModalPanel
      :visible="data.visible"
      :width="1100"
      :title="t('API配置')"
      @submit="submit"
      @close="close"
    >
      <NodeHead class="mb-3 mt-3 ml-3" :nodeName="t('API配置')" />
      <div class="form-box">
        <div class="label"><em class="text-red-600">*</em>{{ t('打印模板') }}：</div>
        <a-select
          class="flex"
          v-model:value="data.printId"
          style="width: 100%"
          placeholder="请选择打印模板"
          @change="submitPrintId"
        >
          <a-select-option
            v-for="(item, index) in data.printData"
            :key="index"
            :value="item.id"
            :disabled="item.enabledMark == 0"
          >
            {{ item.name }}</a-select-option
          >
        </a-select>
      </div>
      <div class="form-box">
        <div class="item">
          <div class="label"><em class="text-red-600">*</em>{{ t('接口名称') }}：</div>
          <a-input
            v-model:value="data.config.name"
            :placeholder="t('点击选择接口')"
            disabled
            style="width: 100%"
            class="flex"
          >
            <template #suffix>
              <Icon icon="ant-design:ellipsis-outlined" />
            </template>
          </a-input>
        </div>
        <div class="item">
          <div class="label"><em class="text-red-600">*</em>{{ t('请求方法') }}：</div>
          <a-input
            v-model:value="data.config.method"
            disabled
            :placeholder="t('请求方法')"
            class="flex"
            style="width: 100%"
          >
            <template #suffix>
              <Icon icon="ant-design:ellipsis-outlined" />
            </template>
          </a-input>
        </div>
      </div>
      <a-tabs v-if="data.visible" class="padding">
        <a-tab-pane :key="item.key" :tab="item.title" v-for="item in data.apiParams">
          <a-table
            :dataSource="item.tableInfo"
            :columns="apiConfigColumns"
            :pagination="false"
            :scroll="{ y: '260px' }"
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'assignmentType'">
                <a-select
                  v-model:value="record.assignmentType"
                  style="width: 100%"
                  :placeholder="t('请选择赋值类型')"
                >
                  <a-select-option :value="bind.value" v-for="bind in bindType" :key="bind.value">
                    {{ bind.label }}
                  </a-select-option>
                </a-select>
              </template>
              <template v-else-if="column.key === 'value'">
                <a-tree-select
                  v-if="record.assignmentType === 'data'"
                  v-model:value="record.config"
                  show-search
                  style="width: 100%"
                  :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                  placeholder="Please select"
                  allow-clear
                  tree-default-expand-all
                  :tree-data="data.formConfigData"
                  :field-names="{
                    children: 'children',
                    label: 'title',
                    value: 'key',
                  }"
                />
                <a-input
                  v-else
                  v-model:value="record.value"
                  :placeholder="record.type ? t('请填写值') : t('请先选择赋值类型后再配置值')"
                />
              </template>
            </template>
          </a-table>
        </a-tab-pane>
      </a-tabs>
    </ModalPanel>
  </span>
</template>

<script setup lang="ts">
  import { NodeHead, ModalPanel } from '/@/components/ModalPanel/index';
  import { reactive, ref } from 'vue';
  import { Icon } from '/@/components/Icon';
  import { ApiConfig, InputParamItem } from '/@/components/ApiConfig/src/interface';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { TreeProps, notification } from 'ant-design-vue';
  import { PrintBasicData, PrintButtonRowItem, PrintConfigData } from '/@/model/generator/print';
  import {
    addPrintConfig,
    getDesignInfo,
    getDesignPrintList,
    getPrintConfigInfo,
  } from '/@/api/system/generator/print';
  import { camelCaseString } from '/@/utils/event/design';
  const { t } = useI18n();
  const props = withDefaults(
    defineProps<{
      row: PrintButtonRowItem;
      hasMetaFormId: Boolean;
    }>(),
    {},
  );
  const bindType = ref([
    {
      label: t('值'),
      value: 'value',
    },
  ]);
  let emits = defineEmits(['close']);
  let data: {
    visible: boolean;
    printId: string;
    printData: Array<PrintBasicData>;
    config: ApiConfig;
    formConfigData: TreeProps['treeData'];
    apiParams: Array<{ key: string; title: string; tableInfo: Array<InputParamItem> }>;
  } = reactive({
    visible: false,
    printId: '',
    printData: [],
    formConfigData: [],
    config: {
      id: '',
      name: '',
      method: '',
      requestParamsConfigs: [], //Query Params
      requestHeaderConfigs: [], //Header
      requestBodyConfigs: [], //Body
    },
    apiParams: [
      {
        key: '1',
        title: 'Query Params',
        tableInfo: [],
      },
      {
        key: '2',
        title: 'Header',
        tableInfo: [],
      },
      {
        key: '3',
        title: 'Body',
        tableInfo: [],
      },
    ],
  });

  function setApiConfig() {
    data.apiParams[0].tableInfo = data.config.requestParamsConfigs;

    data.apiParams[1].tableInfo = data.config.requestHeaderConfigs;

    data.apiParams[2].tableInfo = data.config.requestBodyConfigs;
  }
  async function submitPrintId(id) {
    let res = await getDesignInfo(id);
    if (res) {
      data.config = JSON.parse(res.apiConfig);
      setApiConfig();
    }
  }
  async function open() {
    data.formConfigData = [];
    data.visible = true;
    try {
      if (props.hasMetaFormId) {
        bindType.value = [
          {
            label: t('值'),
            value: 'value',
          },
          {
            label: t('表单数据'),
            value: 'data',
          },
        ];
      }
      let res = await getDesignPrintList();
      data.printData = res;
      let info = await getPrintConfigInfo(getButtonCode(), props.row.menuId);
      if (info.enabledMark == null) {
        // notification.warning({
        //   message: t('提示'),
        //   description: t('当前功能未绑定打印模板，请绑定后再进行模板打印。'),
        // });
        if (props.hasMetaFormId && info.formJson) {
          let formConfig = JSON.parse(info.formJson);
          let formType = 1;
          if (info.formType == 0) {
            //表单类型:0 系统表单 1 自定义表单
            formType = 0;
          }
          let arr = getSchemasConfig(formConfig.formJson.list, formType);
          data.formConfigData = arr;
        }
      } else {
        if (info.enabledMark == 0) {
          notification.warning({
            message: t('提示'),
            description: t('找不到打印模板，请联系管理员。'),
          });
        } else {
          if (props.hasMetaFormId && info.formJson) {
            let formConfig = JSON.parse(info.formJson);
            let formType = 1;
            if (info.formType == 0) {
              //表单类型:0 系统表单 1 自定义表单
              formType = 0;
            }
            let arr = getSchemasConfig(formConfig.formJson.list, formType);
            data.formConfigData = arr;
          }

          if (info.schemaId) {
            data.printId = info.schemaId;
          }
          if (info.apiConfig) {
            data.config = JSON.parse(info.apiConfig);
            setApiConfig();
          }
        }
      }
    } catch (error) {}
  }
  function close() {
    data.visible = false;
    emits('close');
  }
  function getButtonCode() {
    let buttonCode = props.row.code;
    if (props.row.code.includes(':')) {
      let arr = props.row.code.split(':');
      arr.shift();
      buttonCode = arr.join('');
    }
    return buttonCode;
  }
  async function submit() {
    // 提交配置

    let submitData: PrintConfigData = {
      apiConfig: JSON.stringify(data.config),
      buttonCode: getButtonCode(),
      buttonId: props.row.id,
      menuId: props.row.menuId,
      schemaId: data.printId,
    };
    try {
      let res = await addPrintConfig(submitData);
      if (res) {
        close();
      }
    } catch (error) {}
  }
  function getSchemasConfig(list, formType) {
    const arr: TreeProps['treeData'] = [];
    if (list && list.length > 0) {
      list.forEach((ele1) => {
        if (['card', 'Card', 'tab', 'grid'].includes(ele1.type)) {
          if (ele1.layout && ele1.layout.length > 0) {
            ele1.layout.forEach((ele2) => {
              if (ele2.list && ele2.list.length > 0) {
                arr.push(...getSchemasConfig(ele2.list, formType));
              }
            });
          }
        } else if (['one-for-one'].includes(ele1.type) || ['form'].includes(ele1.type)) {
          // if (ele1.children && ele1.children.length > 0) {
          //   arr.push(...getSchemasConfig(ele1.children, formType));
          // }
        } else if (['table-layout'].includes(ele1.type)) {
          if (ele1.layout && ele1.layout.length > 0) {
            ele1.layout.forEach((ele2) => {
              if (ele2.list && ele2.list.length > 0) {
                ele2.list.forEach((ele3) => {
                  if (ele3.children && ele3.children.length > 0) {
                    arr.push(...getSchemasConfig(ele3.children, formType));
                  }
                });
              }
            });
          }
        }
        if (['Card', 'Tab'].includes(ele1.component)) {
          if (ele1.children && ele1.children.length > 0) {
            ele1.children.forEach((ele2) => {
              if (ele2.list && ele2.list.length > 0) {
                arr.push(...getSchemasConfig(ele2.list, formType));
              }
            });
          }
        } else if (ele1.component === 'TableLayout') {
          if (ele1.children && ele1.children.length > 0) {
            ele1.children.forEach((ele2) => {
              if (ele2.list && ele2.list.length > 0) {
                ele2.list.forEach((ele3) => {
                  if (ele3.children && ele3.children.length > 0) {
                    arr.push(...getSchemasConfig(ele3.children, formType));
                  }
                });
              }
            });
          }
        } else if (
          ele1.component == 'SubForm' ||
          ele1.type == 'SubForm' ||
          ele1.type == 'subForm' ||
          ele1.type == 'sub-form'
        ) {
        } else {
          if (ele1.type && ele1.label && ele1.bindField && !disableTypes.includes(ele1.type)) {
            let bindField = formType == 0 ? camelCaseString(ele1.bindField) : ele1.bindField;
            arr.push({
              title: ele1.label ? ele1.label : bindField,
              key: bindField,
              children: [],
            });
          }
        }
      });
    }
    return arr;
  }
  // 去除不能选择的表单字段
  const visitorsBookType = 'opinion'; //意见簿类型
  const titleType = 'title'; //标题类型
  const dividerType = 'divider'; //分割线类型
  const infoType = 'info'; //信息体
  //const autoCodeType = 'auto-code'; //编码
  const buttonType = 'button'; //按钮
  // 标题，分割线、信息体，按钮，编码，意见簿，只允许查看权限
  const disableTypes = [
    visitorsBookType,
    titleType,
    dividerType,
    infoType,
    //autoCodeType,
    buttonType,
    'qrcode', //二维码组件
  ];

  const apiConfigColumns = [
    {
      title: t('API入参名称'),
      dataIndex: 'name',
      key: 'name',
      align: 'center',
    },
    {
      title: t('API入参类型'),
      dataIndex: 'dataType',
      key: 'dataType',
      align: 'center',
    },
    {
      title: t('赋值类型'),
      dataIndex: 'assignmentType',
      key: 'assignmentType',
      align: 'center',
    },
    {
      title: t('赋值配置'),
      dataIndex: 'value',
      key: 'value',
      align: 'center',
    },
  ];
</script>
<style lang="less" scoped>
  .form-box {
    display: flex;
    justify-content: space-around;
    margin: 10px 0;
  }

  .item {
    display: flex;
    justify-content: center;
    align-items: center;
    flex: 1;
  }

  .label {
    width: 100px;
    margin-left: 20px;
  }

  .flex {
    flex: 1;
  }

  .padding {
    padding: 10px 20px;
  }
</style>
