<!-- 检测设备
注意事项：
这个页面涉及到的planid或者runnerid或者executeid都是 this.deviceDetail.curPlanId
 -->
<template>
  <div class="check-container">
    <div class="check-container-inner">
      <div class="check-title">
        <div class="title-main">
          设备编号：{{ deviceGet.serialNumber||deviceGet.name }}
          <!-- <el-button icon="el-icon-plus" class="dark-button" size="mini" @click="test()">测试按钮</el-button> -->
        </div>
        <div class="title-lable">
          <div class="state" :style="'color:'+deviceStatus.stateStyle+';border:1px solid '+deviceStatus.stateStyle+';background: '+deviceStatus.stateStyle+'33;'">{{ deviceStatus.stateName }}</div>
        </div>
      </div>
      <div class="check-sub-title">
        <!-- 选择方案 -->
        <div class="sub-left">
          <el-select
            v-model="deviceDetail.devicePlanValue"
            filterable
            placeholder="请选择方案"
            size="small"
            :disabled="isDisable"
            @change="changePlan"
          >
            <el-option
              v-for="item in deviceDetail.devicePlanOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </div>
        <!-- 选择刷新 -->
        <div class="sub-right">
          <el-select
            v-model="deviceDetail.deviceRefreshValue"
            filterable
            placeholder="请选择刷新"
            size="small"
            @change="changeTime"
          >
            <el-option
              v-for="item in deviceDetail.deviceRefreshOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </div>
      </div>
      <div class="contorl-panel">
        <div class="top">
          <!-- 检测参数 和右侧按钮一起 移入 CheckParames.vue 原来的先保留，测试通过删除 -->
          <el-row>
            <CheckParamesMaster104
              v-if="isMaster104 == true"
              ref="checkparames"
              :cur-plan-detail="deviceDetail.planDetail"
              :device-status="deviceStatus"
              :play-data-id="deviceDetail.curPlanId"
              @updateDisable="getDisable"
              @updateDeviceStatus="getDeviceStatus"
            />
            <CheckParames
              v-else
              ref="checkparames"
              :cur-plan-detail="deviceDetail.planDetail"
              :device-status="deviceStatus"
              :play-data-id="deviceDetail.curPlanId"
              @updateDisable="getDisable"
              @updateDeviceStatus="getDeviceStatus"
            />
          </el-row>
        </div>
        <!-- 如果检测协议是低功耗，则显示低功耗组件，只显示MQTT结果 -->
        <!-- <low-power v-if="deviceDetail.planDetail.productType == 'LOW_POWER'" ref="lowChild" :device-detail="deviceDetail" /> -->
        <PowerCentent
          v-if="deviceDetail.planDetail.productType == 'MICRO_POWER' || deviceDetail.planDetail.productType == 'LOW_POWER'"
          ref="lowPComp"
          :example-update="exampleUpdate"
          :device-detail="deviceDetail"
          :component-parames="{
            'deviceName':deviceGet.name,
            'curPlanId':deviceDetail.curPlanId,
            'curSuiteId':deviceDetail.suiteId,
            'status':exampleStatus,
            'isDisable':isDisable
          }"
        />
        <!-- 默认样式 -->
        <el-row v-else>
          <el-col :span="6" class="main-left">
            <!-- 步骤组件 模块 -->
            <CheckSteps
              v-if="deviceDetail.planDetail.id"
              ref="stepComp"
              :key="checkStepsUpdate"
              :check-steps-parames="{
                curPlanId: deviceDetail.curPlanId,
                curPlanDetailId: deviceDetail.planDetail.id,
                checkPlans: deviceDetail.deviceCheckPlans
              }"
            />
          </el-col>
          <el-col :span="18" class="main-right">
            <div class="main-right-container">
              <!-- 用例模块 -->
              <Example
                :key="exampleUpdate"
                :component-parames="{
                  'deviceName':deviceGet.name,
                  'curPlanId':deviceDetail.curPlanId,
                  'curSuiteId':deviceDetail.suiteId,
                  'status':exampleStatus,
                  'isDisable':isDisable
                }"
              />
              <!-- 采样模块 -->
              <SampleMaster104
                v-if="isMaster104==true"
                :key="sampleUpdate104"
                :component-parames="{
                  'deviceName':deviceGet.name,
                  'curPlanId':deviceDetail.curPlanId,
                  'productId':deviceDetail.planDetail.productId,
                  'status':sampleStatus,
                  'isDisable':isDisable
                }"
              />
              <Sample
                v-if="isMaster104==false"
                :key="sampleUpdate"
                :component-parames="{
                  'deviceName':deviceGet.name,
                  'curPlanId':deviceDetail.curPlanId,
                  'productId':deviceDetail.planDetail.productId,
                  'status':sampleStatus,
                  'isDisable':isDisable
                }"
              />
              <ModelReportMaster104
                v-if="isMaster104"
                :report-parames="{
                  'deviceName':'',
                  'curPlanId':deviceDetail.curPlanId
                }"
                @toggleModel="closeModel"
              />
            </div>
          </el-col>
        </el-row>
        <!-- <div class="left"></div>
        <div class="right"></div> -->
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import { editRow, httpGet, httpPostJson, getOptionIndex } from '@/api/common-action'
import { singleAction } from '@/api/device'
// 当前检测参数
import CheckParamesMaster104 from './components/CheckParames_master104'
import CheckParames from './components/CheckParames'
// 步骤组件
import CheckSteps from './components/CheckSteps.vue'
// 用例表格
import Example from './tables/Example'
// 采样表格
import Sample from './tables/Sample'
// 采样表格（仅主站104检测才显示）
import SampleMaster104 from './tables/Sample_master104'
// 报文列表（仅主站104检测才显示）
import ModelReportMaster104 from './components/ModelReport_master104'
// 导入总线
import { EventBus } from '@/main.js'

// 微功率界面
import PowerCentent from './protocols/PowerCentent'
export default {
  components: {
    CheckParames,
    CheckParamesMaster104,
    Example,
    Sample,
    CheckSteps,
    PowerCentent,
    ModelReportMaster104,
    SampleMaster104
  },
  filters: {
    formartStatus: function(params) {
      if (params == null) {
        return 'null'
      }
    }
  },
  data() {
    return {
      isMaster104: false, // 是否主站104
      // 默认数据
      deviceDetail: {
        deviceId: 0,
        suiteId: 0, // 方案ID 用于获取方案详细信息
        curPlanId: 0, // 当前执行方案ID,用于获取当前正在执行的方案各种状态和执行情况
        planDetail: {}, // 方案详情
        devicePlanValue: '',
        devicePlanOptions: [],
        // 实时状态 刷新时间间隔 默认15秒 0不刷新 -1 自动刷新
        deviceRefreshValue: 0,
        deviceRefreshOptions: [
          {
            label: '不刷新',
            value: 0
          },
          {
            label: '每3秒',
            value: 3
          },
          {
            label: '每10秒',
            value: 10
          },
          {
            label: '每1分钟',
            value: 60
          },
          {
            label: '每5分钟',
            value: 300
          }
        ],
        deviceCheckPlans: [],
        // 当前方案执行步骤id，例: '2400000013',
        currenPlanStepsId: '0',
        showModelReport: false,
        showModelAddStep: false
      },
      // 步骤栏更新值，用于更新步骤栏状态
      deviceCheckPlanUpdate: '0',
      // 从后端获取后的设备信息
      deviceGet: {},
      // 是否禁用
      isDisable: true,
      deviceStatus: {},
      singleActionRunId: '0',
      // 准备编辑的当前步骤数据
      editCheckStepData: {},
      // 开始检测要传的数据
      playData: {},
      // 计时器
      timer: null,
      // 用例高频刷新状态 存放变量
      exampleStatus: {
        successful: 0,
        failed: 0
      },
      // 采集高频刷新状态 存放变量
      sampleStatus: {},
      // 用例刷新值，用于控制用例刷新
      exampleUpdate: 'example-0',
      // 采样刷新值，用于控制用例刷新
      sampleUpdate: 'sample-0',
      sampleUpdate104: 'sample104-0',
      // 步骤刷新值，用于控制用例刷新
      checkStepsUpdate: 'checkSteps-0',
      // 点击样式
      clickClass: {
        schedule: 'default',
        cancel: 'default',
        refresh: 'default'
      },
      // 使用点击对象的方式改变样式，避免当有多个不确定数量的元素时无法控制 的问题
      clickObj: {}
    }
  },
  computed: {
    ...mapGetters(['roles'])
  },
  watch: {
    $route: {
      handler() {
        // 路由改变时先清空定时器，避免切换页面时生成多个定时器
        this.clearTimer()
        this.watchRouter()
      }
    },
    deviceDetail: {
      handler() {
        if (this.deviceDetail.deviceRefreshValue > 0) {
          // 死循环一直更新状态数据
          // this.getStatusLoop()
        }
      },
      deep: true
    }
  },
  created() {
    this.deviceDetail.curPlanId = this.$route.query.curPlanId
    this.deviceDetail.suiteId = this.$route.query.suiteId
    this.deviceDetail.deviceId = this.$route.query.deviceId
  },
  mounted() {
    const tmpdeviceRefreshValue = window.localStorage.getItem('deviceRefreshValue')
    if (tmpdeviceRefreshValue !== null && !isNaN(tmpdeviceRefreshValue)) {
      this.deviceDetail.deviceRefreshValue = tmpdeviceRefreshValue * 1
      this.getStatusLoop()
    }
    this.$nextTick(() => {
      // 网页加载完成后执行
      this.initFunctions()
      // 全局公用函数测试
      // console.log('this.common=', this.common)
      // const test = this.common.ct3()
      // console.log('test=', test)
    })
  },
  beforeDestroy() {
    // 页面切换前先把定时器清空，否则会造成多个定时器，客户无法控制
    // console.log('beforeDestroy started')
    this.clearTimer()
  },
  methods: {
    // 监听路由
    watchRouter() {
      // console.log('watchRouter stated query=', this.$route.query)
      this.deviceDetail.curPlanId = this.$route.query.curPlanId
      this.deviceDetail.suiteId = this.$route.query.suiteId
      this.deviceDetail.deviceId = this.$route.query.deviceId
      this.initFunctions()
    },

    // 初始化
    async initFunctions() {
      // 获取设备详细信息
      const getUrl = `/test/project/${this.deviceDetail.deviceId}`
      httpGet(getUrl).then(response => {
        // console.log('initFunctions deviceGet=', response)
        this.deviceGet = response
      })

      // 刷新测试状态
      this.controlRefresh()

      // 获取选择方案选项
      httpGet(`/test/project/${this.deviceDetail.deviceId}/plan/list`).then(
        (response) => {
          // console.log('获取选择方案选项 getOptions rs=', response)
          this.deviceDetail.devicePlanOptions = response
          this.deviceDetail.devicePlanValue = this.deviceDetail.curPlanId
        }
      )

      // 获取检测参数
      // /test/plan/:plan
      httpGet(`/test/plan/${this.deviceDetail.curPlanId}`).then((response) => {
        // console.log('获取当前方案详细信息 res=', response)
        this.deviceDetail.planDetail = response
        if (response.productType === 'IEC104') {
          this.isMaster104 = true
        } else {
          this.isMaster104 = false
        }
      })

      // 获取当前方案相关步骤
      this.getSteps()
    },
    // 更改定时器时 清除之前的定时器
    changeTime(val) {
      this.clearTimer()
      this.deviceDetail.deviceRefreshValue = val
      if (this.deviceDetail.deviceRefreshValue === 0) {
        window.localStorage.removeItem('deviceRefreshValue')
      } else {
        window.localStorage.setItem('deviceRefreshValue', this.deviceDetail.deviceRefreshValue)
        this.getStatusLoop()
      }
    },
    // 自动循环刷新
    async getStatusLoop() {
      if (this.deviceDetail.deviceRefreshValue === 0 || this.deviceDetail.deviceRefreshValue === null) {
        this.clearTimer()
        return
      }
      // 每隔x秒运行一次
      this.timer = setTimeout(() => {
        if (this.deviceDetail.deviceRefreshValue === 0 || !this.deviceDetail.deviceRefreshValue) {
          this.clearTimer()
          return
        }

        // 刷新测试状态
        this.controlRefresh()

        // #TODO: 999 和 3200000217 都 返回的是空
        // 接口 步骤状态（高频刷新） /test/execute/:runner/progress
        // :runner 例 3200000217
        // 刷新步骤
        EventBus.$emit('refreshManualStep', false)
        // 刷新用例、采样表格状态
        EventBus.$emit('refreshManualFn', false)
        EventBus.$emit('refreshManualSample', false)
        EventBus.$emit('refreshManualReportMsg', false)
        this.getStatusLoop()
      }, this.deviceDetail.deviceRefreshValue * 1000)
    },

    // 获取禁用状态
    getDisable(bVal) {
      this.isDisable = bVal
    },
    // 获取设备状态
    getDeviceStatus(statusObj) {
      this.deviceStatus = statusObj
      // 更新子组件步骤列表的设备状态
      if (this.$refs.stepComp != null) this.$refs.stepComp.UpdateDeviceStatus(statusObj)
      if (this.$refs.lowPComp != null) this.$refs.lowPComp.UpStatusFa(statusObj)
    },
    // 添加/编辑步骤后刷新步骤模块
    getSteps() {
      // console.log('刷新步骤模块 getSteps')
      // 获取设备 - 检测步骤 数据
      // 检测步骤列表 接口 get /test/plan/:plan/steps
      // 暂时没有分页，直接取999条
      const getUrl = `/test/plan/${this.deviceDetail.curPlanId}/steps?page=0&size=999`
      httpGet(getUrl).then((response) => {
        // console.log('刷新步骤模块 response=', response)
        this.deviceDetail.deviceCheckPlans = response.content
        // 刷新一次步骤状态
        this.stepActionClick('refresh')
      })

      // 销毁 添加/编辑 步骤窗口，避免数据残留
      this.editCheckStepData = {}
      this.deviceDetail.showModelAddStep = false
    },
    // 改变方案
    changePlan(curPlanId) {
      this.exampleUpdate = 'example-' + new Date().getTime()
      this.sampleUpdate = 'sample-' + new Date().getTime()
      this.sampleUpdate104 = 'sample104-' + new Date().getTime()
      this.checkStepsUpdate = 'checkSteps-' + new Date().getTime()
      // console.log('changePlan curPlanId=', curPlanId)
      // this.$set(this.deviceDetail, 'curPlanId', curPlanId)
      // 获取当前选中方案的suiteID
      const index = getOptionIndex(this.deviceDetail.devicePlanOptions, curPlanId)
      // console.log('changePlan index=', index)
      // console.log('changePlan this.devicePlanOptions=', this.deviceDetail.devicePlanOptions)
      this.$router.push({
        path: `/device/check?curPlanId=${curPlanId}&suiteId=${this.deviceDetail.devicePlanOptions[index].suiteId}&deviceId=${this.deviceDetail.deviceId}`
      })
    },
    // 提交
    submitPlan() {
      // console.log(`this.requestData=`, this.requestData)
      // 已经是最后一步
      const submitTableData = this.getSubmitTableRowData(this.requestData)
      // /test/project/:project/suites?id=999&id=998
      const editPath = `/test/project`
      // const editData = submitTableData
      editRow(editPath, submitTableData)
      // 已经是最后一步了
    },
    // 获取提交的行数据-公用
    // #TODO: 测试如果翻页，选取状态能否正常保存
    getSubmitTableRowData(rowData) {
      // console.log('   rowData=', rowData)
      let submitRowData = []
      // 组织出待提交数据
      submitRowData = {
        deviceId: rowData.deviceCurrentCheckValue,
        planId: rowData.deviceCurrentPlanValue
      }
      return submitRowData
    },
    // 控制按钮
    controlClick(actStr) {
      // console.log('controlAction 执行开始 actStr=', actStr)
      const postUrl = `/test/execute/${this.deviceDetail.curPlanId}/${actStr}`
      httpPostJson(postUrl).then((response) => {
        // console.log('controlAction 执行完成 rs=', response)
      })
    },
    // 刷新 这里是获取 检测状态 根据获取结果动态显示:
    //  检测状态： .title-tag
    controlRefresh() {
      // 接口 测试状态 /test/execute/:runner/state
      // :runner 3200000208
      const getUrl = `/test/execute/${this.deviceDetail.curPlanId}/state`
      httpGet(getUrl).then((response) => {
        // console.log('controlRefresh() 执行完成 response=', response)
        this.deviceStatus = response
        // 更新子组件步骤列表的设备状态
        if (this.$refs.stepComp != null) this.$refs.stepComp.UpdateDeviceStatus(response)
        if (this.$refs.lowPComp != null) this.$refs.lowPComp.UpStatusFa(response)
        // 设置禁用状态
        if (this.deviceStatus.state === 'RUNNING') {
          this.isDisable = true
        } else {
          this.isDisable = false
        }
      })
    },
    // 步骤控制 按钮
    stepActionClick(actStr) {
      // 设置图片点击效果
      this.clickEffect(actStr)
      if (actStr === 'refresh') {
        // 刷新状态
        const getUrl = `/test/execute/${this.deviceDetail.curPlanId}/progress`
        httpGet(getUrl).then((response) => {
          this.deviceDetail.deviceCheckPlans.forEach(item => {
            response.forEach(ritem => {
              if (item.id === ritem.id) {
                item.status = ritem.stateName
              }
            })
          })
          this.deviceCheckPlanUpdate = 'steps' + new Date().getTime()
        })
      } else {
        // 运行/停止
        const postUrl = `/test/execute/${this.deviceDetail.curPlanId}/step/${actStr}`
        httpPostJson(postUrl).then(response => {
          // 执行成功后刷新状态
          this.stepActionClick('refresh')
        })
      }
    },
    // 点击效果
    clickEffect(actStr) {
      // 设置点击特效 - 开始
      this.clickClass[`${actStr}`] = 'clicked'
      setTimeout(() => {
        // 延迟200毫秒更新样式
        this.clickClass[`${actStr}`] = 'default'
      }, 200)
    },
    // 对象 点击效果
    clickObjEffect(event) {
      // e.target.className = 'clicked'
      this.clickObj = event.currentTarget.parentElement
      this.clickObj.classList.add('clicked')
      setTimeout(() => {
        // 延迟200毫秒更新样式
        this.clickObj.classList.remove('clicked')
      }, 200)
    },
    // 添加步骤
    ModelAddStep() {
      // console.log('addCheckStep 添加步骤 开始')
      this.deviceDetail.showModelAddStep = true
    },
    // 关闭 model
    closeModel(modelName, modelShow) {
      // console.log('closeModel modelName=', modelName)
      // console.log('closeModel modelShow=', modelShow)
      switch (modelName) {
        case 'ModelAddStep':
          this.deviceDetail.showModelAddStep = modelShow
          break
        case 'ModelReport':
          this.deviceDetail.showModelReport = modelShow
          break
        default:
          // console.log('未获取到 modelName')
          break
      }
    },
    // 单条步骤 编辑
    singleEditClick(currentCheckStep, index) {
      this.editCheckStepData = currentCheckStep
      this.deviceDetail.showModelAddStep = true
    },
    // 单条步骤 操作按钮
    singleActionClick(currentCheckStep, actStr, e) {
      // 点击特效
      this.clickObjEffect(e)

      // e.currentTarget.parentElement.classList.add('clicked')
      // this.deviceDetail.deviceCheckPlans[index].singleActionStatus = actStr
      if (actStr === 'run') {
        this.singleActionRunId = currentCheckStep.id
      } else {
        this.singleActionRunId = '0'
      }

      // console.log('singleActionClick 单条步骤开始 currentCheckStep=', currentCheckStep)
      // console.log('singleActionClick 单条步骤开始 this.deviceDetail.deviceCheckPlans=', this.deviceDetail.deviceCheckPlans)
      singleAction(
        this.deviceDetail.curPlanId,
        currentCheckStep.id,
        actStr
      ).then((response) => {
        // 为高亮显示当前步骤，更新当前执行步骤id
        this.deviceDetail.currenPlanStepsId = currentCheckStep.id
        // this.stepActionClick('refresh')
        this.stepActionClick('refresh')
      })
    },
    // 清空定时器
    clearTimer() {
      // console.log('clearTimer started')
      this.deviceDetail.deviceRefreshValue = 0
      clearTimeout(this.timer)
      this.timer = null
    }
  }
}
</script>

<style lang="scss">
.example {
  .el-table {
    font-size: 12px;
  }
}
</style>
<style lang="scss" scoped>
.check-container {
  padding:10px 30px;
  background-color: #fff;
  position: relative;
  font-size: 16px;
  color: rgb(112, 112, 112);
  min-height: calc(100vh - 84px);
  .check-container-inner {
    border: 1px solid #ccc;
    padding: 5px 20px;
    .check-title {
      display: flex;
      font-size: 18px;
      color: #111;
      font-weight: bolder;
      justify-content: center;
      align-items: flex-end;
      .title-lable {
        font-size: 16px;
        font-weight: normal;
        margin-left: 10px;
        .state {
          font-size:12px;
          border-radius: 10%;
          padding: 1px;
          text-align: center;
        }
      }
    }
    .check-sub-title {
      display: flex;
      justify-content: center;
      padding: 10px 0;
      .sub-left {
        padding-right: 10px;
      }
    }
    .contorl-panel {
      .top {
        border: 1px #ccc solid;
        padding: 10px;
        .left {
          // display: flex;
        }
        .right {
          display: flex;
          align-items: center;
          height: 80px;
          // border: 1px solid #f00;
          justify-content: right;
          .play,
          .stop {
            padding-right: 10px;
          }
          .play,
          .stop,
          .refresh {
            cursor: pointer;
            .el-image {
              height: 50px;
            }
          }
          .refresh .el-image {
            height: 44px;
          }
        }
      }
      .main-left {
        padding: 20px 20px 0 0;
        font-size: 14px;
        .left-container {
          border: 1px solid #ccc;
          padding: 0 20px;
          .check-steps {
            display: flex;
            justify-content: space-between;
            padding: 20px 0;
            .check-steps-title {
              font-weight: bold;
            }
          }
          .check-buttons {
            display: flex;
            .play-all,.stop-all,.refresh-all {
              display: flex;
              align-items: center;
              padding-right: 16px;
              cursor: pointer;
              .icon {
                padding-left: 5px;
                .el-image {
                  height: 36px;
                }
              }
              .lable {
                white-space: nowrap;
              }
            }
          }
        }
        .check-item {
          border: 1px solid #ccc;
          margin-top: 10px;
          padding: 10px;
          background-color: #fbffff;
          border-radius: 5px;
          .check-item-title{
            padding-top: 10px;
          }
          .check-item-title,
          .check-item-control-title {
            span {
              font-weight: bold;
              color: #111;
            }
          }
          .check-item-control {
            display: flex;
            justify-content: space-between;
            align-items: center;
            .check-item-control-buttons {
              display: flex;
              align-items: center;
              justify-content: right;
              .check-item-edit,
              .check-item-play,
              .check-item-stop {
                cursor: pointer;
              }
              .el-image {
                height: 30px;
                margin-left: 10px;
              }
            }
          }
          .check-item-status {
            display: flex;
          }
        }
        .check-item.active {
          border: 1px solid #00706b;
          background-color: #f2fdfd;
        }
      }
      .main-right {
        font-size: 14px;
        padding: 20px 0 0 0;
        .main-right-container {
          padding: 0 20px;
          border: 1px solid #ccc;
        }
      }
    }
  }

  // 按钮图片物资公用样式
  .clicked {
    border-radius: 40%;
    filter: Alpha(opacity=50);
    border:4px solid transparent;
  }
  .default {
    filter: Alpha(opacity=100);
  }

  // 底部按钮
  .bottom-button {
    display: flex;
    justify-content: center;
    padding-bottom: 20px;
    .cancel-device {
      padding-right: 20px;
    }
  }
  // 按钮公用样式
  .dark-button {
    background-color: #00706b;
    border: 1px #00706b solid;
    color: #fff;
  }
  .light-button {
    color: #00706b;
    border: 1px #00706b solid;
  }
}
</style>
