<template>
  <div @click.stop="open">
    <InputModel
      :value="data.config.name"
      :placeholder="t('配置API')"
      style="width: 100%; min-width: 100px"
    />
    <ModalPanel
      :visible="visible"
      :width="1100"
      :title="t('API配置')"
      @submit="submit"
      @close="close"
    >
      <NodeHead :nodeName="t('API信息')" class="ml-4 my-4" />
      <SelectInterfaceAddress :config="data.config" @set-api-config="setApiConfig" />
      <ScriptInputParams
        class="padding"
        v-if="visible"
        :apiParams="data.apiParams"
        :paramTree="data.paramTree"
        :need-hide-components="needHideComponents"
        :isGlobalParams="isGlobalParams"
      />
      <a-button
        type="primary"
        class="btn-item"
        @click.stop="data.isShowExample = false"
        @mouseenter="data.isShowExample = true"
        >{{ t('返回出参示例') }}</a-button
      >
      <div class="editor-box" v-if="data.isShowExample">
        <CodeEditor
          v-if="data.isShowExample"
          :value="exampleStr"
          language="json"
          readonly
          style="font-size: 12px"
        />
        <span class="editor-close" @click.stop="data.isShowExample = false"> x </span>
        <span class="editor-copy" @click.stop="copy">{{ t('复制代码') }}</span>
      </div>
    </ModalPanel>
  </div>
</template>

<script setup lang="ts">
  import { reactive, ref } from 'vue';
  import { NodeHead, ModalPanel } from '/@/components/ModalPanel/index';
  import { SelectInterfaceAddress, InputModel } from '/@/components/ApiConfig';
  import { CodeEditor } from '/@/components/CodeEditor';
  import ScriptInputParams from './ScriptInputParams.vue';
  import { TreeProps } from 'ant-design-vue';
  import { cloneDeep } from 'lodash-es';
  import { InterfaceListInfo } from '/@/api/system/interface/model';
  import useClipboard from 'vue-clipboard3';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { ApiConfig, ApiParams } from '/@/components/ApiConfig/src/interface';
  const { t } = useI18n();
  const emit = defineEmits(['update:modelValue']);
  let props = withDefaults(
    defineProps<{
      paramTree?: TreeProps['treeData'];
      modelValue: ApiConfig;
      exampleStr?: string;
      needHideComponents?: Boolean;
      isGlobalParams?: Boolean;
    }>(),
    {
      modelValue: () => {
        return {
          id: '',
          name: '',
          method: '',
          requestParamsConfigs: [], //Query Params
          requestHeaderConfigs: [], //Header
          requestBodyConfigs: [], //Body
        };
      },
      exampleStr: `{
        code: 0,
        msg: 'success',
        data: 'value',
      }`,
      needHideComponents: () => {
        return false;
      },
      isGlobalParams: () => {
        return false;
      },
    },
  );
  const { toClipboard } = useClipboard();
  let data: {
    isShowExample: boolean;
    config: ApiConfig;
    paramTree: TreeProps['treeData'];
    apiParams: Array<ApiParams>;
  } = reactive({
    isShowExample: false,
    config: props.modelValue,
    paramTree: [],
    apiParams: [
      {
        key: '1',
        title: 'Query Params',
        tableInfo: [],
      },
      {
        key: '2',
        title: 'Header',
        tableInfo: [],
      },
      {
        key: '3',
        title: 'Body',
        tableInfo: [],
      },
    ],
  });

  const visible = ref<boolean>(false);
  function open() {
    data.config = cloneDeep(props.modelValue);
    if (props.paramTree) {
      data.paramTree = props.paramTree;
    }
    if (data.config.requestParamsConfigs)
      data.apiParams[0].tableInfo = data.config.requestParamsConfigs;
    if (data.config.requestHeaderConfigs)
      data.apiParams[1].tableInfo = data.config.requestHeaderConfigs;
    if (data.config.requestBodyConfigs)
      data.apiParams[2].tableInfo = data.config.requestBodyConfigs;
    visible.value = true;
  }
  function close() {
    visible.value = false;
  }
  async function copy() {
    try {
      await toClipboard(props.exampleStr);
    } catch (e) {
      console.error(e);
    }
  }

  function submit() {
    emit('update:modelValue', cloneDeep(data.config));
    close();
  }
  function setApiConfig(config: InterfaceListInfo) {
    if (data.config.id !== config.id) {
      data.config.id = config.id;
      data.config.name = config.name;
      data.config.method = config.method;
      data.config.path = config.path;
      data.config.requestParamsConfigs = [];
      data.config.requestHeaderConfigs = [];
      data.config.requestBodyConfigs = [];
    }
    if (data.config.requestParamsConfigs.length <= 0) {
      if (config.parameters) {
        config.parameters.forEach((element) => {
          data.config.requestParamsConfigs.push({
            name: element.name, //API入参名称
            dataType: element.dataType, //API入参类型
            assignmentType: 'value', //赋值类型
            value: element.value, //值
            config: '', //赋值配置
          });
        });
      }
      data.apiParams[0].tableInfo = data.config.requestParamsConfigs;
    }

    if (data.config.requestHeaderConfigs.length <= 0) {
      if (config.headers) {
        config.headers.forEach((element) => {
          data.config.requestHeaderConfigs.push({
            name: element.name, //API入参名称
            dataType: element.dataType, //API入参类型
            assignmentType: 'value', //赋值类型
            value: element.value, //值
            config: '', //赋值配置
          });
        });
      }
      data.apiParams[1].tableInfo = data.config.requestHeaderConfigs;
    }

    if (data.config.requestBodyConfigs.length <= 0) {
      if (config.requestBodyDefinition && config.requestBodyDefinition.children) {
        config.requestBodyDefinition.children.forEach((element) => {
          data.config.requestBodyConfigs.push({
            name: element.name, //API入参名称
            dataType: element.dataType, //API入参类型
            assignmentType: 'value', //赋值类型
            value: element.value, //值
            config: '', //赋值配置
          });
        });
      }

      data.apiParams[2].tableInfo = data.config.requestBodyConfigs;
    }
  }
</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>
