<template>
  <a-row type="flex" align="middle" :gutter="15" class="!mx-0">
    <a-col flex="80px"><em class="required-icon">*</em>{{ t('接口地址') }}</a-col>
    <a-col flex="auto">
      <a-input
        v-model:value="apiData.path"
        :placeholder="t('点击选择接口')"
        @click="apiSelectDialog = true"
      >
        <template #addonAfter>
          <Icon icon="ant-design:ellipsis-outlined" />
        </template>
      </a-input>
    </a-col>
    <a-col flex="80px">{{ t('请求方式') }}</a-col>
    <a-col flex="auto">
      <a-input
        v-model:value="apiData.method"
        :placeholder="t('选择接口后自动显示接口请求方式')"
        disabled
      />
    </a-col>
  </a-row>
  <a-tabs v-model:activeKey="activeParamsKey" v-if="apiData.value === 'view'">
    <a-tab-pane key="import" tab="入参">
      <a-tabs v-model:activeKey="activeKey">
        <a-tab-pane :key="ele.key" :tab="ele.title" v-for="ele in apiData.apiParams">
          <a-table
            :dataSource="ele.tableInfo"
            :columns="state.apiConfigColumns"
            :pagination="false"
            :scroll="{ y: '400px' }"
          >
            <template #emptyText>
              <div class="table-empty">
                <img :src="emptyPng" />
                <div>暂无数据</div>
              </div>
            </template>
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'bindType'">
                <a-select
                  v-model:value="record.bindType"
                  style="width: 100%"
                  :placeholder="t('请选择赋值类型')"
                  :options="state.bindType"
                  allowClear
                  @change="record.value = ''"
                />
              </template>
              <template v-else-if="column.key === 'value'">
                <a-tree-select
                  v-model:value="record.value"
                  show-search
                  style="width: 100%"
                  :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                  :placeholder="t('点击选择表单数据')"
                  allow-clear
                  tree-default-expand-all
                  :tree-data="state.dataInfo"
                  @select="(_, node) => handleSelect(node, record)"
                  v-if="record.bindType === 'data'"
                />
                <a-input
                  v-model:value="record.value"
                  :placeholder="record.bindType ? t('请填写值') : t('请先选择赋值类型后再配置值')"
                  v-else
                />
              </template>
            </template>
          </a-table>
        </a-tab-pane>
      </a-tabs>
    </a-tab-pane>
    <a-tab-pane key="export" tab="出参">
      <a-table
        :dataSource="apiData.outputConfig"
        :columns="state.outPutColumns"
        :pagination="false"
        :scroll="{ y: '400px' }"
      >
        <template #emptyText>
          <div class="table-empty">
            <img :src="emptyPng" />
            <div>暂无数据</div>
          </div>
        </template>
        <template #bodyCell="{ column, record, index }">
          <template v-if="column.key === 'apiField'">
            <a-input v-model:value="record.apiField" :placeholder="t('请填写字段名')" />
          </template>
          <template v-else-if="column.key === 'bindField'">
            <a-tree-select
              v-model:value="record.bindField"
              show-search
              style="width: 100%"
              :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
              :placeholder="t('点击选择表单数据')"
              allow-clear
              tree-default-expand-all
              :tree-data="state.outPutData"
              @select="(_, node) => handleSelect(node, record)"
            />
          </template>
          <template v-else-if="column.key === 'action'">
            <span class="text-[#ff8080]" @click="deleteParamas(index)">删除</span>
          </template>
        </template>
      </a-table>
      <a-button type="dashed" block @click="addOutPutParamas" class="mb-4">
        <PlusOutlined />
        {{ t('新增') }}
      </a-button>
    </a-tab-pane>
  </a-tabs>
  <a-tabs v-model:activeKey="activeKey" v-else>
    <a-tab-pane :key="ele.key" :tab="ele.title" v-for="ele in apiData.apiParams">
      <a-table
        :dataSource="ele.tableInfo"
        :columns="state.apiConfigColumns"
        :pagination="false"
        :scroll="{ y: '400px' }"
      >
        <template #emptyText>
          <div class="table-empty">
            <img :src="emptyPng" />
            <div>暂无数据</div>
          </div>
        </template>
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'bindType'">
            <a-select
              v-model:value="record.bindType"
              style="width: 100%"
              :placeholder="t('请选择赋值类型')"
              :options="state.bindType"
              allowClear
              @change="record.value = ''"
            />
          </template>
          <template v-else-if="column.key === 'value'">
            <a-tree-select
              v-model:value="record.value"
              show-search
              style="width: 100%"
              :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
              :placeholder="t('点击选择表单数据')"
              allow-clear
              tree-default-expand-all
              :tree-data="state.dataInfo"
              @select="(_, node) => handleSelect(node, record)"
              v-if="record.bindType === 'data'"
            />
            <a-input
              v-model:value="record.value"
              :placeholder="record.bindType ? t('请填写值') : t('请先选择赋值类型后再配置值')"
              v-else
            />
          </template>
        </template>
      </a-table>
    </a-tab-pane>
  </a-tabs>
  <NotableApiSelect
    v-if="apiSelectDialog"
    v-model:apiSelectDialog="apiSelectDialog"
    v-model:selectedApiId="apiData.apiId"
    :example="example"
    :apiType="apiData.value"
    @success="handleApiSuccess"
  />
</template>
<script setup lang="ts">
  import { ref, reactive, watch, inject, Ref, onMounted } from 'vue';
  import { message } from 'ant-design-vue';
  import emptyPng from '/@/assets/images/empty.png';
  import NotableApiSelect from './components/NotableApiSelect.vue';
  import { ColumnProps } from 'ant-design-vue/lib/table/Column';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { Icon } from '/@/components/Icon';
  import { infoMap, noHaveTableAndField } from '/@/components/Designer/src/types';
  import { PlusOutlined } from '@ant-design/icons-vue';
  import { cloneDeep } from 'lodash-es';

  const { t } = useI18n();

  const props = defineProps(['info', 'type']);
  const emits = defineEmits(['changeConfig', 'update:info']);

  const generatorConfig = inject('generatorConfig') as any;
  const current = inject<Ref<number>>('current') as Ref<number>;
  const isCustomForm = inject<boolean>('isCustomForm', false);

  const apiSelectDialog = ref(false);
  const apiData = ref(props.info);
  const example = ref('');
  const activeKey = ref('1');
  const activeParamsKey = ref('import');

  watch(
    () => apiData.value,
    (val) => {
      emits('changeConfig', val);
      emits('update:info', val);
    },
    {
      deep: true,
    },
  );

  watch(
    () => current.value,
    (val) => {
      if (val === 2) {
        changeComponent();
      }
    },
    {
      deep: true,
    },
  );

  onMounted(() => {
    if (generatorConfig?.formJson.list?.length) {
      changeComponent();
    }
  });

  const changeComponent = () => {
    state.dataInfo[0].children = [];
    getTableComponents(generatorConfig?.formJson.list, t('主表组件'));
    state.outPutData = cloneDeep(state.dataInfo[0].children);
    state.outPutData[0].children.map((item) => {
      item.value = item.value ? JSON.parse(item.value)?.bindField : '';
    });
  };

  const state = reactive({
    apiConfigColumns: [
      {
        title: t('API入参名称'),
        dataIndex: 'name',
        key: 'name',
        align: 'center',
      },
      {
        title: t('API入参类型'),
        dataIndex: 'dataType',
        key: 'dataType',
        align: 'center',
      },
      {
        title: t('赋值类型'),
        dataIndex: 'bindType',
        key: 'bindType',
        align: 'center',
      },
      {
        title: t('赋值配置'),
        dataIndex: 'value',
        key: 'value',
        align: 'center',
      },
    ] as ColumnProps[],
    bindType: [
      {
        label: t('值'),
        value: 'value',
      },
      {
        label: t('表单数据'),
        value: 'data',
      },
    ],
    dataInfo: [
      {
        title: t('表单数据'),
        value: 'formData',
        disabled: true,
        children: [],
      },
      {
        title: '当前信息',
        value: 'currentInfo',
        disabled: true,
        children: infoMap,
      },
    ] as any[],
    outPutColumns: [
      {
        title: t('接口返回参数字段名'),
        key: 'apiField',
        align: 'center',
      },
      {
        title: t('填充组件'),
        key: 'bindField',
        align: 'center',
      },
      {
        title: t('操作'),
        key: 'action',
        align: 'center',
        width: 80,
      },
    ],
    outPutData: [] as any[],
  });

  const handleSelect = ({ value }, record) => {
    if (!value) {
      message.error(t('请先选择该组件的绑定表及绑定字段'));
      record.value = null;
    }
  };

  const handleApiSuccess = (config) => {
    apiData.value = { ...apiData.value, ...config };
    delete apiData.value.script;

    apiData.value.apiParams.forEach((para) => {
      if (!!para.tableInfo && para.tableInfo.length) {
        para.tableInfo?.map((item) => {
          return (item.bindType = !!item.value && !item.bindType ? 'value' : '');
        });
      }
    });
  };

  const getTableComponents = (list, tableName, key?) => {
    list.forEach((item) => {
      if (['tab', 'grid', 'card'].includes(item.type)) {
        for (const child of item.layout!) {
          getTableComponents(child.list, tableName);
        }
      } else if (item.type === 'table-layout') {
        for (const child of item.layout!) {
          for (const list of child.list) {
            getTableComponents(list.children, tableName, key);
          }
        }
      } else if (item.type === 'one-for-one') {
        getTableComponents(item.children, item.label, item.key);
      } else if (item.type === 'form') {
        const itemChildren = item.children.filter((child) => {
          return !noHaveTableAndField.includes(child.type) && child.type !== 'sun-form';
        });
        state.dataInfo[0].children.push({
          label: item.label,
          value: item.bindTable,
          children: itemChildren.map((x) => {
            return {
              label: x.label,
              value: `${x.bindTable},${x.bindField}`,
            };
          }),
        });
      } else if (!noHaveTableAndField.includes(item.type)) {
        const index = state.dataInfo[0].children.findIndex((x) => x.label === tableName);
        const fieldObj = {
          bindField: item.bindField,
          fieldKey: item.key,
        };
        let info = [
          {
            label: item.label,
            value:
              tableName === t('主表组件')
                ? JSON.stringify(fieldObj)
                : `${item.bindTable},${item.bindField}`,
          },
        ];
        if (
          props.type === 'list' &&
          ['time', 'date'].includes(item.type) &&
          item.options.searchType === 'range'
        ) {
          const start = isCustomForm ? 'Start' : '_start';
          const end = isCustomForm ? 'End' : '_end';

          const fieldObjStart = {
            bindField: item.bindField + start,
            fieldKey: item.key,
          };
          const fieldObjEnd = {
            bindField: item.bindField + end,
            fieldKey: item.key,
          };
          info = [
            {
              label: item.label + '开始时间',
              value:
                tableName === t('主表组件')
                  ? JSON.stringify(fieldObjStart)
                  : `${item.bindTable},${item.bindField}${start}`,
            },
            {
              label: item.label + '结束时间',
              value:
                tableName === t('主表组件')
                  ? JSON.stringify(fieldObjEnd)
                  : `${item.bindTable},${item.bindField}${end}`,
            },
          ];
        }
        if (index !== -1) {
          state.dataInfo[0].children[index].children.push(...info);
        } else {
          if (tableName === t('主表组件')) {
            state.dataInfo[0].children.unshift({
              label: tableName,
              value: '1',
              disabled: true,
              children: [...info],
            });
          } else {
            state.dataInfo[0].children.push({
              label: tableName,
              value: key,
              children: [...info],
            });
          }
        }
      }
    });
  };

  const addOutPutParamas = () => {
    apiData.value.outputConfig.push({
      apiField: '',
      bindField: '',
    });
  };

  const deleteParamas = (index) => {
    apiData.value.outputConfig.splice(index, 1);
  };
</script>
<style lang="less" scoped>
  .required-icon {
    color: red;
  }

  :deep(.ant-tabs-content) {
    padding: 0 20px;
  }

  .table-empty {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
  }
</style>
