<template>
  <div id="app">
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view> 
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>
    <van-popup :close-on-click-overlay="false" get-container="body" v-model="network" :style="{ width: '324px' }">
      <network/>
    </van-popup>
    <van-popup :close-on-click-overlay="false" get-container="body" v-model="abnormalPop" round position="bottom">
      <abnormal v-if="abnormalPop" />
    </van-popup>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
import { openSubscribe, updateSubscribe } from "@/api/subscribe";
import { getParams, getApiParams } from "@/api/app";
import WebSocketClient from "@/utils/socket";
import { getProductList } from "@/api/product";
import { setSession } from "@/utils/sessionStorage";
import bus from '@/utils/bus'
import tradeAssets from "@/mixins/tradeAssets";
import { getCookie } from "@/utils/cookie";
import network from "@/components/network";
import abnormal from "@/components/abnormal";
export default {
  name: 'App',
  mixins: [tradeAssets],
  components: {
    network,
    abnormal
  },
  data () {
    return {
      webSocket: null,
      productDataObj: {},
      timerSign: 0,
      socketTimer: null,
      waitList: [],
      abnormalPopSign: false
    }
  },
  provide() {
    return {
      getproductDataObj: () => this.productDataObj,
    }
  },
  watch: {
    '$route'() {
      this.abnormalPopSign = false
      if (!this.$route.meta.socket) {
        this.webSocket && this.webSocket.close();
        clearInterval(this.socketTimer)
        this.socketTimer = null
        this.$store.commit('setUpdateSymbolList', [])
      }
    }
  },
  computed: {
    ...mapGetters(['socketToken', 'token', 'accountList', 'networkPopup']),
    network: {
      get() {
        return this.networkPopup;
      },
      set() {}
    },
    abnormalPop: {
      get() {
        return this.isLogin && this.userInfo.group == 9999 && this.abnormalPopSign;
      },
      set() {}
    },
    cfdInfo() {
      var info = {}
      this.accountList.forEach(item => {
        if (item.market == 'CFD') {
          info = item
        }
      })
      return info
    }
  },
  created () {
    if (this.isLogin) {
      this.$store.dispatch('getUserInfo', true)
    }
    if (this.$route.meta.socket) {
      this.init()
    }
    bus.$on('abnormalPopSign', (val) => {
      this.abnormalPopSign = val !== undefined ? val : true
    })
    bus.$on('alterProductData', this.alterProductData)
    bus.$on('resetProductDataObj', this.resetProductDataObj)
    bus.$on('socketInit', this.init)
    this.getParams()
    this.getApiParams()
  },
  mounted () {
    document.addEventListener('visibilitychange', (ev) => {
      if(!document.hidden) {
        this.alterProductData({
          getData: this.updateSymbolList
        })
      }
    }, false)
  },
  methods: {
    init() {
      if (this.isLogin) {
        this.creatSocket(this.token)
      } else {
        if (this.socketToken) {
          this.creatSocket(this.socketToken)
        } else {
          this.openSubscribe()
        }
      }
    },
    openSubscribe() {
      openSubscribe().then(res => {
        if (res.token) {
          setSession('socketToken', res.token)
          this.$store.commit('setSocketToken', res.token)
          this.creatSocket(res.token)
          if (this.waitList.length) {
            updateSubscribe({
              symbols: JSON.stringify(this.waitList)
            }).then(res => {
            }).catch(() => {}).finally(() => {
              this.waitList = []
            })
          }
        }
      }).catch(() => {

      })
    },
    creatSocket(token) {
      this.webSocket = new WebSocketClient('/Quotation/' + token)
      this.webSocket.connect(this.onopen, this.onmessage)
    },
    onopen() {
      if (this.socketTimer) {
        return
      }
      this.socketTimer = setInterval(() => {
        if (this.webSocket && this.webSocket.socket.readyState == 3) {
          this.init()
        }
      }, 120000)
    },
    onmessage(data) {
      var msg = JSON.parse(data.data)
      if (msg) {
        if (msg.type == 'depth' && this.updateSymbolList.indexOf(msg.symbol) != -1) {
          if (this.productDataObj && this.productDataObj[msg.symbol] !== undefined) {
            var targetSymbol = this.productDataObj[msg.symbol];
            var asks = (msg.asks || []).sort((a, b) => Number(a.price) - Number(b.price)).filter(item => Number(item.price))
            var bids = (msg.bids || []).sort((a, b) => Number(b.price) - Number(a.price)).filter(item => Number(item.price))
            if (asks[0]) {
              var ask = asks[0].price
              this.$set(this.productDataObj[msg.symbol], 'spread', this.$bigDecimal.subtract(ask, targetSymbol.close))
              this.$set(this.productDataObj[msg.symbol], 'ask', ask)
              if (targetSymbol.close) {
                this.$set(this.productDataObj[msg.symbol], 'percentage', ((((ask || targetSymbol.close) - targetSymbol.close) / targetSymbol.close) * 100).toFixed(2))
              }
            }
            if (bids[0]) {
              var bid = bids[0].price
              this.$set(this.productDataObj[msg.symbol], 'bid', bid)
            }
          }
          bus.$emit('updateDepth', msg)
          if ((new Date().getTime() - this.timerSign) < 700) {
            return
          }
          this.timerSign = new Date().getTime()
          bus.$emit('updateSymbol', true)
        }
        if (msg.type == 'price' && this.updateSymbolList.indexOf(msg.symbol) != -1) {
          if (this.productDataObj && this.productDataObj[msg.symbol] !== undefined) {
            var item = this.productDataObj[msg.symbol]
            msg.ask = Number(this.$handleDigits(item.ask, item.digits))
            msg.bid = Number(this.$handleDigits(item.bid, item.digits))
            // if (item.high < item.ask) {
            //   this.$set(this.productDataObj[msg.symbol], 'high', msg.ask)
            // }
            // if (item.low > item.ask) {
            //   this.$set(this.productDataObj[msg.symbol], 'low', msg.ask)
            // }
            bus.$emit('updateChart', msg)
          }
        }
      }
    },
    close() {
      this.webSocket && this.webSocket.close()
    },
    getParams() {
      getParams({
        type: 'Product,Thirdini,TradeVolume,Advertisement'
      }).then(res => {
        var list = res || [];
        var obj = {
          marketVolume: {}
        };
        list.forEach(item => {
          if (item.type == 'TradeVolume') {
            if (item.remark) {
              item.remark = JSON.parse(item.remark)
              item.remark.forEach(item => {
                obj.marketVolume[item.market] = item.volume
              })
            }
            return
          }
          if (item.type == 'Advertisement') {
            obj[item.title] = item.value ? JSON.parse(item.value) : {}
            return
          }
          if (item.type == 'Product') {
            obj.uncrypto = (item.value.indexOf('H5') === -1)
          } else {
            item.value.forEach((i) => {
              obj[i.key] = i.value
            })
          }
        })
        this.$store.commit('setAppParams', obj)
      }).catch(() => {})
    },
    getApiParams() {
      getApiParams({
        type: 'jdnxuri'
      }).then(res => {
        var params = (res || [])[0] || {};
        var list = [];
        var wsslist = [];
        (params.value || []).forEach(item => {
          list.push(item.api)
          wsslist.push(item.wss)
        })
        window.apiList = window.apiList.concat(list)
        window.streamList = window.streamList.concat(list)
      }).catch(() => {})
    },
    resetProductDataObj(list) {
      var productDataObj1 = {}
      list.forEach(item => {
        productDataObj1[item] = this.productDataObj[item]
      })
      this.productDataObj = productDataObj1
    },
    alterProductData(data = {}) {
      if (data.getData && data.getData.length) {
        getProductList({
          symbol: JSON.stringify(data.getData)
        }).then(res => {
          var list1 = res.list || []
          list1.forEach(item => {
            if (item.profit_mode == 0 && item.margin_mode == 0 && this.cfdInfo.leverage) {
              item.margin_divider1 = this.cfdInfo.leverage
            }
            if (item.close) {
              item.percentage = ((((item.ask || item.close) - item.close) / item.close) * 100).toFixed(2);
            } else {
              item.percentage = 100;
            }
            // if (item.high < item.ask) {
            //   item.high = item.ask
            // }
            // if (item.low > item.ask) {
            //   item.low = item.ask
            // }
            item.spread = this.$bigDecimal.subtract(item.ask, item.close)
            item.ask = Number(this.$handleDigits(item.ask, item.digits))
            item.bid = Number(this.$handleDigits(item.bid, item.digits))
            this.$set(this.productDataObj, item.symbol, item)
          })
        }).catch(() => {})
      }
      if (data.setData && data.setData.length) {
        data.setData.forEach(item => {
          item.ask = Number(this.$handleDigits(item.ask, item.digits))
          item.bid = Number(this.$handleDigits(item.bid, item.digits))
          if (item.profit_mode == 0 && item.margin_mode == 0 && this.cfdInfo.leverage) {
            item.margin_divider1 = this.cfdInfo.leverage
          }
          if (item.close) {
            item.percentage = ((((item.ask || item.close) - item.close) / item.close) * 100).toFixed(2);
          } else {
            item.percentage = 100;
          }
          // if (item.high < item.ask) {
          //   item.high = item.ask
          // }
          // if (item.low > item.ask) {
          //   item.low = item.ask
          // }
          item.spread = this.$bigDecimal.subtract(item.ask, item.close)
          item.ask = Number(this.$handleDigits(item.ask, item.digits))
          item.bid = Number(this.$handleDigits(item.bid, item.digits))
          this.$set(this.productDataObj, item.symbol, item)
        })
      }
      if (!this.webSocket || (this.webSocket && this.webSocket.socket.readyState == 3)) {
        this.init()
      }
      if (this.isLogin) {
        if (this.updateTradeAssetSocket && this.updateTradeAssetSocket.socket.readyState == 3) {
          this.sendTimer && clearInterval(this.sendTimer)
          this.creatSocket1(getCookie('userToken') || Math.random())
        }
      }
      if (data.subscribeList && data.subscribeList.length) {
        this.$store.commit('setUpdateSymbolList', data.subscribeList)
        if (this.socketToken || this.token) {
          updateSubscribe({
            symbols: JSON.stringify(data.subscribeList)
          }).then(res => {
          }).catch(() => {})
        } else {
          this.waitList = data.subscribeList
        }
      }
    }
  }
}
</script>

<style>
#app {
  position: relative;
  color: var(--color-d-);
  background-color: var(--bg-);
  line-height: 1;
}
</style>
