<template>
  <div class="performanceAdd">
    <div class="header">
      <div class="name">
        <div class="name-wrap">测试名称</div>
        <el-input v-model="addForm.performanceName" placeholder="请输入名称" maxlength="255" show-word-limit></el-input>
      </div>
      <div class="save" v-loading="loading">
        <el-button type="primary" plain @click="handleWithSave">保存</el-button>
        <el-button type="primary" plain @click="handleWithSaveAndExecute">保存并执行</el-button>
        <el-button type="primary" plain @click="handleWithExecute">立即执行</el-button>
        <el-button type="warning" plain @click="handleWithCancel">取消</el-button>
      </div>
      <div class="date">
        <div class="date-top">
          <i class="el-icon-date"></i>
          <span class="date-title">SCHEDULER</span>
          <el-switch v-model="addForm.crontabStatus" :active-value="1" :inactive-value="0" @change="handleSwitchChange"></el-switch>
        </div>
        <div class="date-bottom" v-if="addForm.crontabStatus === 1">
          <span>下次执行时间：{{ nextExecutionTime }}</span>
        </div>
      </div>
    </div>
    <div class="tab">
      <el-tabs v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="场景配置" name="first">
          <div class="title">场景列表</div>
          <el-button style="margin-top: 10px; margin-bottom: 10px;" icon="el-icon-share"
            @click="handleClickLoad">引用接口自动化场景</el-button>
          <el-table :data="changeList">
            <el-table-column prop="testCaseName" label="场景名称" />
            <el-table-column prop="status" label="Enable/Disable">
              <template slot-scope="scope">
                <el-switch v-model="scope.row.status" active-value="1" inactive-value="0"></el-switch>
              </template>
            </el-table-column>
            <el-table-column prop="action" label="操作">
              <template slot-scope="scope">
                <el-button type="text" icon="el-icon-delete" style="color: red;"
                  @click="hadleClickDelete(scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <el-tab-pane label="压力配置" name="second">
          <div class="pressure-header">
            <div class="title">速兑通接口</div>
            <div class="pressure-title">并发用户数{{ addForm.concurrentThreads }}，压测时长{{ addForm.pressureHour }}时{{
              addForm.pressureMinute }}分{{ addForm.pressureSecond }}秒</div>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">并发用户数</div>
            <el-input-number v-model="addForm.concurrentThreads" controls-position="right" :min="0"></el-input-number>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">取样器错误后</div>
            <el-select v-model="addForm.errorOperType" placeholder="请选择">
              <el-option key="1" label="继续" value="1"></el-option>
              <el-option key="2" label="开始下一个线程轮询" value="2"></el-option>
              <el-option key="3" label="停止线程" value="3"></el-option>
              <el-option key="4" label="停止测试" value="4"></el-option>
              <el-option key="5" label="立即停止测试" value="5"></el-option>
            </el-select>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">执行方式</div>
            <el-radio-group v-model="addForm.executeType">
              <el-radio-button :label="1">按持续时间</el-radio-button>
              <el-radio-button :label="2">按迭代次数</el-radio-button>
            </el-radio-group>
            <el-input-number v-if="addForm.executeType === 2" style="margin-left: 10px;" v-model="addForm.loopCount"
              controls-position="right" :min="0"></el-input-number>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">Ramp-Up</div>
            <el-input-number v-model="addForm.rampUpSeconds" controls-position="right" :min="0"></el-input-number>
            <div class="pressure-warap-name">秒</div>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">压测时长</div>
            <el-input-number v-model="addForm.pressureHour" controls-position="right" :min="0"></el-input-number>
            <div class="pressure-warap-name">时</div>
            <el-input-number v-model="addForm.pressureMinute" controls-position="right" :min="0"></el-input-number>
            <div class="pressure-warap-name">分</div>
            <el-input-number v-model="addForm.pressureSecond" controls-position="right" :min="0"></el-input-number>
            <div class="pressure-warap-name">秒</div>
          </div>
          <div class="pressure-wrap">
            <div class="pressure-warap-name">Rps开启</div>
            <el-switch v-model="addForm.rpsStatus" active-value="1" inactive-value="0"></el-switch>
            <div class="pressure-warap-name">Rps上限</div>
            <el-input-number v-model="addForm.rpsLimit" controls-position="right" :min="0"></el-input-number>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
    <el-dialog title="场景列表" :visible.sync="dialogVisible" width="60%">
      <div class="search">
        <el-input v-model="searchScenen.name" style="width: 300px;" placeholder="根据ID/名称/标签 搜索"
          @blur="searchSecenList"></el-input>
      </div>
      <div class="table">
        <el-table ref="tableRef" :data="sceneList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column prop="id" width="100" label="ID" align="center" />
          <el-table-column prop="name" label="场景名称" align="center" />
          <el-table-column prop="remark" label="标签" align="center" />
          <el-table-column prop="createTime" label="修改时间" align="center" />
        </el-table>
        <div class="page">
          <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
            :page-size="searchScenen.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="totalScene" />
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="handleWithSure">确 定</el-button>
      </span>
    </el-dialog>
    <el-dialog title="定时任务" :visible.sync="dialogVisibleTime" width="60%" :before-close="handleClose">
      <el-tabs v-model="activeTime">
        <el-tab-pane label="任务配置" name="first"></el-tab-pane>
        <div class="editTimeTitle">编辑定时任务</div>
        <div class="crontab-wrap">
          <div class="title">Crontab表达式</div>
          <el-input v-model="addForm.crontab" @input="updateExecutionTimes" placeholder="请输入crontab表达式" />
        </div>
        <div class="near-time">
          <div class="title">最近5次运行时间</div>
          <div v-for="(item, index) in executionTimeList" :key="index">
            {{ item.time }}
          </div>
        </div>
      </el-tabs>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisibleTime = false, addForm.crontabStatus = 0">取 消</el-button>
        <el-button type="primary" @click="handleDialogConfirm">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { editTest, editAndExecuteTest, getTestCaseList, getTestDetail, executeTest } from '../../../api/performance';
import {runTestPlanCase} from "../../../api/test/planCase";
import parser from 'cron-parser';  // 添加 cron-parser 依赖

export default {
  name: "PerformanceEdit",
  data() {
    return {
      addForm: {
        performanceName: '', // 性能测试名称
        performanceTestCaseVOList: [], // 场景列表
        concurrentThreads: '', // 并发用户数
        errorOperType: '', // 在取样器错误后要执行的动作，1：继续；2：开始下一个线程轮询；3：停止线程；4：停止测试；5：立即停止测试
        executeType: '', // 执行方式，1：按持续时间；2：按迭代次数
        rampUpSeconds: '0', // 多少秒内线程建立完成，默认0
        pressureHour: '0',  // 压测时长，时，默认0
        pressureMinute: '0', // 压测时长，分，默认0
        pressureSecond: '0', // 压测时长，秒，默认0
        rpsStatus: '0', //  rps状态：0关闭，1开启，默认0
        rpsLimit: '0', // 每分钟rps上限数，默认0
        crontab: '', // crontab表达式
        crontabStatus: 0, // 定时任务状态：0关闭，1开启，默认0
        loopCount: '0', // 迭代次数，默认0
      },
      loading: false,
      activeName: 'first',
      sceneList: [], // 场景列表
      dialogVisible: false, // 场景列表
      searchScenen: {
        pageNum: 1,
        pageSize: 10,
        name: '', // 名称
      },
      totalScene: 0,
      searchScene: '',
      changeList: [],
      multipleSelection: [],
      dialogVisibleTime: false,
      activeTime: 'first',
      executionTimeList: [],  // 修改为空数组
      nextExecutionTime: '',  // 添加下次执行时间
      validation: false, // 校验
    }
  },
  mounted() {
    this.getTestCaseData()
    this.getTestDetailData()
  },
  watch: {
    // 监听 crontab 和 crontabStatus 的变化
    'addForm.crontab': {
      handler(newVal) {
        if (newVal && this.addForm.crontabStatus === 1) {
          this.updateExecutionTimes();
        }
      }
    },
    'addForm.crontabStatus': {
      handler(newVal) {
        if (newVal === 1 && this.addForm.crontab) {
          this.updateExecutionTimes();
        } else if (newVal === 0) {
          this.nextExecutionTime = '';
        }
      }
    }
  },
  methods: {
    // 校验
    validationForm() {
      if (this.addForm.performanceName === '' || this.addForm.performanceName === null) {
        this.$message({ message: '请输入测试名称', type: 'warning' })
        return
      }

      if (this.addForm.errorOperType === '' || this.addForm.errorOperType === null) {
        this.$message({ message: '请填写取样器错误后', type: 'warning' })
        return
      }

      if (this.addForm.executeType === '' || this.addForm.executeType === null) {
        this.$message({ message: '请选择执行方式', type: 'warning' })
        return
      }

      this.validation = true
    },
    // 保存
    handleWithSave() {
      this.validationForm()
      if (this.validation === false) { return }
      this.addForm.performanceTestCaseVOList = this.changeList
      editTest(this.addForm).then(res => {
        if (res.code === 200) {
          this.$message({ message: '编辑成功', type: 'success' })
          this.$tab.closeOpenPage({ path: "/performance/performance" });
        } else {
          this.$message({ message: '编辑失败', type: 'error' })
        }
      })
    },
    // 保存并执行
    handleWithSaveAndExecute() {
      this.validationForm()
      if (this.validation === false) { return }
      if (this.addForm.crontab === '' || this.addForm.crontab === null) {
        this.$message({ message: '请输入Crontab表达式', type: 'warning' })
        return
      }
      this.loading = true;
      editAndExecuteTest(this.addForm).then(res => {
        if (res.code === 200) {
          this.$message({ message: '编辑成功', type: 'success' })
          this.$tab.closeOpenPage({ path: "/performance/performance" });
        } else {
          this.$message({ message: '编辑失败', type: 'error' })
        }
      }).finally(() => {
        this.loading = false;
      })
    },
    // 立即执行
    handleWithExecute() {
      const myId = this.$route.query.id;
      this.$modal.confirm('是否确认立即执行性能测试？').then(function () {
        return executeTest(myId);
      }).then((res) => {
          if (res.code === 200) {
            this.$modal.msgSuccess("提交执行成功");
          } else {
            this.$message({ message: '提交执行失败', type: 'error' })
          }
      }).finally(() => {
        this.loading = false;
      });
    },
    // 取消
    handleWithCancel() {
      this.$tab.closeOpenPage({ path: "/performance/performance" });
    },
    handleClick() { },
    // 加载jmx文件
    handleClickLoad() {
      this.dialogVisible = true
      this.$nextTick(() => {
        let array = this.multipleSelection
        this.sceneList.forEach(row => {
          if (array.includes(row)) {
            this.$refs.tableRef.toggleRowSelection(row, true);
          } else {
            this.$refs.tableRef.toggleRowSelection(row, false);
          }
        })
      });

    },
    // 删除
    hadleClickDelete(val) {
      this.changeList = this.changeList.filter(item => item !== val);
      console.log(this.changeList)
      this.multipleSelection = []
      this.sceneList.forEach(row => {
        this.changeList.forEach(item => {
          if (row.id === item.testCaseId) {
            this.multipleSelection.push(row)
          }
        })
      })
    },
    // netWorking
    getTestCaseData() {
      getTestCaseList(this.searchScenen).then(res => {
        if (res.code === 200) {
          this.sceneList = res.rows
          this.totalScene = res.total
        }
      })
    },
    // 获取详情
    getTestDetailData() {
      getTestDetail(this.$route.query.id).then(res => {
        if (res.code === 200) {
          this.addForm = res.data
          this.changeList = res.data.performanceTestCaseVOList
          // 如果有定时任务，更新下次执行时间
          if (this.addForm.crontabStatus === 1 && this.addForm.crontab) {
            this.updateExecutionTimes();
          }
        }
      })
    },
    searchSecenList() {
      this.getTestCaseData()
    },
    // 分页
    handleSizeChange(val) {
      this.searchScenen.pageSize = val
      this.getTestCaseData()
    },
    handleCurrentChange(val) {
      this.searchScenen.pageNum = val
      this.getTestCaseData()
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    handleWithSure() {
      this.changeList = []
      this.multipleSelection.forEach(item => {
        var par = {
          testCaseId: item.id,
          status: '1',
          testCaseName: item.name
        }
        this.changeList.push(par)
      })

      this.dialogVisible = false
    },
    handleClose() {
      this.dialogVisibleTime = false
      this.addForm.crontabStatus = 0
    },
    // 更新执行时间列表
    updateExecutionTimes() {
      const crontab = this.addForm.crontab.trim();
      if (!crontab) {
        this.executionTimeList = [];
        this.nextExecutionTime = '';
        return;
      }

      try {
        // 解析crontab表达式
        const interval = parser.parseExpression(crontab);
        const times = [];

        // 获取最近5次执行时间
        for (let i = 0; i < 5; i++) {
          const nextTime = interval.next().toDate();
          times.push({
            time: this.formatDate(nextTime)
          });
        }

        this.executionTimeList = times;
        this.nextExecutionTime = times[0].time;  // 设置下次执行时间
      } catch (error) {
        this.$message.error('无效的crontab表达式');
        this.executionTimeList = [];
        this.nextExecutionTime = '';
      }
    },
    // 格式化日期
    formatDate(date) {
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      const hour = String(date.getHours()).padStart(2, '0');
      const minute = String(date.getMinutes()).padStart(2, '0');
      const second = String(date.getSeconds()).padStart(2, '0');
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
    },
    // 修改确定按钮的处理函数
    handleDialogConfirm() {
      if (!this.addForm.crontab.trim()) {
        this.$message.warning('请输入Crontab表达式');
        return;
      }
      
      try {
        parser.parseExpression(this.addForm.crontab.trim());
        this.updateExecutionTimes();
        this.dialogVisibleTime = false;
      } catch (error) {
        this.$message.error('无效的crontab表达式，请修正后再确定');
        return;
      }
    },
    // 添加开关变化处理函数
    handleSwitchChange(val) {
      if (val === 1) {
        this.dialogVisibleTime = true;
      }
    },
  }

}

</script>


<style scoped lang="scss">
.performanceAdd {
  padding: 20px;

  .header {
    display: flex;
    justify-content: space-between;

    .name {
      display: flex;
      width: 300px;
      align-items: center;

      .name-wrap {
        width: 80px;
        font-size: 14px;
      }
    }
  }

  .tab {
    margin-top: 20px;

    .title {
      font-size: 14px;
      font-weight: 600;
    }
  }

  .search {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 10px;
  }

  .page {
    padding: 10px;
    display: flex;
    justify-content: flex-end;
  }

  .pressure-header {
    display: flex;
    align-items: center;
    margin-bottom: 10px;

    .pressure-title {
      margin-left: 20px;
      font-size: 12px;
      font-weight: 500;
    }
  }

  .pressure-wrap {
    display: flex;
    padding: 10px;
    align-items: center;

    .pressure-warap-name {
      font-size: 14px;
      font-weight: 400;
      margin: 0px 10px;
    }
  }

  .date {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    .date-top {
      display: flex;

      .date-title {
        font-size: 14px;
        font-weight: 500;
        margin: 0px 10px;
      }
    }

    .date-bottom {
      display: flex;
      margin: 10px;
    }

  }

  .editTimeTitle {
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 10px;
  }

  .crontab-wrap {
    display: flex;
    align-items: center;

    .title {
      font-size: 14px;
      width: 150px;
      margin-right: 20px;
    }
  }

  .near-time {
    margin-top: 20px;
    padding: 20px 10px;
    border: solid #dcdfe6 1px;
  }
}
</style>
