<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import { ref } from 'vue';

/*
 * There are example components in both API styles: Options API, and Composition API
 *
 * Select your preferred style from the imports below:
 */
import LWChart from './components/LWChart.vue';
import {getCandleList} from '/@src/utils/api'
import {calculateMACD, calculateEMA, calculateBollingerBands, calculateRSI} from "./utils/meter.js";
import {entrySignals} from "./utils/cro.js";
import {swingSignal} from "./utils/sig.js";
import { useWindowSize } from '@vueuse/core'

const { width, height } = useWindowSize()
console.log(width, height)
/**
 * Generates sample data for the lightweight chart
 * @param  {Boolean} ohlc Whether generated dat should include open, high, low, and close values
 * @returns {Array} sample data
 */
let socket;
const lazyLock = ref(false)
const positionData = ref('')

const contract = ref('BTC_USDT')
/*	Interval : "10s", "1m", "5m", "15m", "30m", "1h", "4h", "8h", "1d", "7d"*/
const time = ref('1h')
const chartOptions = ref({
  layout: {
    textColor: 'black',
    background: { type: 'solid', color: 'white' },
    panes: {
      separatorColor: '#FF0000',
    },
  },
  width: width,
  height: height,
  timeScale: {
    timeVisible: true,      // 분/초까지 표시
    secondsVisible: false   // 초 숨기고 싶으면 false
  },

});

const candleTick = ref([])
const ema = ref([])
const macd = ref({})
const bb = ref({})
const rsi = ref({})

const selectCoins = [
  { title: 'BTC_USDT'},
  { title: 'ETH_USDT'},
  { title: 'SOL_USDT'},
  { title: 'XRP_USDT'},
  { title: 'LINK_USDT'},
]
const selectTimes = [
  { title: '10s'},
  { title: '1m'},
  { title: '5m'},
  { title: '15m'},
  { title: '30m'},
  { title: '1h'},
  { title: '4h'},
  { title: '8h'},
  { title: '1d'},
  { title: '7d'},
]

const line_color = [
    '#AD81FF',
    '#FFBAB5',
    '#6BFF74',
    '#FFFC7B',
    '#27FFE6',
    '#225EFF'
]


const emaLineOptions = ref({
  lineWidth: 2,
  color: '#AD81FF',
  title: 'EMA',
});

const candleOptions = ref({
  upColor: '#26a69a',
  downColor: '#ef5350',
  borderVisible: false,
  wickUpColor: '#26a69a',
  wickDownColor: '#ef5350',
});

const macdLineOptions = ref({
  lineWidth: 2,
  color: '#FFBAB5',
  title: 'MACD',
});

const macdSignalOptions = ref({
  lineWidth: 2,
  color: '#AD81FF',
  title: 'SIGNAL',
});

const macdHistogramOptions = ref({
  lineWidth: 2,
  color: '#27FFE6',
  title: 'HISTOGRAM',
});

const upperBbOptions = ref({
  color: '#006AFF',   // 주황색 계열
  lineStyle: 0,                      // 점선 스타일 (선택)
  lineWidth: 2,
  title: 'UpperBB',
})

const middleBbOptions = ref({
  color: '#006AFF',   // 주황색 계열
  lineStyle: 1,                      // 점선 스타일 (선택)
  lineWidth: 0,
  title: 'MiddleBB(SMA)',
})

const lowerBbOptions = ref({
  color: '#006AFF',   // 주황색 계열
  lineStyle: 0,                      // 점선 스타일 (선택)
  lineWidth: 2,
  title: 'LowerBB',
})

const rsiLineOptions = ref({
  lineWidth: 2,
  color: '#AD81FF',
  title: 'RSI',
});

const chartType = ref('candlestick');
const lwChart = ref();


onMounted(() => {
  init(contract.value, time.value)
})

const init = (cont, ti) => {
  socket = new WebSocket("wss://fx-ws.gateio.ws/v4/ws/usdt");
  const dt = new Date()
  getCandleList(cont, ti, Math.round(dt.getTime()/1000)).then(data => {
    ema.value = calculateEMA(data, 20)
    macd.value = calculateMACD(data)
    bb.value = calculateBollingerBands(data)
    rsi.value = calculateRSI(data)
    // console.log(swingSignal(data))
    // console.table(entrySignals(data))
    candleTick.value = data
  })

  candleSocket(cont, ti)
}

const distroy = (cont) => {
  candleTick.value = []
  socket.close()
}

const lazyLoad = async (ti) => {
  lazyLock.value = true
  getCandleList(contract.value, time.value, ti).then(data => {
    candleTick.value = [...data, ...candleTick.value]
    ema.value = calculateEMA(data, 20)
    macd.value = calculateMACD(data)
    bb.value = calculateBollingerBands(data)
    rsi.value = calculateRSI(data)
    setTimeout(() => {lazyLock.value = false}, 3000)

  })
}

const candleSocket = (cont, ti) => {
  socket.addEventListener('open', (event) => {
    // socket.send(JSON.stringify({"type":"subscribe", "channel": cont, "time": ti}))
    console.log(cont, ti)
    socket.send(JSON.stringify({"time" : curToUnix(), "channel" : "futures.candlesticks","event": "subscribe", "payload" : [ti, cont]}))
  })

  socket.addEventListener('message', (message) => {
    const msg = JSON.parse(message.data)
    if(msg.event === 'update') {
      const item = msg.result[0]

      const ticks = candleTick.value
      if(item.t === ticks[ticks.length - 1].t) {
        ticks[ticks.length - 1] = item
        candleTick.value = [...ticks]
      } else {
        ticks.push(item)
        candleTick.value = [...ticks]
      }

      ema.value = calculateEMA(ticks, 20)
      macd.value = calculateMACD(ticks)
      bb.value = calculateBollingerBands(ticks)
      rsi.value = calculateRSI(ticks)
      // console.table(entrySignals(ticks))
      console.log(swingSignal(ticks))
      lazyLock.value = false
    }


  })
}

const timeToUnix = (time) => {
  return Math.floor(new Date(time).getTime() / 1000);
}

const curToUnix = (() => {
  return Math.floor(new Date().getTime() / 1000);
})

const epochToString = (epo) => {
  const cu = new Date(epo)
  return cu.getFullYear() + '-' + cu.getMonth().toString().padStart(2, '0') + '-' +
      cu.getDate().toString().padStart(2, '0') + ' ' + cu.getHours().toString().padStart(2, '0') + ':' +
      cu.getMinutes().toString().padStart(2, '0') + ':' + cu.getSeconds().toString().padStart(2, '0');
}


const colorsTypeMap = {
  area: [
    ['topColor', 0.4],
    ['bottomColor', 0],
    ['lineColor', 1],
  ],
  bar: [
    ['upColor', 1],
    ['downColor', 1],
  ],
  baseline: [
    ['topFillColor1', 0.28],
    ['topFillColor2', 0.05],
    ['topLineColor', 1],
    ['bottomFillColor1', 0.28],
    ['bottomFillColor2', 0.05],
    ['bottomLineColor', 1],
  ],
  candlestick: [
    ['upColor', 1],
    ['downColor', 1],
    ['borderUpColor', 1],
    ['borderDownColor', 1],
    ['wickUpColor', 1],
    ['wickDownColor', 1],
  ],
  histogram: [['color', 1]],
  line: [['color', 1]],
};

const mouseMove = (data) => {
  positionData.value = `
<span style="color:red; padding-right:3px;">O</span>${data == null ? 0 : data.open}
<span style="color:red; padding-left:5px; padding-right:3px;">C</span>${data == null ? 0 : data.close}
<span style="color:red; padding-left:5px; padding-right:3px;">L</span>${data == null ? 0 : data.low}
<span style="color:red; padding-left:5px; padding-right:3px;">H</span>${data == null ? 0 : data.high}
<span style="color:red; padding-left:5px; padding-right:3px;">T</span>${data == null ? 0 : epochToString(data.time*1000)}
`;
}

watch(contract, newVal => {
  distroy()
  init(newVal, time.value)
})

watch(time, newVal => {
  distroy()
  init(contract.value, newVal)
})

</script>

<template>
  <div class="container">
    <div class="d-flex justify-content-center">
      <v-menu>
        <template v-slot:activator="{ props }">
          <v-btn color="grey-lighten-5" min-width="100" size="small" v-bind="props">{{contract}}</v-btn>
        </template>
        <v-list v-model="contract">
          <v-list-item
              v-for="(item, idx) in selectCoins"
              :key="idx"
              :value="item.title"
              @click="() => {
                socket.send(JSON.stringify({'type':'unsubscribe', 'channel': contract, 'time': time}))
                contract = item.title
              }"
          >
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
      <v-menu>
        <template v-slot:activator="{ props }">
          <v-btn color="grey-lighten-5" min-width="50" size="small" v-bind="props">{{time}}</v-btn>
        </template>
        <v-list v-model="time">
          <v-list-item
              v-for="(item, idx) in selectTimes"
              :key="idx"
              :value="item.title"
              @click="() => {
                socket.send(JSON.stringify({'type':'unsubscribe', 'channel': contract, 'time': time}))
                time = item.title
              }"
          >
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>

    </div>
    <div class="chart-container" v-if="candleTick !== undefined">
      <LWChart
          :type="chartType"
          :data="candleTick"
          :ema="ema"
          :macd="macd"
          :bb="bb"
          :rsi="rsi"
          :autosize="true"
          :chart-options="chartOptions"
          :ema-options="emaLineOptions"
          :candle-options="candleOptions"
          :macd-line-options="macdLineOptions"
          :macd-signal-options="macdSignalOptions"
          :macd-histogram-options="macdHistogramOptions"
          :lower-bb-options="lowerBbOptions"
          :middle-bb-options="middleBbOptions"
          :upper-bb-options="upperBbOptions"
          :rsi-line-options="rsiLineOptions"
          :lazyLock="lazyLock"
          @lazyLoad="lazyLoad"
          @mouseMove="mouseMove"
          ref="lwChart"
      />
      <div class="ohlc-info" v-html="positionData"></div>

    </div>
  </div>
</template>
<style scoped lang="scss">
.chart-container {
  height: calc(100% - 3.2em);
}

.ohlc-info {
  position: absolute;
  top: 20px;
  left: 10px;
  font-size: 12px;
  color: #333;
  background: rgba(255, 255, 255, 0.8);
  padding: 5px;
  border-radius: 4px;
  z-index: 1000;
}
</style>
