<template>
  <div class="apiDebugging">
    <div class="left" v-if="stepZeroForm.needLogin === '1'">
      <template v-if="stepZeroForm.needLogin === '1'">
        <div class="debugchunk">
          <div class="title" style="margin: 10px 0">
            <h1>认证接口</h1>
          </div>
          <div class="addressChunk">
            <div class="label">地址:</div>
            <div class="input">
              <el-input v-model="authInterfaceAddress"></el-input>
            </div>
          </div>
          <div class="code-json-editor">
            <vue-json-editor
              class="editor"
              v-model="authInfo"
              :showBtns="false"
              :mode="'code'"
              @json-change="onAuthJsonChange"
              @json-save="onAuthJsonSave"
              @has-error="onAuthError"
            />
          </div>
          <div class="btn">
            <el-button
              type="primary"
              :loading="authDebugGoLoading"
              @click="authDebugGoHandle"
              style="margin: 10px 0"
            >认证调试
            </el-button
            >
          </div>
          <div class="title">
            <h1>认证结果展示</h1>
          </div>
          <div
            class="result"
            style="margin-top: 30px"
            v-loading="authResultLoading"
            v-if="Object.keys(authJsonData).length"
          >
            <json-view :data="authJsonData"/>
          </div>
        </div>
      </template>
    </div>
    <div class="right">
      <template>
        <div class="debugchunk">
          <div class="title" style="margin: 10px 0">
            <h1>测试数据设置</h1>
          </div>
          <div class="addressChunk">
            <div class="label">地址:</div>
            <div class="input">
              <el-input v-model="interfaceAddress" style="width: 100%"></el-input>
            </div>
          </div>
          <div class="code-json-editor">
            <vue-json-editor
              v-model="resultInfo"
              :showBtns="false"
              :mode="'code'"
              @json-change="onJsonChange"
              @json-save="onJsonSave"
              @has-error="onError"
              class="json-editor"
            />
          </div>
          <div class="btn">
            <el-button
              type="primary"
              :loading="debugGoLoading"
              @click="debugGoHandle"
              style="margin: 10px 0"
            >开始调试
            </el-button
            >
          </div>
          <h1>测试结果展示</h1>
          <div
            class="result"
            style="margin-top: 30px"
            v-loading="resultLoading"
            v-if="Object.keys(jsonData).length"
          >
            <json-view :data="jsonData"/>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>
<script>
import jsonView from "vue-json-views";
import vueJsonEditor from "vue-json-editor";
import {deepClone} from "@/utils/index.js";
import {getApiModuleApi, getApiResultApi} from "@/api/apiChunks/index.js";

export default {
  name: "apiDebugging",
  props: {
    queryTableInfo: {
      type: Array,
      default: () => {
        return []
      }
    },
    bodyEntTableInfo: {
      type: Array,
      default: () => {
        return []
      }
    },
    bodyExitTableInfo: {
      type: Array,
      default: () => {
        return []
      }
    },
    headersTableInfo: {
      type: Array,
      default: () => {
        return []
      }
    },
    stepZeroForm: {
      type: Object,
      default: () => {
        return {}
      }
    },
    stepOneForm: {
      type: Object, default: () => {
        return {}
      }
    }
  },
  data() {
    return {
      //测试数据区域
      interfaceAddress: "",//测试数据地址
      debugInfo: {},//debug信息
      resultInfo: {},//测试数据json
      hasJsonFlag: true,//测试数据json是否通过
      debugGoLoading: false,//测试数据按钮loading
      resultLoading: false,//测试数据展示区loading
      jsonData: {},//测试数据展示区json
      //认证接口区域
      authInterfaceAddress: "",//认证接口地址
      authInfo: {},//认证接口数据json
      authJsonFlag: true,//认证数据json是否通过
      authDebugGoLoading: false,//认证调试loading
      authResultLoading: false,//认证接口展示loading
      authJsonData: {},//认证接口展示json
      authMethod: ""
    }
  },
  methods: {
    //测试数据JSON相关（可以不用管）
    onJsonChange(value) {
      this.onJsonSave(value);
    },
    onJsonSave(value) {
      this.resultInfo = value;
      this.hasJsonFlag = true;
    },
    onError(value) {
      this.hasJsonFlag = false;
    },
    checkJson() {
      if (this.hasJsonFlag === false) {
        alert("json验证失败");
        return false;
      } else {
        return true;
      }
    },
    //认证数据JSON相关（可以不用管）
    onAuthJsonChange(value) {
      this.onAuthJsonSave(value);
    },
    onAuthJsonSave(value) {
      this.authInfo = value;
      this.authJsonFlag = true;
    },
    onAuthError(value) {
      this.authJsonFlag = false;
    },
    checkAuthJson() {
      if (this.authJsonFlag === false) {
        alert("json验证失败");
        return false;
      } else {
        return true;
      }
    },
    //点击认证接口
    async authDebugGoHandle() {
      this.authDebugGoLoading = true;
      if (this.checkAuthJson()) {
        this.authResultLoading = true;
        let tempUrl =
          this.authInterfaceAddress;
        try {
          if (this.authInfo.query && Object.keys(this.authInfo.query).length) {
            tempUrl = tempUrl + "?";
            Object.keys(this.authInfo.query).forEach((item) => {
              tempUrl += `${item}=${this.authInfo.query[item]}&`;
            });
            tempUrl = tempUrl.slice(0, -1);
          }
          const res = await getApiResultApi({
            method: this.authMethod,
            url: tempUrl,
            ...this.authInfo,
          });
          if (res.status == 200) {
            this.authJsonData = deepClone(JSON.parse(res.msg));
            this.authDataSearch();
          }
        } catch (error) {
          console.log(error)
          // this.$message({
          //   type: "warning",
          //   message: error,
          // });
        }
        this.authResultLoading = false;
      }
      this.authDebugGoLoading = false;
    },
    authDataSearch() {

      if (this.headersTableInfo) {
        this.authDataHandle(
          this.resultInfo.headers,
          this.headersTableInfo
        );
      }
      if (this.bodyEntTableInfo) {
        this.authDataHandle(
          this.resultInfo.body,
          this.bodyEntTableInfo[0].children
        );
      }
    },
    authDataHandle(obj, arr) {
      arr.forEach((item) => {
        if (item.parameterType === "authport") {
          obj[item.parameterName] = this.authDataReturn(item.example);
        }
        if (item.children && item.children.length) {
          this.authDataHandle(obj[item.parameterName], item.children);
        }
      });
    },
    //点击测试接口
    async debugGoHandle() {
      if (this.checkJson()) {
        this.debugGoLoading = true;
        this.resultLoading = true;
        let tempUrl = this.interfaceAddress;
        let methods = this.stepOneForm.requestMethod == 1 ? 'post' : 'get';
        try {
          if (
            this.resultInfo.query &&
            Object.keys(this.resultInfo.query).length
          ) {
            tempUrl = tempUrl + "?";
            Object.keys(this.resultInfo.query).forEach((item) => {
              tempUrl += `${item}=${this.resultInfo.query[item]}&`;
            });
            tempUrl = tempUrl.slice(0, -1);
          }
          const res = await getApiResultApi({
            method: methods,
            url: tempUrl,
            ...this.resultInfo,
          });
          if (res.status == 200) {
            this.jsonData = deepClone(JSON.parse(res.msg));
          }
        } catch (error) {
          // this.$message({
          //   type: "warning",
          //   message: error,
          // });
        }
        this.resultLoading = false;
        this.debugGoLoading = false;
      }
    },
    //初始化
    async init() {
      //拼接url
      this.getApiModuleApiHanlde(0, false, this.stepOneForm.destinationAddress)
      if (this.stepZeroForm.needLogin === '1') {
        this.getApiModuleApiHanlde(this.stepZeroForm.authenticationPort, true)
      }
    },
    async getApiModuleApiHanlde(id, flag, address = {}) {
      const res = await getApiModuleApi(
        {
          tl: "sysApplicationService",
          as: "application",
          dj: "debugAppApi",
        },
        {id: id, appId: this.$route.query.id}
      );
      let tempUrl = res.attribute.app.interfaceAddress ? res.attribute.app.interfaceAddress : ""
      if (flag) {
        this.authMethod = res.attribute.api.requestMethod == 1 ? 'post' : 'get';
        this.authInterfaceAddress = tempUrl + res.attribute.api.destinationAddress;
        let bodyIn = JSON.parse(res.attribute.api.bodyIn)
        let bodyFlag = bodyIn[0].parameterType !== "complex"
        let headerObj = {}
        let bodyObj
        let queryObj = {}
        if (!bodyFlag) {
          bodyObj = {};
        } else {
          bodyObj = [{}];
        }
        res.attribute.para.forEach(item => {
          if (item.interfaceType === '1') {
            headerObj[item.interfaceKey] = item.interfaceValue === null ? "" : item.interfaceValue;
          } else if (!bodyFlag) {
            bodyObj[item.interfaceKey] = item.interfaceValue === null ? "" : item.interfaceValue;
          }
        })
        this.headerDisposeHandle(headerObj, JSON.parse(res.attribute.api.headerIn))
        this.queryDisposeHandle(queryObj, JSON.parse(res.attribute.api.queryIn))
        if (!bodyFlag) {
          this.bodyDisposeHandle(bodyObj, bodyIn[0].children)
        } else {
          this.bodyDisposeHandle(bodyObj[0], bodyIn[0].children)
        }
        this.$set(this.authInfo, 'headers', deepClone(headerObj))
        this.$set(this.authInfo, 'query', deepClone(queryObj))
        this.$set(this.authInfo, 'body', deepClone(bodyObj))
      } else {
        let bodyFlag = this.bodyEntTableInfo[0].parameterType !== "complex"
        let headerObj = {}
        let bodyObj
        let queryObj = {}
        if (!bodyFlag) {
          bodyObj = {};
        } else {
          bodyObj = [{}];
        }
        res.attribute.para.forEach(item => {
          if (item.interfaceType === '1') {
            headerObj[item.interfaceKey] = item.interfaceValue === null ? "" : item.interfaceValue;
          } else if (!bodyFlag) {
            bodyObj[item.interfaceKey] = item.interfaceValue === null ? "" : item.interfaceValue;
          }
        })
        this.interfaceAddress = tempUrl + address;
        this.headerDisposeHandle(headerObj, this.headersTableInfo)
        this.queryDisposeHandle(queryObj, this.queryTableInfo)
        if (!bodyFlag) {
          this.bodyDisposeHandle(bodyObj, this.bodyEntTableInfo[0].children)
        } else {
          this.bodyDisposeHandle(bodyObj[0], this.bodyEntTableInfo[0].children)
        }
        this.$set(this.resultInfo, 'headers', deepClone(headerObj))
        this.$set(this.resultInfo, 'query', deepClone(queryObj))
        this.$set(this.resultInfo, 'body', deepClone(bodyObj))
      }

    },
    headerDisposeHandle(header, arr) {
      arr.forEach(item => {
        if (item.parameterType === "authport") {
          header[item.parameterName] = "";
        } else {
          header[item.parameterName] = item.example
        }
      })
    },
    queryDisposeHandle(query, arr) {
      arr.forEach(item => {
        query[item.parameterName] = item.example
      })
    },
    // 旧版防止新版出bug先留着
    // bodyDisposeHandle(obj, arr) {
    //   arr.forEach((item) => {
    //     if (item.parameterName && item.concreteType) {
    //       // 判断是否为obj
    //       if (
    //         item.concreteType != "Object" &&
    //         item.concreteType != "ObjectCom" &&
    //         item.concreteType != "Map"
    //       ) {
    //         // 如果不是obj 判断是否是认证属性 如果是认证属性直接滞空
    //         if (item.parameterType === "authport") {
    //           obj[item.parameterName] = "";
    //           //判断是否为复杂列表
    //         } else if (item.parameterType == "fundamentallist") {
    //           obj[item.parameterName] = [item.example];
    //         } else {
    //           // 判断value是否为空
    //           if (item.example !== "") {
    //             //判断value是否为 string类型的布尔值
    //             if (item.example === "false" || item.example === "true") {
    //               obj[item.parameterName] = JSON.parse(item.example)
    //             } else {
    //               obj[item.parameterName] = item.example
    //             }
    //           } else {
    //             if (!obj[item.parameterName] && obj[item.parameterName] != false) {
    //               obj[item.parameterName] = ""
    //             }
    //           }
    //         }
    //       } else if (
    //         item.concreteType == "Object" ||
    //         item.concreteType == "Map" ||
    //         item.concreteType == "ObjectCom"
    //       ) {
    //         if (item.concreteType == "Object" || item.concreteType == "Map") {
    //           obj[item.parameterName] = {};
    //           if (item.children && item.children.length) {
    //             this.bodyDisposeHandle(obj[item.parameterName], item.children);
    //           }
    //         } else if (item.concreteType == "ObjectCom") {
    //           obj[item.parameterName] = [];
    //           obj[item.parameterName].push({});
    //           this.bodyDisposeHandle(
    //             obj[item.parameterName][obj[item.parameterName].length - 1],
    //             item.children
    //           );
    //         }
    //       }
    //     }
    //   });
    // },
    jsonParseHandle(parameterType, example, concreteType = false) {
      let parameterTypeDist = {
        authport: "",
        fundamentallist: [example],
      }[parameterType]
      return parameterTypeDist || (()=>{
        if (concreteType === "Number" && this.isNumberOrFloat(example)) return example * 1;
        if (example === "false" || example === "true") return JSON.parse(example)
        return example
      })()
    },
    //判断是否为num或浮点数
    isNumberOrFloat(str) {
      let num = parseFloat(str);
      return !isNaN(num) && isFinite(num);
    },
    bodyDisposeHandle(obj, arr) {
      arr.forEach((item) => {
        const {parameterName, concreteType, parameterType, example, children} = item;
        if (parameterName && concreteType) {
          if (!["Object", "ObjectCom", "Map"].includes(concreteType)) {
            // 这两代码在做一件事情（1）
            obj[parameterName] = this.jsonParseHandle(parameterType, example, concreteType)
            // 这两代码在做一件事情（2）
            // if (parameterType === "authport") {
            //   obj[parameterName] = "";
            // } else if (parameterType === "fundamentallist") {
            //   obj[parameterName] = [example];
            // } else if (concreteType === "Number" && this.isNumberOrFloat(example)) {
            //   obj[parameterName] = example * 1
            // } else {
            //   obj[parameterName] = example !== "" ? (example === "false" || example === "true" ? JSON.parse(example) : example) : "";
            // }
          } else {
            if (concreteType === "Object" || concreteType === "Map") {
              obj[parameterName] = {};
              if (children && children.length) {
                this.bodyDisposeHandle(obj[parameterName], children);
              }
            } else if (concreteType === "ObjectCom") {
              obj[parameterName] = [{}];
              this.bodyDisposeHandle(obj[parameterName][0], children);
            }
          }
        }
      });
    },
    authDataReturn(arr) {
      let temp = deepClone(this.authJsonData);
      let flag = arr.some((item) => {
        if (temp[item]) {
          temp = temp[item];
          return false;
        } else {
          this.$message({
            type: "error",
            message: "数据处理失败，认证存在无效值",
          });
          return true;
        }
      });
      if (!flag) {
        return temp;
      }
    },
  },
  components: {
    jsonView,
    vueJsonEditor
  },
  created() {
    this.init()
  }
}
</script>
<style scoped lang="scss">
.apiDebugging {
  display: flex;
  width: 100%;
  margin-top: 5px;

  .left {
    margin-right: 5px;
    height: 72vh;
    padding: 10px 15px;
    overflow: auto;
    background-color: #fff;
    flex: 0.5;

    > .debugchunk {

    }
  }

  .right {
    height: 72vh;
    padding: 10px 15px;
    overflow: auto;
    background-color: #fff;
    border-radius: 8px;
    flex: 0.5;

    > .debugchunk {
    }
  }

  .addressChunk {
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    width: 100%;

    > .label {
      flex: 0.1;
    }

    > .input {
      flex: 0.9;
    }
  }
}
</style>
<style lang="less" scoped>
.code-json-editor {
  /* jsoneditor右上角默认有一个链接,加css去掉 */

  /deep/ .jsoneditor-poweredBy {
    display: none !important;
  }

  /deep/ .jsoneditor-menu {
    background-color: #fff !important;
    color: #000 !important;

    button {
      background-color: #4c81f2 !important;
    }
  }

  /deep/ .ace_gutter {
    background-color: #fff;
    border-right: 1px solid gainsboro;
  }

  /deep/ .ace-jsoneditor {
    height: 250px !important;
  }
}
</style>
