<template>
  <el-dialog class="api-test" v-model="showDialog" title="测试API" width="800px" :close-on-click-modal="false" :close-on-press-escape="false">
    <el-descriptions :column="2" border>
      <el-descriptions-item label="API名称" :span="2">{{ apiData.name }}</el-descriptions-item>
      <el-descriptions-item label="API路径" :span="2">
        <div class="api-path-container">
            <span class="domain">{{ originUrl }}/apihub/</span>
            <span class="path">{{ apiData.path }}</span>
          <el-tooltip content="复制API完整路径" placement="top">
            <el-icon class="copy-icon" @click="copyApiPath"><CopyDocument /></el-icon>
          </el-tooltip>
        </div>
      </el-descriptions-item>
      <el-descriptions-item label="请求方法">
        <el-tag :type="getMethodTagType(apiData.method)" size="small">{{ apiData.method }}</el-tag>
      </el-descriptions-item>
      <el-descriptions-item label="数据源">{{ apiData.dataSourceName }}</el-descriptions-item>
    </el-descriptions>

    <div class="section-title">参数设置</div>
    <el-form :model="testParams" label-width="120px" v-if="apiData.parameters && apiData.parameters.length">
      <el-form-item v-for="param in apiData.parameters" :key="param.name" :label="param.name" :required="param.required">
        <el-input v-if="param.type === 'string'" v-model="testParams[param.name]" :placeholder="getParamPlaceholder(param)"></el-input>
        <el-input-number v-else-if="param.type === 'int' || param.type === 'float'" v-model="testParams[param.name]" :placeholder="getParamPlaceholder(param)"></el-input-number>
        <el-switch v-else-if="param.type === 'bool'" v-model="testParams[param.name]" :active-value="true" :inactive-value="false"></el-switch>
        <el-input v-else v-model="testParams[param.name]" :placeholder="getParamPlaceholder(param)"></el-input>
        <div class="param-desc" v-if="param.description">{{ param.description }}</div>
      </el-form-item>
    </el-form>
    <el-empty description="该API没有定义参数" v-else></el-empty>

    <div class="section-title">测试结果</div>
    <div v-if="!testResult.success && !loading" class="test-placeholder">点击下方"执行测试"按钮开始测试</div>
    <div v-else>
      <el-alert :title="testResult.message" :type="testResult.success ? 'success' : 'error'" :closable="false" show-icon></el-alert>
      <div v-if="testResult.success && testResult.data" class="result-container">
        <el-tabs v-model="activeTab">
          <el-tab-pane label="结果数据" name="data">
            <pre class="result-json">{{ formatJson(testResult.data) }}</pre>
          </el-tab-pane>
          <el-tab-pane label="原始响应" name="raw">
            <pre class="result-json">{{ formatJson(testResult) }}</pre>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="closeDialog">关闭</el-button>
        <el-button type="primary" @click="runTest" :loading="loading">执行测试</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, reactive, watch } from "vue";
import apiHub from "/@/api/modules/apiHub";
import { ElMessage } from "element-plus";
import { CopyDocument } from "@element-plus/icons-vue";
import getOrigin from "/@/utils/origin";

const showDialog = ref(false);
const loading = ref(false);
const activeTab = ref("data");
const originUrl: string = getOrigin("");

// API数据
const apiData = reactive<any>({
  id: null,
  name: "",
  path: "",
  method: "",
  dataSourceId: null,
  dataSourceName: "",
  sqlType: "",
  sqlContent: "",
  parameters: [],
  returnFormat: "",
  version: "",
  status: "",
  plugins: [],
  description: "",
  createdAt: "",
  updatedAt: "",
});

// 测试参数
const testParams = reactive<any>({});

// 测试结果
const testResult = reactive<any>({
  success: false,
  message: "",
  data: null,
});

// 监听API数据变化，初始化测试参数
watch(
  () => apiData.parameters,
  (newParams) => {
    // 清空测试参数
    Object.keys(testParams).forEach((key) => {
      delete testParams[key];
    });

    // 根据参数定义初始化测试参数
    if (newParams && newParams.length) {
      newParams.forEach((param: any) => {
        // 如果有默认值，使用默认值
        if (param.defaultValue !== undefined && param.defaultValue !== "") {
          // 根据类型转换默认值
          if (param.type === "int") {
            testParams[param.name] = parseInt(param.defaultValue);
          } else if (param.type === "float") {
            testParams[param.name] = parseFloat(param.defaultValue);
          } else if (param.type === "bool") {
            testParams[param.name] = param.defaultValue === "true";
          } else {
            testParams[param.name] = param.defaultValue;
          }
        } else {
          // 否则设置为空值
          if (param.type === "int" || param.type === "float") {
            testParams[param.name] = null;
          } else if (param.type === "bool") {
            testParams[param.name] = false;
          } else {
            testParams[param.name] = "";
          }
        }
      });
    }
  },
  { deep: true }
);

// 根据请求方法返回不同的标签类型
const getMethodTagType = (method: string) => {
  switch (method?.toUpperCase()) {
    case "GET":
      return "success";
    case "POST":
      return "primary";
    case "PUT":
      return "warning";
    case "DELETE":
      return "danger";
    default:
      return "info";
  }
};

// 获取参数占位符文本
const getParamPlaceholder = (param: any) => {
  if (param.required) {
    return `请输入${param.description || param.name}（必填）`;
  }
  return `请输入${param.description || param.name}（选填）`;
};

// 格式化JSON
const formatJson = (json: any) => {
  try {
    return JSON.stringify(json, null, 2);
  } catch (e) {
    return json;
  }
};

// 关闭对话框
const closeDialog = () => {
  showDialog.value = false;
};

// 执行测试
const runTest = async () => {
  // 重置测试结果
  testResult.success = false;
  testResult.message = "";
  testResult.data = null;

  loading.value = true;

  apiHub
    .test({
      id: apiData.id,
      parameters: testParams,
    })
    .then((res: any) => {
      testResult.success = true;
      testResult.message = "测试成功";

      testResult.data = res;
    })
    .catch((error: any) => {
      testResult.success = false;
      testResult.message = error?.message || "测试失败";
    })
    .finally(() => {
      loading.value = false;
    });
};

// 复制API完整路径
const copyApiPath = () => {
  // 实现复制功能
  const fullPath = `${originUrl}/apihub/${apiData.path}`;

  // 使用Clipboard API复制到剪贴板
  navigator.clipboard.writeText(fullPath)
    .then(() => {
      ElMessage.success('已复制API完整路径到剪贴板');
    })
    .catch(() => {
      ElMessage.error('复制失败，请手动复制');
    });
};

// 打开对话框
const open = async (row: any) => {
  // 清空数据
  Object.keys(apiData).forEach((key) => {
    apiData[key] = undefined;
  });

  // 重置测试结果
  testResult.success = false;
  testResult.message = "";
  testResult.data = null;

  showDialog.value = true;

  // 实际使用时，应该调用API获取详细信息
  // const res = await apiHub.get(row.id)
  // Object.assign(apiData, res)

  // 这里模拟直接使用传入的行数据
  Object.assign(apiData, row);
};

defineExpose({ open });
</script>

<style scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
}

.section-title {
  font-weight: bold;
  margin: 20px 0 10px;
  font-size: 16px;
  border-left: 4px solid #409eff;
  padding-left: 10px;
}

.param-desc {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.test-placeholder {
  text-align: center;
  color: #909399;
  padding: 20px;
  background-color: #f5f7fa;
  border-radius: 4px;
}
/* 深色主题下的样式 */
[data-theme='dark'] .test-placeholder {
  text-align: center;
  color: #e4e3e3;
  padding: 20px;
  background-color: #424040;
  border-radius: 4px;
}

.result-container {
  margin-top: 15px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
}
/* 深色主题下的样式 */
[data-theme='dark'] .result-container {
  margin-top: 15px;
  border: 1px solid #575656;
  border-radius: 4px;
}

.result-json {
  background-color: #f5f7fa;
  padding: 10px;
  font-family: monospace;
  white-space: pre-wrap;
  word-break: break-all;
  margin: 0;
  max-height: 300px;
  overflow: auto;
}
/* 深色主题下的样式 */
[data-theme='dark'] .result-json {
  background-color: #3c3b3b;
  color: #ffffff;
  padding: 10px;
  font-family: monospace;
  white-space: pre-wrap;
  word-break: break-all;
  margin: 0;
  max-height: 300px;
  overflow: auto;
}


.el-empty{
  height: 120px;
}

.api-path-container {
  display: inline-block;
  text-decoration: none;
  color: black; /* 设置整体文字颜色 */
  align-items: center; /* 垂直居中对齐 */
}
/* 深色主题下的样式 */
[data-theme='dark'] .api-path-container {
  display: inline-block;
  text-decoration: none;
  color: #fff; /* 设置整体文字颜色 */
}
.api-path-container .domain {
  background-color: #eee; /* 设置域名部分的背景颜色 */
  color: black; /* 设置域名部分的文字颜色 */
  padding: 2px 4px; /* 添加一些内边距 */
  display: inline-block;
  border-radius: 15px; /* 增加圆角 */
}
/* 深色主题下的样式 */
[data-theme='dark'] .api-path-container .domain{
  background-color: #3c3b3b; /* 设置域名部分的背景颜色 */
  color: white; /* 设置域名部分的文字颜色 */
  padding: 2px 4px; /* 添加一些内边距 */
  display: inline-block;
  border-radius: 15px; /* 增加圆角 */
}
.api-path-container .path {
  display: inline-block;
}


.copy-icon {
  cursor: pointer;
  color: var(--el-color-primary);
  transition: all 0.2s;
  font-size: 24px;
  margin-left: 8px;
  padding: 4px;
  border-radius: 4px;
}

.copy-icon:hover {
  transform: scale(1.1);
  color: var(--el-color-primary-dark-2);
  background-color: var(--el-color-primary-light-9);
}
</style>
