<template>
  <custom-modal v-model="visible" :width="1280" title="Energy Calibration" :footer="null" destroy-on-close>
    <a-spin :spinning="isLoading">
      <div class="energy-calibration">
        <div class="left">
          <!-- Calibration Data -->
          <title-over-border title="Calibration Data">
            <div class="calibration-data">
              <a-form-model
                :colon="false"
                :labelCol="{
                  style: {
                    width: '70px',
                    textAlign: 'left',
                    flexShrink: 0
                  }
                }"
                :wrapperCol="{
                  style: {
                    flex: 1
                  }
                }"
              >
                <a-form-model-item label="Channel">
                  <a-input type="number" v-model="model.channel"></a-input>
                </a-form-model-item>
                <a-form-model-item label="Energy">
                  <a-input type="number" v-model="model.energy"></a-input>
                </a-form-model-item>
                <a-form-model-item :label="' '">
                  <a-button type="primary" @click="handleInsert">Insert</a-button>
                </a-form-model-item>
                <a-form-model-item :label="' '">
                  <a-button type="primary" @click="handleModify">Modify</a-button>
                </a-form-model-item>
                <a-form-model-item :label="' '">
                  <a-button type="primary" @click="handleDelete">Delete</a-button>
                </a-form-model-item>
              </a-form-model>
              <!-- 表格 -->
              <custom-table
                :columns="columns"
                :list="list"
                :pagination="false"
                size="small"
                :class="list.length ? 'has-data' : ''"
                :scroll="{ y: 182 }"
                :selectedRowKeys.sync="selectedRowKeys"
                :canDeselect="false"
                @rowClick="handleRowClick"
              ></custom-table>
              <!-- 表格结束 -->
              <div class="operators">
                <div>
                  <a-button type="primary">Call</a-button>
                  <a-button type="primary">Save</a-button>
                </div>
                <div>
                  <a-button type="primary" @click="handleApply">Apply</a-button>
                </div>
              </div>
            </div>
          </title-over-border>
          <!-- Equation -->
          <title-over-border class="mt-20" title="Equation">
            <div class="equation" v-html="equation"></div>
          </title-over-border>
          <!-- curve -->
          <title-over-border class="mt-20" title="curve">
            <div class="curve">
              <custom-chart :option="option" :opts="opts" />
            </div>
          </title-over-border>
        </div>
        <div class="right">
          <title-over-border title="Data Source" style="height: 100%">
            <div class="data-source">
              <div class="content">
                <div
                  class="item"
                  :class="item == currSelectedDataSource ? 'active' : ''"
                  v-for="(item, index) in dataSourceList"
                  :key="index"
                  @click="handleDataSourceClick(item)"
                >
                  {{ item }}
                </div>
              </div>
              <div class="footer mt-20">
                <a-button type="primary" @click="handleSetToCurrent">Set to Current</a-button>
                <div class="mt-20">{{ appliedDataSource }}</div>
              </div>
            </div>
          </title-over-border>
        </div>
      </div>
    </a-spin>
  </custom-modal>
</template>

<script>
import ModalMixin from '@/mixins/ModalMixin'
import TitleOverBorder from '../TitleOverBorder.vue'
import CustomChart from '@/components/CustomChart/index.vue'
import { getAction, postAction } from '@/api/manage'
import { cloneDeep } from 'lodash'
import { buildLineSeries } from '@/utils/chartHelper'
import SampleDataMixin from '../../SampleDataMixin'

const columns = [
  {
    title: 'Channel',
    dataIndex: 'channel'
  },
  {
    title: 'Energy(keV)',
    dataIndex: 'energy'
  },
  {
    title: 'Fit(keV)',
    dataIndex: 'fit'
  },
  {
    title: 'Delta(%)',
    dataIndex: 'delta'
  }
]

const initialOption = {
  grid: {
    top: 20,
    right: 20,
    bottom: 50,
    left: 70
  },
  title: {
    text: 'Channel',
    textStyle: {
      color: '#8FD4F8',
      fontSize: 14,
      fontWeight: 'normal'
    },
    right: 10,
    bottom: 0
  },
  tooltip: {
    trigger: 'axis',
    formatter: params => {
      const [x, y] = params[0].value
      const channel = parseInt(x)
      const energy = y.toFixed(3)
      return `<div class="channel">Channel: ${channel}</div>
              <div class="energy">Energy: ${energy}</div>`
    },
    className: 'figure-chart-option-tooltip'
  },
  xAxis: {
    min: 1,
    max: 'dataMax',
    axisLabel: {
      color: '#fff'
    },
    axisLine: {
      lineStyle: {
        color: '#fff'
      }
    },
    splitLine: {
      show: false
    }
  },
  yAxis: {
    axisLabel: {
      color: '#fff'
    },
    axisTick: {
      show: false
    },
    axisLine: {
      lineStyle: {
        color: '#fff'
      }
    },
    splitLine: {
      show: false
    },
    name: 'keV',
    nameLocation: 'center',
    nameGap: 50,
    nameTextStyle: {
      color: '#8FD4F8',
      fontSize: 14
    }
  },
  series: []
}

export default {
  components: { TitleOverBorder, CustomChart },
  mixins: [ModalMixin, SampleDataMixin],
  data() {
    this.columns = columns
    return {
      isLoading: false,
      equation: '',
      dataSourceList: [],
      list: [],
      option: cloneDeep(initialOption),
      selectedRowKeys: [],
      model: {},
      currSelectedDataSource: '',
      appliedDataSource: '',
      opts: {
        notMerge: true
      }
    }
  },
  methods: {
    async getData() {
      try {
        this.isLoading = true
        const { sampleId, inputFileName: fileName } = this.sampleData
        const { success, result, message } = await getAction('/gamma/energyCalibration', {
          sampleId,
          fileName
        })
        this.isLoading = false
        if (success) {
          console.log('%c [  ]-220', 'font-size:13px; background:pink; color:#bf2c9f;', result)
          const { list_dataSource } = result
          this.dataSourceList = list_dataSource
          this.currSelectedDataSource = list_dataSource[0]
          this.appliedDataSource = list_dataSource[0]

          this.handleResult(result)
        } else {
          this.$message.error(message)
        }
      } catch (error) {
        console.error(error)
      }
    },

    handleResult(result) {
      const { AllData, equation, param, table, uncert } = result
      // 有数据
      if (AllData) {
        const [linePoint, scatterPoint] = AllData
        this.equation = equation
        this.param = param
        this.uncert = uncert

        this.list = table
        this.generateTableId()

        const series = []
        series.push(
          buildLineSeries(
            'LineSeries',
            linePoint.pointlist.map(({ x, y }) => [x, y]),
            `rgb(${linePoint.color})`
          )
        )
        series.push({
          type: 'scatter',
          data: scatterPoint.pointlist.map(({ x, y }) => {
            return {
              value: [x, y],
              itemStyle: {
                color: scatterPoint.color,
                borderWidth: 0
              }
            }
          }),
          emphasis: {
            disabled: true
          },
          animation: false,
          zlevel: 20
        })
        this.option.series = series
      }
      // 没数据
      else {
        this.option.series = []
      }
    },

    beforeModalOpen() {
      this.selectedRowKeys = []
      this.getData()
    },

    // 表格单行点击
    handleRowClick(row) {
      this.model = cloneDeep(row)
    },

    // 插入
    handleInsert() {
      const centroid = parseFloat(this.model.channel)
      const energy = parseFloat(this.model.energy)

      if (Number.isNaN(centroid) || Number.isNaN(energy)) {
        this.$message.warn('Format is invalid.')
        return
      }

      if (centroid <= 100 || centroid >= 16342) {
        this.$message.warn('Centroid must be in the range of analysis!')
        return
      }

      let i,
        num = this.list.length
      for (i = 0; i < num; ++i) {
        const channel = this.list[i].channel
        if (Math.abs(channel - centroid) < 0.01) {
          this.$message.warn('The centroid has already existed!')
          return
        } else if (channel > centroid) {
          break
        }
      }

      this.list.splice(i, 0, {
        channel: centroid,
        energy
      })

      this.uncert.splice(i, 0, 0.5)

      this.selectedRowKeys = [i]
      this.generateTableId()

      this.recalculate()
    },

    // 生成table中数据的id，用以选中
    generateTableId() {
      this.list.forEach((item, index) => {
        item.id = index
      })
    },

    // 修改
    handleModify() {
      if (this.selectedRowKeys.length) {
        const centroid = parseFloat(this.model.channel)
        const energy = parseFloat(this.model.energy)

        if (Number.isNaN(centroid) || Number.isNaN(energy)) {
          this.$message.warn('Format is invalid.')
          return
        }

        if (centroid <= 100 || centroid >= 16342) {
          this.$message.warn('Centroid must be in the range of analysis!')
          return
        }

        const [currSelectedIndex] = this.selectedRowKeys

        this.list[currSelectedIndex].channel = centroid
        this.list[currSelectedIndex].energy = energy

        this.uncert[currSelectedIndex] = 0

        this.recalculate()
      }
    },

    // 删除
    handleDelete() {
      if (this.selectedRowKeys.length) {
        const [currSelectedIndex] = this.selectedRowKeys

        this.list.splice(currSelectedIndex, 1)
        this.uncert.splice(currSelectedIndex, 1)
        this.generateTableId()
        if (this.list.length) {
          const selectedKey = this.selectedRowKeys[0]
          if (selectedKey > this.list.length - 1) {
            this.selectedRowKeys[0] = selectedKey - 1
          }
        } else {
          this.selectedRowKeys = []
        }
        this.recalculate()
      }
    },

    // 重新计算
    async recalculate() {
      try {
        this.isLoading = true
        const { sampleId, inputFileName: fileName } = this.sampleData
        const { success, result, message } = await postAction('/gamma/changeDataEnergy', {
          sampleId,
          fileName,
          m_vCurCentroid: this.list.map(item => item.channel),
          m_vCurEnergy: this.list.map(item => item.energy),
          m_vCurUncert: this.uncert,
          m_curParam: this.param
        })
        if (success) {
          this.handleResult(result)
        } else {
          this.$message.error(message)
        }
      } catch (error) {
        console.error(error)
      } finally {
        this.isLoading = false
      }
    },

    // 应用
    async handleApply() {
      try {
        let curCalName = this.currSelectedDataSource
        // 如果沒选中以Input开头的，也就是选中了PHD之类的
        if (!curCalName.includes('Input')) {
          curCalName = `Input ${this.dataSourceList.filter(item => item.includes('Input')).length + 1}`
        }

        const { sampleId, inputFileName: fileName } = this.sampleData
        const { success, result, message } = await postAction('/gamma/applyDataEnergy', {
          m_vCurCentroid: this.list.map(item => item.channel),
          m_vCurEnergy: this.list.map(item => item.energy),
          m_vCurUncert: this.uncert,
          m_curParam: this.param,
          curCalName,
          sampleId,
          fileName
        })
        if (success) {
          this.dataSourceList.push(curCalName)
        } else {
          this.$message.error(message)
        }
      } catch (error) {
        console.error(error)
      }
    },

    // 右侧DataSource中的选项点击
    handleDataSourceClick(item) {
      this.currSelectedDataSource = item
    },

    handleSetToCurrent() {
      this.appliedDataSource = this.currSelectedDataSource
    }
  }
}
</script>

<style lang="less" scoped>
.energy-calibration {
  display: flex;

  .left {
    flex: 1;

    .calibration-data {
      display: flex;
      gap: 20px;

      .ant-form {
        width: 25%;

        ::v-deep {
          .ant-form-item {
            margin-bottom: 15px;

            &-label,
            &-control {
              line-height: 32px;
            }

            &:last-child {
              margin-bottom: 0;
            }
          }
        }

        .ant-btn {
          width: 100%;
        }
      }

      .ant-table-wrapper {
        width: 50%;

        &.has-data {
          ::v-deep {
            .ant-table-body {
              height: 182px;
              background-color: #06282a;
            }
          }
        }

        ::v-deep {
          .ant-table-placeholder {
            height: 183px;
            display: flex;
            justify-content: center;
            align-items: center;
          }
        }
      }

      .operators {
        width: 25%;
        display: flex;
        flex-direction: column;
        justify-content: space-between;

        .ant-select {
          width: 100%;
        }
        .ant-btn {
          width: 100%;

          &:last-child {
            margin-top: 10px;
          }
        }
      }
    }

    .equation {
      height: 40px;
      background-color: #1b5465;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .curve {
      height: 400px;
    }
  }

  .right {
    width: 20%;
    margin-left: 20px;

    .data-source {
      .content {
        height: 330px;
        background-color: #275466;
        overflow: auto;

        .item {
          height: 32px;
          line-height: 32px;
          padding: 0 5px;
          cursor: pointer;

          &.active {
            background-color: #296d81;
          }
        }
      }

      .footer {
        .ant-btn {
          width: 100%;
        }

        > div {
          text-align: center;
          height: 32px;
          line-height: 32px;
          background-color: #285367;
        }
      }
    }
  }
}

.mt-20 {
  margin-top: 20px;
}
</style>
