<template>
  <ModalPanel
    :visible="state.apiSelectDia"
    :width="1200"
    :title="t('选择接口')"
    @submit="handleSubmit"
    @close="handleClose"
  >
    <template #left>
      <NodeHead :nodeName="t('接口分类')" class="margin-bottom" />
      <CategoryTree @select="handleSelect" />
    </template>
    <div class="title-box-box margin-bottom">
      <NodeHead :nodeName="t('接口列表')" />
      <div class="search-box">
        <a-input v-model:value="state.searchText" :placeholder="t('输入搜索关键字')" allowClear />
        <div class="btn-box">
          <a-button @click="handleReset" class="ml-2"> {{ t('重置') }} </a-button>
          <a-button type="primary" @click="handleSearch" class="ml-2">
            {{ t('搜索') }}
          </a-button>
        </div>
      </div>
    </div>

    <div :class="[prefixCls, prefixCls + '-form-has-pagenation']" style="height: calc(100% - 60px)">
      <a-table
        size="middle"
        :dataSource="state.interfaceDataSource"
        :columns="state.apiConfigColumns"
        rowKey="id"
        :pagination="state.paginationProps"
        :row-selection="{
          selectedRowKeys: state.selectedRowKeys,
          onSelect: onSelectChange,
          type: props.isMultiple ? 'checkbox' : 'radio',
        }"
        :scroll="{ y: '455px !important' }"
        :customRow="customRow"
        ><template #headerCell="{ column }">
          <div class="header-cell__custom-title">{{ column.title }}</div>
        </template></a-table
      >
    </div>
  </ModalPanel>
</template>
<script lang="ts" setup>
  import { onMounted, reactive, watch, createVNode } from 'vue';
  import { ColumnProps } from 'ant-design-vue/lib/table/Column';
  import { getInterfaceTree, getInterfaceList } from '/@/api/system/interface/index';
  import { InterfaceList } from '../interface';
  import { getInterfaceInfo } from '/@/api/system/interface/index';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { apiConfigFunc } from '/@/utils/event/design';
  import { Modal } from 'ant-design-vue';
  import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
  import { NodeHead, ModalPanel } from '/@/components/ModalPanel/index';
  import CategoryTree from './CategoryTree.vue';
  import { useDesign } from '/@/hooks/web/useDesign';
  const { prefixCls } = useDesign('basic-table');
  const { t } = useI18n();
  const props = defineProps({
    apiSelectDialog: { type: Boolean },
    selectedApiId: { type: [String, Array] },
    isMultiple: {
      type: Boolean,
      default: false,
    },
    example: { type: String },
  });
  const emit = defineEmits(['update:apiSelectDialog', 'update:selectedApiId', 'success']);
  const state = reactive({
    apiSelectDia: props.apiSelectDialog,
    interfaceTreeData: [] as any[],
    expandedKeys: [] as string[],
    selectedKeys: [] as string[],
    interfaceList: [] as InterfaceList[], //接口列表全部
    interfaceListSearch: [] as InterfaceList[], //接口列表搜索全部
    interfaceDataSource: [] as InterfaceList[], //接口列表分页
    selectedRowKeys: [] as string[],
    searchText: '' as string,
    isSearch: false,
    fieldNames: { children: 'children', title: 'name', key: 'id' },
    modalBodyStyle: {
      display: 'flex',
      padding: '15px 0 10px 0',
      minHeight: '400px',
    },
    apiConfigColumns: [
      {
        key: 'name',
        title: t('接口名称'),
        dataIndex: 'name',
        width: 300,
      },
      {
        key: 'path',
        title: t('接口地址'),
        dataIndex: 'path',
      },
    ] as ColumnProps[],
    paginationProps: {
      current: 1,
      total: 0,
      pageSize: 10,
      size: 'none',
      showQuickJumper: true,
      showSizeChanger: true,
      showLessItems: true,
      onChange: (page: number) => getInterfacePage(page),
      onShowSizeChange: (current: number, pageSize: number) => {
        state.paginationProps.pageSize = pageSize;
        getInterfacePage(current);
      },
    },
    interfaceInfo: [
      {
        key: '1',
        title: 'Query Params',
        tableInfo: [],
      },
      {
        key: '2',
        title: 'Header',
        tableInfo: [],
      },
      {
        key: '3',
        title: 'Body',
        tableInfo: [],
      },
    ],
    configInfo: {
      path: '',
      method: '',
      apiId: '',
      apiParams: [] as any[],
      script: '',
    },
  });

  onMounted(() => {
    getInterfaceTreeData();
  });
  watch(
    () => props.selectedApiId,
    (val: any) => {
      if (!!val) {
        state.selectedRowKeys = props.isMultiple ? [...val] : [val];
      }
    },
    {
      immediate: true,
      deep: true,
    },
  );
  //获取左边树结构
  const getInterfaceTreeData = async () => {
    state.interfaceTreeData = await getInterfaceTree();
    //默认展示第一个接口分类的列表
    if (state.interfaceTreeData.length && state.interfaceTreeData[0].id) {
      const id = state.interfaceTreeData[0].id;
      state.selectedKeys.push(id);
      state.expandedKeys.push(id);
      selectTree(state.selectedKeys);
    }
  };
  async function handleSelect(deptId = '') {
    state.paginationProps.current = 1;
    state.isSearch = false;
    const data = await getInterfaceList({ groupId: deptId });
    //清空接口列表
    state.interfaceList = [];
    data.map((item: any) => {
      state.interfaceList.push({
        id: item.id,
        name: item.name,
        path: item.path,
      });
    });
    getInterfacePage(1);
  }
  //获取右边接口列表
  const selectTree = async (selectedKeys: string[], e?) => {
    state.isSearch = false;
    if (!selectedKeys.length) state.selectedKeys.push(e.node.dataRef.id);
    const groupId = selectedKeys[selectedKeys.length - 1];
    const data = await getInterfaceList({ groupId });
    //清空接口列表
    state.interfaceList = [];
    data.map((item: any) => {
      state.interfaceList.push({
        id: item.id,
        name: item.name,
        path: item.path,
      });
    });
    getInterfacePage(1);
  };
  //展示右边接口列表（分页）
  const getInterfacePage = (page) => {
    const size = state.paginationProps.pageSize;
    const startIndex = (page - 1) * size;
    const endIndex = page * size;

    const list = state.isSearch ? state.interfaceListSearch : state.interfaceList;

    state.paginationProps.current = page;
    state.paginationProps.total = list.length;
    state.interfaceDataSource = list.slice(startIndex, endIndex);
  };
  const handleReset = () => {
    state.searchText = '';
    state.interfaceListSearch = state.interfaceList;
    getInterfacePage(1);
  };
  const handleSearch = () => {
    state.isSearch = true;
    state.interfaceListSearch = state.interfaceList.filter((item: InterfaceList) => {
      const hasKeywords = Object.values(item).find((val: string, index: number) => {
        //index!==0 id不参与搜索
        return index !== 0 && val.indexOf(state.searchText) !== -1;
      });
      return hasKeywords;
    });

    getInterfacePage(1);
  };

  const customRow = (record: InterfaceList) => {
    return {
      onClick: () => {
        let selectedRowKeys = [...state.selectedRowKeys];
        if (selectedRowKeys.indexOf(record.id) >= 0) {
          let index = selectedRowKeys.indexOf(record.id);
          selectedRowKeys.splice(index, 1);
        } else {
          selectedRowKeys = props.isMultiple ? [...selectedRowKeys, record.id] : [record.id];
        }
        state.configInfo.apiId = selectedRowKeys[0];
        state.selectedRowKeys = selectedRowKeys;
      },
    };
  };
  const onSelectChange = (record, selected, selectedRows) => {
    const rowKey = selectedRows.filter((x) => x && x.id).map((x) => x.id);
    if (!selected) {
      state.selectedRowKeys = state.selectedRowKeys.filter((x) => x !== record.id);
    } else {
      state.selectedRowKeys = props.isMultiple
        ? [...new Set([...rowKey, ...state.selectedRowKeys])]
        : rowKey;
    }
    state.configInfo.apiId = rowKey.length ? rowKey[0] : '';
  };
  const getInterfaceInfoById = async (id) => {
    const data = await getInterfaceInfo({ id });
    state.interfaceInfo[0].tableInfo = data.parameters;
    state.interfaceInfo[1].tableInfo = data.headers;
    if (data.requestBody) {
      const requestBody = JSON.parse(data.requestBody);
      state.interfaceInfo[2].tableInfo = [];
      Object.keys(requestBody).forEach((body) => {
        let info: any = {
          name: body,
          value: requestBody[body],
        };
        if (requestBody[body] && Array.isArray(requestBody[body]) && requestBody[body][0]) {
          info.value = '';
          info.type = 'form';
          info.children = [];
          Object.keys(requestBody[body][0])?.forEach((sub) => {
            info.children.push({
              name: sub,
              bindType: 'value',
              form: body,
              value: requestBody[body][0][sub],
            });
          });
        }
        console.log('info', info);
        (state.interfaceInfo[2].tableInfo as any).push(info);
      });
    } else {
      state.interfaceInfo[2].tableInfo = data.requestBodyDefinition?.children;
    }
    state.configInfo.path = data.path;
    state.configInfo.method = data.method;
    state.configInfo.script = data.script;
    state.configInfo.apiParams = state.interfaceInfo;
  };
  const handleSubmit = async () => {
    if (!!state.selectedRowKeys[0]) {
      emit(
        'update:selectedApiId',
        props.isMultiple ? state.selectedRowKeys : state.selectedRowKeys[0],
      );
      if (!props.isMultiple) {
        await getInterfaceInfoById(state.selectedRowKeys[0]);
      }
      // 查询接口返回是否跟案例一样
      await judgeFormat();
    } else {
      emit('update:apiSelectDialog', false);
    }
  };
  async function judgeFormat() {
    let resData = await apiConfigFunc(state.configInfo);
    if (resData) {
      if (props.example) {
        let tempData = JSON.parse(props.example);
        let json = {};
        if (Array.isArray(tempData.data)) {
          json = tempData.data[0];
          if (Array.isArray(resData)) {
            let topArr: String[] = [];
            for (const key in json) {
              topArr.push(key);
            }
            let returnData = resData.filter((ele) => {
              let arr: String[] = [];
              for (const key in json) {
                if (ele[key] !== undefined) {
                  arr.push(key);
                }
              }
              return arr.length == topArr.length;
            });
            if (resData.length == returnData.length) {
              // 一致
              emit('success', state.configInfo);
              emit('update:apiSelectDialog', false);
            } else {
              Modal.confirm({
                title: t('提示'),
                icon: createVNode(ExclamationCircleOutlined),
                content: t('该接口返回的数据结构与示例不一致，组件可能无法适配该接口，是否继续？'),
                onOk() {
                  emit('success', state.configInfo);
                  emit('update:apiSelectDialog', false);
                },
                onCancel() {},
                okText: t('确认'),
                cancelText: t('取消'),
              });
            }
          } else {
            Modal.confirm({
              title: t('提示'),
              icon: createVNode(ExclamationCircleOutlined),
              content: t('该接口返回的数据结构与示例不一致，组件可能无法适配该接口，是否继续？'),
              onOk() {
                emit('success', state.configInfo);
                emit('update:apiSelectDialog', false);
              },
              onCancel() {},
              okText: t('确认'),
              cancelText: t('取消'),
            });
          }
        } else if (typeof tempData.data === 'string' && typeof resData === 'string') {
          emit('success', state.configInfo);
          emit('update:apiSelectDialog', false);
        } else {
          Modal.confirm({
            title: t('提示'),
            icon: createVNode(ExclamationCircleOutlined),
            content: t('该接口返回的数据结构与示例不一致，组件可能无法适配该接口，是否继续？'),
            onOk() {
              emit('success', state.configInfo);
              emit('update:apiSelectDialog', false);
            },
            onCancel() {},
            okText: t('确认'),
            cancelText: t('取消'),
          });
        }
      } else {
        emit('success', state.configInfo);
        emit('update:apiSelectDialog', false);
      }
    } else {
      Modal.confirm({
        title: t('提示'),
        icon: createVNode(ExclamationCircleOutlined),
        content: t('系统未获取到该接口返回值，无法判断数据结构是否正确，是否继续？'),
        onOk() {
          emit('success', state.configInfo);
          emit('update:apiSelectDialog', false);
        },
        onCancel() {},
        okText: t('确认'),
        cancelText: t('取消'),
      });
    }
  }
  const handleClose = () => {
    emit('update:apiSelectDialog', false);
  };
</script>
<style lang="less" scoped>
  .margin-bottom {
    height: 52px;
    padding: 16px;
    border-bottom: 1px solid #eee;
    margin-bottom: 8px;
  }

  .title-box-box {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  .search-box {
    display: flex;
  }

  .btn-box {
    display: flex;
  }
</style>
