<template>
  <a-spin ref="container" :spinning="isLoading" :tip="tipMsg" :style="{ minHeight: '45px' }">
    <a-icon slot="indicator" :type="spinIcon" style="font-szie: 24px" :spin="spinIcon === 'loading'" />

    <a-alert v-show="topAlert.visible" :type="topAlert.type" :showIcon="topAlert.showIcon">
      <p slot="message" style="margin-bottom: 0px">
        <count-down
          style="font-size: 14px"
          v-if="topAlert.countDown"
          :target="new Date().getTime() + config.interval * 1000"
        />
        {{ topAlert.txt }}
      </p>
    </a-alert>
    <a-alert v-if="this.warnList.length === 0" message="尚无报警信息"></a-alert>
    <slick-list class="list" v-model="warnList" lockAxis="y">
      <slick-item class="list-item" v-for="(item, index) in warnList" :index="index" :key="index">
        <a-descriptions size="small" :column="descriptionColumn" bordered>
          <template slot="title"> </template>
          <a-descriptions-item label="井号">
            <div :class="{ breatheDiv: !item.canceled }">
              {{ item.jh }}
              &nbsp;&nbsp;
              <a @mousedown.stop="" @mouseup="cancelWarn(item)">
                <a-icon
                  :type="item.canceled ? 'eye-invisible' : 'eye'"
                  theme="twoTone"
                  :two-tone-color="item.canceled ? '#52c41a' : '#eb2f96'"
                />
                <template v-if="!item.canceled">取消关注</template>
              </a>
            </div>
          </a-descriptions-item>
          <a-descriptions-item label="查询时间"> {{ item.queryTime }} </a-descriptions-item>
          <a-descriptions-item label="发生时间"> {{ item.warnTime }} </a-descriptions-item>
          <a-descriptions-item label="异常类别" :span="preContentSpan"> {{ item.source }} </a-descriptions-item>
          <a-descriptions-item label="内容" :span="contentSpan">
            <j-ellipsis v-if="contentSpan === 1" :value="item.warnMsg" />
            <text-highlight v-else :queries="config.keyWordsCmb" :wholeWordMatch="true">
              {{ item.warnMsg }}
            </text-highlight>
          </a-descriptions-item>
        </a-descriptions>
      </slick-item>
    </slick-list>

    <a-modal
      title="重点关注-配置项"
      :width="720"
      :visible="configVisible"
      @cancel="handleCancel"
      :okButtonProps="{ style: { display: 'none' } }"
      @ok="handleOk"
      cancelText="关闭"
      destroyOnClose
      :maskClosable="false"
    >
      <a-form-model :model="config" :label-col="labelCol" :wrapper-col="wrapperCol">
        <a-form-model-item label="井号">
          <a-input v-model="config.jh" disabled />
        </a-form-model-item>
        <a-form-model-item label="坐标">
          <font slot="extra" style="color: #1890ff"> 提示：当坐标无数据时，无法进行复杂情况类型的预警 </font>
          <a-input-group compact>
            <a-input addon-before="X" disabled style="width: 120px" v-model="config.coordinate[0]" />

            <a-input addon-before="Y" disabled style="width: 120px; margin-left: 8px" v-model="config.coordinate[1]" />
          </a-input-group>
        </a-form-model-item>
        <a-form-model-item label="可用数据源">
          <template>
            <a-tag color="green" v-if="widgetItemData.wellRecord.ltd === 1">
              录井仪{{ `(${widgetItemData.wellRecord.ltdDay.replace(/-/g, '/')})` }}
            </a-tag>
            <template v-if="widgetItemData.wellRecord.ltd === 1 && widgetItemData.wellRecord.zjy === 1">
              &nbsp;
            </template>
            <a-tag color="cyan" v-if="widgetItemData.wellRecord.zjy === 1">
              钻井液{{ `(${widgetItemData.wellRecord.zjyDay.replace(/-/g, '/')})` }}
            </a-tag>
          </template>
        </a-form-model-item>
        <a-form-model-item>
          <font slot="extra" style="color: #1890ff"> 提示：预警需要数据支持，当无相应数据源时无法进行调用 </font>
          <span slot="label">
            报警来源&nbsp;
            <a-tooltip title="报警信息在配置更改后按新配置类型加载">
              <a-icon style="color: rgb(82, 196, 26)" type="question-circle" />
            </a-tooltip>
          </span>
          <a-checkbox-group v-model="config.type">
            <a-checkbox :disabled="!(config.typeEnable & 2)" value="1" name="type"> 复杂情况 </a-checkbox>
            <a-checkbox :disabled="!(config.typeEnable & 1)" value="2" name="type"> 钻井液溢漏 </a-checkbox>
            <a-checkbox :disabled="!(config.typeEnable & 4)" value="3" name="type"> 工程预警 </a-checkbox>
          </a-checkbox-group>
        </a-form-model-item>
        <a-form-model-item label="刷新间隔(秒)">
          <a-input-number v-model="config.interval" :min="20" :max="199" style="width: 120px"></a-input-number>
        </a-form-model-item>
        <a-form-model-item label="排序规则">
          <a-select v-model="config.sortType" style="width: 120px" @change="handleSortChange">
            <a-select-option value="timeDesc"> 时间降序 </a-select-option>
            <a-select-option value="timeAsc"> 时间升序 </a-select-option>
            <a-select-option value="keyAsc"> 关键字在前 </a-select-option>
          </a-select>
        </a-form-model-item>
        <a-form-model-item>
          <span slot="label">
            关键字&nbsp;
            <a-tooltip title="您可以在下拉框中选择或者在输入框内输入其他内容">
              <a-icon style="color: rgb(82, 196, 26)" type="question-circle" />
            </a-tooltip>
          </span>
          <a-select
            v-model="config.keyWordsCmb"
            mode="tags"
            style="width: 100%"
            placeholder="请输入或选择关键字"
            @change="handleChange"
          >
            <a-select-option v-for="(item, index) in config.keyWordsCmb" :key="index" :value="item">
              {{ item }}
            </a-select-option>
          </a-select>
        </a-form-model-item>
      </a-form-model>
    </a-modal>
  </a-spin>
</template>

<script>
import { SlickList, SlickItem } from 'vue-slicksort'
import elementResizeDetector from 'element-resize-detector'
import TextHighlight from 'vue-text-highlight'
import JEllipsis from '@/components/jeecg/JEllipsis'
import { mapState } from 'vuex'
import _ from 'lodash'
import vue from 'vue'
import warnApi from '@/api/warnApi'
import CountDown from '@/components/CountDown/CountDown'

const keysStoreKey = "KEYFOCUS_KEYWORDS"
function sortWarn (src, type, keyWords) {
  switch (type) {
    case 'timeDesc':
      return _.sortBy(src, ['queryTime'], ['desc'])
    case 'timeAsc':
      return _.sortBy(src, ['queryTime'], ['asc'])
    case 'keyAsc':
      return _.sortBy(src, [(p) => {
        let exist = false
        _.each(keyWords, k => {
          exist = p.includes(k)
          return !exist
        })
        return exist ? 99 : 0
      }, 'queryTime'], ['desc', 'desc'])
  }
}
export default {
  name: 'KeyFocus',
  components: {
    SlickList,
    SlickItem,
    TextHighlight,
    JEllipsis,
    CountDown
  },
  props: {
    widgetItemData: {
      type: Object,
      default: () => undefined
    }
  },
  data () {
    return {
      isLoading: false,
      tipMsg: '正在查询最新数据...',
      spinIcon: 'loading',
      topAlert: {
        visible: false,
        type: 'info',
        txt: '',
        showIcon: false,
        countDown: false
      },
      warnList: [],
      descriptionColumn: 1,
      preContentSpan: 1,
      contentSpan: 1,

      configVisible: false,
      labelCol: { span: 6 },
      wrapperCol: { span: 14 },
      config: {
        jh: '井号123',
        keyWordsCmb: [],
        type: [],
        typeEnable: 0,
        interval: 30,
        sortType: 'timeDesc',
        coordinate: ['', '']
      },
      configSnap: {}
    }
  },
  created () { },
  mounted () {
    const that = this
    const erd = elementResizeDetector()
    const breakPoints = { xxl: 1600, xl: 1200, lg: 992, md: 768, sm: 576, xs: -1 }
    const keys = Object.keys(breakPoints)
    const vals = { xxl: 4, xl: 4, lg: 4, md: 3, sm: 2, xs: 1 }
    const valsPreContent = { xxl: 2, xl: 2, lg: 2, md: 3, sm: 2, xs: 1 }
    const valsContent = { xxl: 4, xl: 4, lg: 4, md: 3, sm: 2, xs: 1 }
    erd.listenTo(this.$refs.container.$el, function (el) {
      that.$nextTick(function () {
        var px = el.offsetWidth
        let fitIndex = -1
        for (var p in breakPoints) {
          fitIndex++
          if (px >= breakPoints[p]) {
            break
          }
        }
        for (var k = fitIndex; k < keys.length; k++) {
          if (vals[keys[k]] > 0) {
            that.descriptionColumn = vals[keys[k]]
            that.preContentSpan = valsPreContent[keys[k]]
            that.contentSpan = valsContent[keys[k]]
            break
          }
        }
      })
    })

    if (!this.widgetItemData.wellRecord) {
      this.isLoading = true
      this.tipMsg = "尚未选择井，请关闭工具选择井号后重新打开"
      return
    }
    // zjy, fzqk, gc
    // 1 ,  2,    4
    if (this.widgetItemData.wellRecord.zjy) {
      this.config.typeEnable = 1
    }
    if (this.widgetItemData.wellRecord.ltd) {
      // TODO: 查询井坐标 并 决定可以进行报警的种类
      this.config.typeEnable += 4
      warnApi.queryWellCoordinate({ jh: this.widgetItemData.wellRecord.JH })
        .then(res => {
          if (res.result.exist) {
            this.config.typeEnable += 2
            this.config.coordinate = res.result.coor
          }
        }).catch(e => {
          this.message.info(e.message)
        })
    }


    const keysStored = vue.ls.get(keysStoreKey)
    if (keysStored) {
      this.config.keyWordsCmb = keysStored
    }

    this.config.jh = this.widgetItemData.wellRecord.JH

    this.setSourceEmptyTip()

    this.$nextTick(() => {
      setTimeout(() => {
        this.queryWarn(this)
      }, 300)
    })
  },
  computed: {
    ...mapState({
      warnTheme: state => state.app.warnTheme
    }),
    showContent () {
      return this.contentSpan > 1
    }
  },
  watch: {
    'config.type' (val) {
      if (val.length === 0) {
        this.setSourceEmptyTip()
      }
    }
  },
  methods: {
    executeFromParent (which, paras) {
      switch (which) {
        case 'SHOWCONFIG':
          this.configSnap = _.clone(this.config)
          this.configVisible = true
          break
        default:
          break
      }
    },
    handleOk () {
      vue.ls.set(keysStoreKey, this.config.keyWordsCmb)
      this.configVisible = false
      this.$emit('configChanged')
      if (this.config.type.length > 0) {
        this.$nextTick(() => {
          this.topAlert.visible = false
          this.queryWarn(this, false)
        })
      }
    },
    handleCancel () {
      // this.config = this.configSnap
      if (this.config.type.length > 0) {
        this.topAlert.visible = false
        this.queryWarn(this, false)
      }
      this.configVisible = false
    },
    cancelWarn (item) {
      item.canceled = true
    },
    showCountDown () {
      this.$nextTick(() => {
        this.topAlert = {
          visible: true,
          txt: '正在等待下次预警查询...',
          type: 'info',
          showIcon: false,
          countDown: true
        }
      })
    },
    handleSortChange () {
      sortWarn(this.warnList, this.config.sortType, this.config.keyWordsCmb)
    },
    showQueryTip () {
      this.topAlert = {
        visible: true,
        txt: '正在查询预警内容...',
        type: 'info',
        showIcon: true
      }
    },
    setSourceEmptyTip () {
      this.topAlert = {
        visible: true,
        txt: '请点击右上配置选择报警数据源',
        type: 'warning',
        showIcon: true
      }
    },
    pickLastZjyTime () {
      if (this.widgetItemData.wellRecord.zjy === 1) {
        if (this.warnList.length === 0) {
          return null
        }
        let last = ''
        this.warnList.map(p => {
          if (p.warnTime > last) {
            last = p.warnTime
          }
        })
        return last
      }
      return null
    },
    queryWarn (that, doNext = true) {
      if (that._isDestroyed) {
        return
      }
      if (that.config.type.length === 0) {
        doNext && _.delay(this.queryWarn, that.config.interval * 1000, that)
        return
      }
      const queryBody = {
        jh: that.widgetItemData.wellRecord.JH,
        checkZjy: that.config.type.indexOf('2') >= 0,
        checkFzqk: that.config.type.indexOf('1') >= 0,
        checkGc: that.config.type.indexOf('3') >= 0,
        zjyLastType: '',
        zjyLastTime: this.pickLastZjyTime(),
        coorX: that.config.coordinate[0],
        coorY: that.config.coordinate[1]
      }
      if (!queryBody.coorX) {
        queryBody.coorX = '-1'
      }
      if (!queryBody.coorY) {
        queryBody.coorY = '-1'
      }
      that.showQueryTip()
      warnApi.queryFocusWarn(queryBody)
        .then(res => {
          const zjy = _.get(res.result, 'zjy', null)
          const fzqk = _.get(res.result, 'fzqk', null)
          const gc = _.get(res.result, 'gc', null)
          function filterWarn (list) {
            let addCount = 0
            list.map(p => {
              const exist = _.find(that.warnList, k1 => {
                return k1.key === p.key
              })
              if (!exist) {
                that.warnList.push({
                  key: p.key,
                  jh: p.jh,
                  canceled: false,
                  queryTime: p.requestStart,
                  warnTime: p.warnTime,
                  source: p.source,
                  catogary: p.catogary,
                  warnMsg: p.bjnr
                })
                addCount++
              }
            })
            return addCount
          }
          const a1 = zjy && filterWarn(zjy)
          const a2 = fzqk && filterWarn(fzqk)
          const a3 = gc && filterWarn(gc)

          if (a1 && a2 && a3) {
            that.warnList = sortWarn(that.warnList, that.config.sortType, that.config.keyWordsCmb)
          }
          that.showCountDown()
          doNext && _.delay(this.queryWarn, that.config.interval * 1000, that)
        }).catch(e => {
          that.showCountDown()
          that.$notification.warning({ message: `重点关注工具-${that.widgetItemData.wellRecord.JH}查询时出错`, description: e.message })
          doNext && _.delay(this.queryWarn, that.config.interval * 1000, that)
        })
    }
  }
}
</script>

<style lang="less" scoped>
ul {
  list-style-type: none;
  padding: 0;
}

li {
  padding: 10px;
}

pre {
  width: 80%;
  max-width: 500px;
  border-radius: 20px;
  padding: 20px;
  background: #fefefe;
}

// Base styles
.list {
  width: 100%;
  margin: 0 auto;
  padding: 0;
  overflow: auto;
  background-color: #f3f3f3;
  border: none;
  border-radius: 3;
}

.list-item {
  // display: flex;
  align-items: center;
  width: 100%;
  padding: 20px;
  background-color: #fff;
  border-bottom: 1px solid #edb2b2;
  box-sizing: border-box;
  user-select: none;

  color: #333;
  font-weight: 400;
}

// Stylized
.stylizedList {
  position: relative;
  z-index: 0;
  background-color: #f3f3f3;
  border: 1px solid #efefef;
  border-radius: 3px;
  outline: none;
}
.stylizedItem {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0 20px;
  background-color: #fff;
  border-bottom: 1px solid #efefef;
  box-sizing: border-box;
  user-select: none;

  color: #333;
  font-weight: 400;
}

// Drag handle
.handle {
  display: block;
  width: 18px;
  height: 18px;
  background-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50"><path d="M 0 7.5 L 0 12.5 L 50 12.5 L 50 7.5 L 0 7.5 z M 0 22.5 L 0 27.5 L 50 27.5 L 50 22.5 L 0 22.5 z M 0 37.5 L 0 42.5 L 50 42.5 L 50 37.5 L 0 37.5 z" color="black"></path></svg>');
  background-size: contain;
  background-repeat: no-repeat;
  opacity: 0.25;
  margin-right: 20px;
  cursor: row-resize;
}

// Horizontal list
.horizontalList {
  display: flex;
  width: 600px;
  height: 300px;
  white-space: nowrap;
}

.horizontalItem {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 200px;
  border-right: 1px solid #efefef;
  border-bottom: 0;
}

// Grid
.grid {
  display: block;
  width: 130 * 4px;
  height: 350px;
  white-space: nowrap;
  border: 0;
  background-color: transparent;
}

.gridItem {
  float: left;
  width: 130px;
  padding: 8px;
  background: transparent;
  border: 0;

  .wrapper {
    display: flex;
    align-items: center;
    justify-content: center;

    width: 100%;
    height: 100%;
    background: #fff;
    border: 1px solid #efefef;

    font-size: 28px;

    span {
      display: none;
    }
  }
}

// Nested
.category {
  height: auto;

  .categoryHeader {
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
    padding: 10px 14px;
    background: #f9f9f9;
    border-bottom: 1px solid #efefef;
  }

  .categoryList {
    height: auto;
  }
}

// Divider
.divider {
  padding: 10px 20px;
  background: #f9f9f9;
  border-bottom: 1px solid #efefef;
  text-transform: uppercase;
  font-size: 14px;
  color: #333;
}

// Helper styles
.helper {
  box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.2), 0 -5px 5px -5px rgba(0, 0, 0, 0.2);
}
.stylizedHelper {
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
  background-color: rgba(31, 136, 255, 0.8);
  color: #fff;
  cursor: row-resize;
  border: 1px solid white;

  &.horizontalItem {
    cursor: col-resize;
  }
  &.gridItem {
    background-color: transparent;
    white-space: nowrap;
    box-shadow: none;

    .wrapper {
      background-color: rgba(255, 255, 255, 0.8);
      box-shadow: 0 0 7px rgba(0, 0, 0, 0.15);
    }
  }
}

.shrinkedHelper {
  height: 20px !important;
}

/deep/ .ant-descriptions-title {
  margin-bottom: 0px;
}
/deep/ .ant-input:disabled {
  color: rgba(0, 0, 0, 0.85);
}

.breatheDiv {
  border: 1px solid #ccc;
  text-align: center;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
  overflow: hidden;
  -webkit-animation-timing-function: ease-in-out;
  -webkit-animation-name: breathe;
  -webkit-animation-duration: 1500ms;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-direction: alternate;
  animation-timing-function: ease-in-out;
  animation-name: breathe;
  animation-duration: 1500ms;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

@-webkit-keyframes breathe {
  0% {
    opacity: 0.4;
    box-shadow: 0 1px 2px rgba(223, 171, 0, 0.4), 0 1px 1px rgba(0, 147, 223, 0.1) inset;
  }

  100% {
    opacity: 1;
    border: 1px solid rgba(235, 71, 59, 0.7);
    box-shadow: 0 1px 30px #df5200, 0 1px 20px #df3f00 inset;
  }
}
@keyframes breathe {
  0% {
    opacity: 0.4;
    box-shadow: 0 1px 2px rgba(223, 171, 0, 0.4), 0 1px 1px rgba(0, 147, 223, 0.1) inset;
  }

  100% {
    opacity: 1;
    border: 1px solid rgba(235, 71, 59, 0.7);
    box-shadow: 0 1px 30px #df5200, 0 1px 20px #df3f00 inset;
  }
}

/deep/ .ant-descriptions-item-label {
  min-width: 90px;
}
</style>
