<template>
  <div class="beta-gamma-analysis">
    <a-spin :spinning="isLoading">
      <!-- 二级交互栏 -->
      <div class="spectrum-analysis-sub-operators">
        <pop-over-with-icon placement="bottomLeft">
          Detailed-Information
          <beta-gamma-detailed-infomation slot="content" :data="spectrumData" />
        </pop-over-with-icon>
        <custom-select
          v-model="spectraType"
          :options="SampleType"
          @change="changeChartByType"
          style="width: 246px"
          class="sample-select"
        ></custom-select>
        <div class="spectrum-analysis-sub-operators-roi" v-for="(_, index) in 4" :key="index">
          <div class="spectrum-analysis-sub-operators-roi-name" :style="{ color: ROIColors[index] }">
            ROI{{ index + 1 }}
          </div>
          <a-input-group>
            <a-input
              type="number"
              v-model="roiParamList[index][0]"
              class="spectrum-analysis-sub-operators-roi-input"
              placeholder="Beta1"
              :disabled="spectraType !== 'sample'"
            />
            <span class="spectrum-analysis-sub-operators-roi-split">,</span>
            <a-input
              type="number"
              v-model="roiParamList[index][1]"
              class="spectrum-analysis-sub-operators-roi-input"
              placeholder="Beta2"
              :disabled="spectraType !== 'sample'"
            />
          </a-input-group>
        </div>
        <a-button
          type="primary"
          class="spectrum-analysis-sub-operators-button"
          :disabled="spectraType !== 'sample'"
          @click="handleUpdate"
        >
          Update
        </a-button>
      </div>
      <!-- 二级交互栏结束 -->

      <!-- 主体部分 -->
      <div class="beta-gamma-analysis-main">
        <!-- 左侧图表部分 -->
        <div class="beta-gamma-analysis-main-left">
          <beta-gamma-chart-container>
            <template slot="title"> Beta-Gamma Spectrum: {{ currSpectrum }} </template>
            <beta-gamma-spectrum
              ref="betaChartRef"
              :betaEnergyData="betaEnergyData"
              :gammaEnergyData="gammaEnergyData"
              :isLoading.sync="isLoading"
              :disabled="spectraType !== 'sample'"
              @boundaryChange="handleBoundaryChange"
              @open-modal="handleOpenModal"
            />
          </beta-gamma-chart-container>
        </div>
        <!-- 左侧图表结束 -->
        <!-- 右侧开始 -->
        <div class="beta-gamma-analysis-main-right">
          <beta-gamma-chart-container>
            <template slot="title"> Beta-Gated-Gamma-Spectrum </template>
            <roi-limits
              ref="RoiChartRef"
              :ROILists="ROILists"
              :ROIAnalyzeLists="ROIAnalyzeLists"
              :gammaEnergyData="gammaEnergyData"
            />
          </beta-gamma-chart-container>
          <!-- 底部显示 -->
          <div class="beta-gamma-analysis-main-bottom">
            <div class="beta-gamma-analysis-main-bottom-left">
              <beta-gamma-chart-container>
                <template slot="title"> Result display </template>
                <result-display-beta :data="resultDisplay" @sendFlag="handleGetFlag"></result-display-beta>
              </beta-gamma-chart-container>
            </div>
          </div>
          <!-- 底部显示结束 -->
        </div>
        <!-- 右侧结束 -->
      </div>
      <!-- 主体部分结束 -->
    </a-spin>

    <!-- Gamma 按钮的弹窗 -->
    <gamma-modal ref="gammaModalRef" />
    <!-- Gamma 按钮的弹窗结束 -->
    <!-- Beta 按钮的弹窗 -->
    <beta-modal ref="betaModalRef" />
    <!-- Beta 按钮的弹窗结束 -->

    <!-- Arr和RRR弹窗 -->
    <self-station-arr-rrr-modal ref="ARR_RRRModalRef" />
    <!-- Arr和RRR弹窗结束 -->

    <!-- Spectrum弹窗 -->
    <self-station-spectrum-modal ref="spectrumModalRef" />
    <!-- Spectrum弹窗结束 -->

    <!-- Peak Infomation弹窗 -->
    <self-station-peak-infomation ref="peakInfoModalRef" />
    <!-- Peak Infomation弹窗结束 -->

    <!-- 自动分析日志弹窗 -->
    <self-station-automatic-analysis-log-modal ref="autoAnalysisLogRef" />
    <!-- 自动分析日志弹窗结束 -->

    <!-- BgLog -->
    <self-station-bg-log-viewer ref="bgLogViewerRef" />
    <!-- BgLog结束 -->
  </div>
</template>

<script>
import PopOverWithIcon from './components/SubOperators/PopOverWithIcon.vue'
import BetaGammaDetailedInfomation from './components/SubOperators/BetaGammaDetailedInfomation.vue'
import BetaGammaQcFlags from './components/SubOperators/BetaGammaQcFlags.vue'
import CustomSelect from '@/components/CustomSelect/index.vue'
import BetaGammaChartContainer from './components/BetaGammaChartContainer.vue'
import ResultDisplayBeta from './components/ResultDisplay-Beta.vue'
import BetaGammaSpectrum from './components/BetaGammaSpectrum.vue'
import RoiLimits from './components/RoiLimits/RoiLimits.vue'
import RoiParam from './components/RoiParam.vue'
import axios from 'axios'
import store from '@/store/'
import { getAction, postAction, putAction } from '../../api/manage'
import { addSampleData, getSampleData, updateSampleData } from '@/utils/SampleStore'
import { cloneDeep } from 'lodash'
import GammaModal from './components/Modals/SelfStation/GammaModal.vue'
import BetaModal from './components/Modals/SelfStation/BetaModal.vue'
import SelfStationArrRrrModal from './components/Modals/SelfStation/SelfStationArrRrrModal.vue'
import SelfStationSpectrumModal from './components/Modals/SelfStation/SelfStationSpectrumModal.vue'
import SelfStationPeakInfomation from './components/Modals/SelfStation/SelfStationPeakInfomation.vue'
import SelfStationAutomaticAnalysisLogModal from './components/Modals/SelfStation/SelfStationAutomaticAnalysisLogModal.vue'
import SelfStationBgLogViewer from './components/Modals/SelfStation/SelfStationBGLogViewer.vue'

const SampleType = [
  {
    label: 'Sample Data',
    value: 'sample',
  },
  {
    label: 'DetBg Data',
    value: 'det',
  },
  {
    label: 'QC Data',
    value: 'qc',
  },
]

const InitialRoiParamList = new Array(4).fill([0, 0])

const ROIColors = ['#16d5e6', '#34a1ff', '#66e411', '#fdaa1a']

export default {
  components: {
    PopOverWithIcon,
    BetaGammaDetailedInfomation,
    BetaGammaQcFlags,
    CustomSelect,
    BetaGammaChartContainer,
    ResultDisplayBeta,
    BetaGammaSpectrum,
    RoiLimits,
    RoiParam,
    GammaModal,
    BetaModal,
    SelfStationArrRrrModal,
    SelfStationSpectrumModal,
    SelfStationPeakInfomation,
    SelfStationAutomaticAnalysisLogModal,
    SelfStationBgLogViewer,
  },
  props: {
    sample: {
      type: Object,
    },
    sampleList: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    this.SampleType = SampleType
    this.ROIColors = ROIColors

    return {
      currSpectrum: 'Sample',
      isLoading: false,
      spectrumData: {}, // Detailed Infomation 信息
      spectraType: 'sample',
      gammaEnergyData: [],
      betaEnergyData: [],
      ROILists: [],
      ROIAnalyzeLists: [],
      roiParamList: cloneDeep(InitialRoiParamList),
      sampleDetail: {},
      resultDisplay: [],
      timerStamp: Date.now(),
    }
  },
  watch: {
    sample: {
      async handler(newVal, oldVal) {
        const sampleData = getSampleData(newVal.inputFileName)
        if (sampleData) {
          const { data, from } = sampleData
          this.sampleDetail = data
          this.changeChartByType('sample')
          if (from == 'db') {
            this.sampleDetail = data
          }
          this.ROIAnalyzeLists = data.ROIAnalyzeLists || []
        } else {
          if (newVal.sampleId) {
            this.getDetailFromDB()
          } else {
            this.getDetailFromFile()
          }
          this.ROIAnalyzeLists = []
        }
      },
      immediate: true,
      deep: true,
    },
  },
  created() {
    this.$bus.$on('selfRefresh', this.handleRefresh)
    this.$bus.$on('selfAccept', this.handleAccept)
  },
  beforeDestroy() {
    this.cancelLastRequest()
    this.$bus.$on('selfRefresh', this.handleRefresh)
    this.$bus.$off('selfAccept', this.handleAccept)
  },
  methods: {
    // 从分析或来自db的谱信息拿到分析结果列表
    getROIAnalyzeListsFromResult(sampleData) {
      const arr = []
      for (let index = 1; index <= 4; index++) {
        const k = `ROI${index}`
        arr.push(sampleData[k])
      }
      return arr
    },

    // 分析当前谱
    async getAnalyzeCurrentSpectrum() {
      if (this.isLoading) {
        return
      }

      try {
        const { inputFileName } = this.sample
        const userId = store.getters.userInfo.id
        this.isLoading = true

        const formData = new FormData()
        formData.append('fileName', inputFileName)
        formData.append('processKey', `${userId}_${this.timerStamp}`)
        const { success, result, message } = await postAction('/selfStation/Reprocessing', formData)
        if (success) {
          const analyseList = this.getROIAnalyzeListsFromResult(result)
          this.ROIAnalyzeLists = analyseList
          updateSampleData({
            inputFileName,
            key: 'ROIAnalyzeLists',
            data: analyseList,
          })

          this.resultDisplay = result.XeData
        } else {
          const arr = message.split('\n')
          this.$warning({
            title: 'Warning',
            content: () => arr.map((text) => <div>{text}</div>),
          })
        }
      } catch (error) {
        console.error(error)
      } finally {
        this.isLoading = false
      }
    },

    // 分析全部
    getAnalyzeAllSpectrum() {
      this.$message.warning('尚未实现该功能')
    },

    // 点击Update
    async handleUpdate() {
      const hasEmpty = this.roiParamList.some(
        ([startChannel, endChannel]) => (!startChannel && startChannel != '0') || (!endChannel && endChannel != '0')
      )
      if (hasEmpty) {
        this.$message.warning('Channel cannot be null')
        return
      }

      const hasNegative = this.roiParamList.some(([startChannel, endChannel]) => startChannel < 0 || endChannel < 0)
      if (hasNegative) {
        this.$message.warning('Channel cannot be negative')
        return
      }

      try {
        this.isLoading = true
        const params = this.roiParamList.map(([startChannel, endChannel], index) => ({
          startChannel,
          endChannel,
          roiNum: index + 1,
        }))

        const { inputFileName } = this.sample
        const userId = store.getters.userInfo.id

        const formData = new FormData()
        formData.append('roiParams', JSON.stringify(params))
        formData.append('fileName', inputFileName)
        formData.append('processKey', `${userId}_${this.timerStamp}`)
        const { success, result, message } = await postAction('/selfStation/Reprocessing', formData)

        if (success) {
          for (let index = 0; index < 4; index++) {
            const key = `ROI${index + 1}`
            const value = result[key]
            if (value) {
              this.$set(this.ROIAnalyzeLists, index, value)
            }
          }
          updateSampleData({
            inputFileName,
            key: 'ROIAnalyzeLists',
            data: cloneDeep(this.ROIAnalyzeLists),
          })

          this.$refs.betaChartRef.setBoundaryList(cloneDeep(this.roiParamList))
          const updateKeys = ['One', 'Two', 'Three', 'Four']
          updateKeys.forEach((updateKey, index) => {
            const innerKeys = ['Start', 'Stop']
            innerKeys.forEach((innerKey, ind) => {
              const realKey = `ROI${updateKey}${innerKey}`
              updateSampleData({
                inputFileName,
                key: `sample.${realKey}`,
                data: this.roiParamList[index][ind],
              })
            })
          })
        } else {
          this.isLoading = false
          const arr = message.split('\n')
          this.$warning({
            title: 'Warning',
            content: () => arr.map((text) => <div>{text}</div>),
          })
        }
      } catch (error) {
        console.error(error)
      } finally {
        this.isLoading = false
      }
    },

    async getDetailFromFile() {
      this.spectraType = this.SampleType[0].value
      const { inputFileName, detFileName, qcFileName } = this.sample
      let params = {
        sampleFileName: inputFileName,
        detFileName: detFileName,
        qcFileName: qcFileName,
      }
      try {
        this.isLoading = true
        this.cancelLastRequest()
        const cancelToken = this.createCancelToken()
        const { success, result, message } = await getAction('/selfStation/loadFromFile', params, cancelToken)
        if (success) {
          addSampleData({
            inputFileName,
            data: result,
            from: 'file',
          })
          this.sampleDetail = result
          this.changeChartByType('sample')
          this.isLoading = false
        } else {
          this.$message.error(message)
          this.isLoading = false
        }
      } catch (error) {
        console.error(error)
        const isCancel = axios.isCancel(error)
        if (!isCancel) {
          this.isLoading = false
        }
      }
    },

    // 获取样品详情
    async getDetailFromDB() {
      const { dbName, sampleId, analyst, inputFileName } = this.sample
      try {
        this.cancelLastRequest()
        this.isLoading = true
        const cancelToken = this.createCancelToken()

        const { success, result, message } = await getAction(
          '/selfStation/loadFromDB',
          {
            dbName,
            sampleId,
            analyst,
          },
          cancelToken
        )
        if (success) {
          addSampleData({
            inputFileName,
            data: result,
            from: 'db',
          })

          const analyseList = this.getROIAnalyzeListsFromResult(result.sample)
          this.ROIAnalyzeLists = analyseList
          updateSampleData({
            inputFileName,
            key: 'ROIAnalyzeLists',
            data: analyseList,
          })

          this.sampleDetail = result
          this.changeChartByType('sample')
          this.isLoading = false
        } else {
          this.$message.error(message)
          this.isLoading = false
        }
      } catch (error) {
        console.error(error)
        const isCancel = axios.isCancel(error)
        if (!isCancel) {
          this.isLoading = false
        }
      }
    },

    changeChartByType(val) {
      const currSampleDetail = this.sampleDetail[this.spectraType]
      if (!currSampleDetail) {
        this.$message.warning(`No ${this.spectraType} spectrum file!`)
        this.$nextTick(() => {
          this.spectraType = this.prevSpectraType
        })
        return
      }

      this.prevSpectraType = val

      if (val == 'sample') {
        this.currSpectrum = 'Sample'
        this.ROIAnalyzeLists = this.sampleDetail.ROIAnalyzeLists || []
      } else {
        this.ROIAnalyzeLists = []
      }
      if (val == 'detBg') this.currSpectrum = 'Det'
      if (val == 'qc') this.currSpectrum = 'QC'
      this.roiParamList = cloneDeep(InitialRoiParamList)
      this.ROILists = []
      const {
        spectrumData,
        betaEnergyData,
        gammaEnergyData,
        histogramDataList,
        ROIOneList,
        ROITwoList,
        ROIThreeList,
        ROIFourList,
        ROIOneStart,
        ROIOneStop,
        ROITwoStart,
        ROITwoStop,
        ROIThreeStart,
        ROIThreeStop,
        ROIFourStart,
        ROIFourStop,
      } = currSampleDetail

      this.spectrumData = spectrumData

      const boundaryList = [
        [ROIOneStart, ROIOneStop],
        [ROITwoStart, ROITwoStop],
        [ROIThreeStart, ROIThreeStop],
        [ROIFourStart, ROIFourStop],
      ]

      this.roiParamList = cloneDeep(boundaryList)
      this.$nextTick(() => {
        this.$refs.betaChartRef.setBoundaryList(boundaryList)
        this.$refs.betaChartRef.setData(histogramDataList)
      })
      this.gammaEnergyData = gammaEnergyData
      this.betaEnergyData = betaEnergyData
      this.ROILists = [ROIOneList, ROITwoList, ROIThreeList, ROIFourList]
      this.$bus.$emit('selfAnalyzeSampleTypeChange', val)
    },
    cancelLastRequest() {
      if (this._cancelToken && typeof this._cancelToken == 'function') {
        this._cancelToken()
      }
    },

    createCancelToken() {
      const cancelToken = new axios.CancelToken((c) => {
        this._cancelToken = c
      })
      return cancelToken
    },
    handleGetFlag(val, obj) {
      this.resultDisplay.forEach((item) => {
        if (item.nuclideName === obj.nuclideName) {
          item.nidFlag = val ? 1 : 0
        }
      })
    },

    resize() {},

    // 矩形框范围改变
    handleBoundaryChange(evt) {
      const { index, start, end } = evt
      this.$set(this.roiParamList, index, [start, end])
      this.$refs.betaChartRef.setBoundaryList(cloneDeep(this.roiParamList))
    },

    // 从分析工具刷新部分数据
    handleRefresh(data, index) {
      this.ROIAnalyzeLists[index] = this.$set(this.ROIAnalyzeLists, index, data)

      const { inputFileName } = this.sample
      updateSampleData({
        inputFileName,
        key: 'ROIAnalyzeLists',
        data: this.ROIAnalyzeLists,
      })
    },

    // 分析工具Accept时刷新部分数据
    handleAccept(data, index) {
      const {
        allData,
        peak,
        shadowChannelChart,
        shadowEnergyChart,
        shapeChannelData,
        shapeEnergyData,
        barChart,
        BaseCtrls,
      } = data

      this.ROIAnalyzeLists[index] = this.$set(this.ROIAnalyzeLists, index, {
        allData,
        peak,
        shadowChannelChart,
        shadowEnergyChart,
        shapeChannelData,
        shapeEnergyData,
        barChart,
        BaseCtrls,
      })

      const { inputFileName } = this.sample
      updateSampleData({
        inputFileName,
        key: 'ROIAnalyzeLists',
        data: this.ROIAnalyzeLists,
      })
    },

    // 打开Gamma或Beta弹窗
    handleOpenModal(index) {
      const currSampleDetail = this.sampleDetail[this.spectraType]
      if (!currSampleDetail) {
        this.$message.warning(`No ${this.spectraType} spectrum file!`)
        return
      }
      if (index == 0) {
        this.$refs.gammaModalRef.open(currSampleDetail.gSpectrum, currSampleDetail.gammaEnergyData)
      } else if (index == 1) {
        this.$refs.betaModalRef.open(currSampleDetail.bSpectrum, currSampleDetail.betaEnergyData)
      }
    },

    // 保存当前谱到db
    async saveCurrentToDB() {
      if (!this.ROIAnalyzeLists || !this.ROIAnalyzeLists.length) {
        throw new Error('Please Analyse Spectrum First')
      }
      const { inputFileName: fileName } = this.sample
      const { success, message, result } = await getAction('/selfStation/saveToDB', {
        fileName,
      })
      if (success) {
        Object.entries(result).forEach(([k, v]) => {
          // 更新缓存中的DetailedInfomation数据
          updateSampleData({
            inputFileName: fileName,
            key: `${k}.spectrumData`,
            data: v,
          })
        })

        this.spectrumData = result[this.spectraType]
      } else {
        throw new Error(message)
      }
    },

    // 显示ARR或RRR弹窗
    showArrRRRModal(type) {
      this.$refs.ARR_RRRModalRef.show(type)
    },

    showSpectrumModal() {
      this.$refs.spectrumModalRef.show()
    },

    showPeakInfoModal() {
      this.$refs.peakInfoModalRef.show()
    },

    showAutomaticAnalysisLog() {
      this.$refs.autoAnalysisLogRef.show()
    },

    showBgLogViewer() {
      this.$refs.bgLogViewerRef.show()
    },
  },
}
</script>

<style lang="less" scoped>
.beta-gamma-analysis {
  height: 100%;

  .ant-spin-nested-loading {
    height: 100%;

    ::v-deep {
      .ant-spin-container {
        height: 100%;
      }
    }
  }

  .sample-select {
    ::v-deep {
      .ant-select-selection {
        background-color: transparent !important;
        color: #ade6ee;
      }
    }
  }

  &-main {
    height: calc(100% - 65px);
    display: flex;
    gap: 30px;
    overflow: auto hidden;

    &-left {
      flex: 768;
    }

    &-right {
      flex: 1068;
      .betagamma-chart {
        height: calc(100% - 200px);
      }
    }

    &-bottom {
      height: 194px;
      overflow: auto hidden;

      &-left {
        flex: 1;
      }

      &-right {
        flex: 1;
      }
    }
  }
}

// 二级操作栏开始
.spectrum-analysis-sub-operators {
  flex-shrink: 0;
  margin-bottom: 19px;
  display: flex;
  gap: 11px;
  flex-wrap: nowrap;
  overflow: auto;
  height: 46px;
  align-items: center;
  font-family: Microsoft Yahei;

  .pop-over-with-icon {
    height: 32px;
    flex-shrink: 0;

    &:nth-child(1) {
      width: 224px;
    }

    &:nth-child(3) {
      width: 125px;
    }
  }

  &-roi {
    display: flex;
    align-items: center;

    &-name {
      padding: 5px 10px;
    }

    .ant-input-group {
      display: flex;
      background-color: #04414d;
      border: solid 1px #0b8c82;
    }

    &-input {
      width: 80px;
      text-align: center;
      border: 0;
      background: transparent;
    }

    &-split {
      width: 5px;
    }
  }

  &-button {
    text-align: center;
    height: 32px;
    line-height: 32px;
    min-width: 94px;
    padding: 0 10px;
    font-size: 16px;
    margin-left: 16px;
    cursor: pointer;

    &[disabled] {
      color: #fff;
      background-color: #1397a3;
      cursor: not-allowed;
    }
  }
}

// 二级操作栏结束
</style>