<script setup>
import {
  onMounted,
  inject,
  ref,
  nextTick,
  onBeforeUnmount,
} from 'vue'

import {
  calculateMA,
  calculateStdDeviation,
  calculateMACD,
  calculateKDJ,
  calculateRSI,
  calculateVOL,
} from './computedInfo'

let charts1 = ref(null)
let charts2 = ref(null)
let charts3 = ref(null)
let charts4 = ref(null)

// 请求后端数据
let szdata = ref([])
let kdata = ref([])
let xdata = ref([])
let closedata = ref([])
let ma5 = ref()
// 标准差
let StdDev = ref()
let topStdDev = ref()
let downStdDev = ref()

let rsi1 = ref()
let rsi2 = ref()
let rsi3 = ref()

let vol = ref()
let interval = ref()

import request from '@/utils/request'
let baseURL = 'http://127.0.0.1:8015'
const redata = () => {
  try {
    request({
      url: baseURL + '/stock',
      method: 'get',
      params: {
        symbol: 'sz000001',
        start_date: '2021-01-01',
        end_date: '2022-12-31',
      },
    }).then((res) => {
      xdata.value = Object.values(res.date)
      let { open, close, low, high, volume } = res
      for (let i = 0; i < Object.keys(open).length; i++) {
        kdata.value.push([open[i], close[i], low[i], high[i]])
        closedata.value.push(close[i])
      }

      // 计算5日移动平均线
      ma5.value = calculateMA(closedata.value, 5)

      StdDev.value = calculateStdDeviation(closedata.value)

      topStdDev.value = closedata.value.map((item) =>
        parseFloat((item + StdDev.value).toFixed(2))
      )
      downStdDev.value = closedata.value.map((item) =>
        parseFloat((item - StdDev.value).toFixed(2))
      )

      // MACD数据
      let { dif, dea, macd } = calculateMACD(closedata.value)

      // 准备数据数组，同时设置颜色
      macd = macd.map(function (value) {
        return {
          value: value,
          itemStyle: {
            color: value >= 0 ? '#FF0000' : '#00FF00', // 根据值的正负设置颜色
          },
        }
      })

      chartConfigs.value[0].options.series[0].data = dif
      chartConfigs.value[0].options.series[1].data = dea
      chartConfigs.value[0].options.series[2].data = macd
      chartConfigs.value[0].options.xAxis.data = xdata.value

      // vol数据
      vol.value = calculateVOL(close, high, low)
      chartConfigs.value[1].options.xAxis.data = xdata.value
      chartConfigs.value[1].options.series[0].data = vol.value

      // KDJ数据
      let { kValues, dValues, jValues } = calculateKDJ(res)
      chartConfigs.value[2].options.series[0].data = kValues
      chartConfigs.value[2].options.series[1].data = dValues
      chartConfigs.value[2].options.series[2].data = jValues
      chartConfigs.value[2].options.xAxis.data = xdata.value

      // RSI数据
      rsi1.value = calculateRSI(closedata.value)
      rsi2.value = calculateRSI(closedata.value, 12)
      rsi3.value = calculateRSI(closedata.value, 24)
      chartConfigs.value[3].options.series[0].data = rsi1.value
      chartConfigs.value[3].options.series[1].data = rsi2.value
      chartConfigs.value[3].options.series[2].data = rsi3.value
      chartConfigs.value[3].options.xAxis.data = xdata.value

      dynamicsHeight()
      configecharts()
    })
  } catch (err) {
    console.error('请求失败:', err)
  }
}

//引入echarts
let echarts = inject('echarts')

// 外层盒子容器，为了计算图形在内部的高度分配问题
const chartsInfo = ref(null)
// K线图的容器
const mKline = ref(null)

// 存储各个图形所分配的高度信息
let heightList = ref([])
// 计算高度、设置高度
const dynamicsHeight = () => {
  // 高度
  let domHeightList = chartsInfo.value.offsetHeight
  // 判断是否进行了底部选项的点击事件，如果点击了则会往数组中添加信息，则长度就会改变

  // if (clicklist.value.length) {
  //   // 先清空数组，避免
  //   heightList.value = []
  //   // 将处理过后的数据加入数组
  //   heightList.value.push(domHeightList * (1 - clicklist.value.length * 0.15))
  //   // 设置最上面K线图的高度
  //   mKline.value.style.height = `${heightList.value[0]}px`
  //   // 设置新添加图表的高度
  //   heightList.value.push(domHeightList * 0.15)

  //   console.log(heightList.value)
  // } else {
  //   // 先清空数组，避免之前的数据没有被清空
  //   heightList.value = []

  //   // 设置只有K线图的高度的父容器的全部大小
  //   mKline.value.style.height = `${domHeightList}px`
  // }

  console.log(chartsInfo.value.children.length)
  // 子元素长度
  let childrenLength = chartsInfo.value.children.length

  if (childrenLength) {
    // 先清空数组，避免
    heightList.value = []
    // 将处理过后的数据加入数组
    heightList.value.push(domHeightList * (1 - childrenLength * 0.15))
    // 设置最上面K线图的高度
    mKline.value.style.height = `${heightList.value[0]}px`
    // 设置新添加图表的高度
    heightList.value.push(domHeightList * 0.15)

    console.log(heightList.value)
  } else {
    // 先清空数组，避免之前的数据没有被清空
    heightList.value = []

    // 设置只有K线图的高度的父容器的全部大小
    mKline.value.style.height = `${domHeightList}px`
  }
}

// 定义图表配置数组
let chartConfigs = ref([
  {
    id: 1,
    name: 'MACD',
    attId: 'charts1',
    status: false,
    options: {
      animation: false,
      tooltip: {
        trigger: 'axis', // 触发类型为坐标轴
        axisPointer: {
          // 坐标轴指示器
          type: 'cross', // 类型为交叉
          label: {
            backgroundColor: '#6a7985', // 标签背景色
          },
        },
      },
      dataZoom: [
        {
          type: 'inside',
        },
        {
          type: 'slider',
          show: false,
        },
      ],
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: [],
      },
      yAxis: {
        type: 'value',
      },
      series: [
        {
          name: 'DIF',
          type: 'line',
          itemStyle: {
            normal: {
              color: 'rgba(204,102,0,1)',
            },
          },
          symbol: 'none',
          data: [],
        },
        {
          name: 'DEA',
          type: 'line',
          itemStyle: {
            normal: {
              color: 'rgba(0,128,255,1)',
            },
          },
          symbol: 'none',
          data: [],
        },
        {
          name: 'MACD',
          type: 'bar',
          barWidth: '1',
          // symbol: 'none',
          data: [],
        },
      ],
    },
  },
  {
    id: 2,
    name: 'VOL',
    attId: 'charts2',
    status: false,
    options: {
      animation: false,
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'cross',
          label: {
            backgroundColor: '#6a7985',
          },
        },
      },
      dataZoom: [
        {
          type: 'inside',
        },
        {
          type: 'slider',
          show: false,
        },
      ],
      xAxis: {
        type: 'category',
        data: [],
      },
      yAxis: {
        type: 'value',
        // splitNumber: 3 ,
        interval: 10,
      },
      series: [
        {
          name: 'VOL',
          type: 'bar',
          data: [],
        },
      ],
    },
  },
  {
    id: 3,
    name: 'KDJ',
    attId: 'charts3',
    status: false,
    options: {
      animation: false,
      tooltip: {
        trigger: 'axis', // 触发类型为坐标轴
        axisPointer: {
          // 坐标轴指示器
          type: 'cross', // 类型为交叉
          label: {
            backgroundColor: '#6a7985', // 标签背景色
          },
        },
      },
      dataZoom: [
        {
          type: 'inside',
          xAxisIndex: [0, 0],
          start: 20,
          end: 100,
        },
        {
          type: 'slider',
          show: false,
        },
      ],
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: [],
      },
      series: [
        {
          name: 'K',
          type: 'line',
          data: [],
          symbol: 'none',
          smooth: true,
          // lineStyle: {
          //   width: 1,
          // },
          // areaStyle: {
          //   opacity: 0.5,
          // },
          // itemStyle: {
          //   color: 'rgba(0,128,255,1)',
          // },
        },
        {
          name: 'D',
          type: 'line',
          data: [],
          symbol: 'none',
          smooth: true,
          //   lineStyle: {
          //     width: 1,
          //   },
          //   areaStyle: {
          //     opacity: 0.5,
          //   },
          //   itemStyle: {
          //     color: 'rgba(0,128,255,1)',
          //  },
        },
        {
          name: 'J',
          type: 'line',
          data: [],
          symbol: 'none',
          smooth: true,
          //   lineStyle: {
          //     width: 1,
          //   },
          //   areaStyle: {
          //     opacity: 0.5,
          //   },
          //   itemStyle: {
          //     color: 'rgba(0,128,255,1)',
          //  },
        },
      ],
    },
  },
  {
    id: 4,
    name: 'RSI',
    attId: 'charts4',
    status: false,
    options: {
      animation: false,
      tooltip: {
        trigger: 'axis', // 触发类型为坐标轴
        axisPointer: {
          // 坐标轴指示器
          type: 'cross', // 类型为交叉
          label: {
            backgroundColor: '#6a7985', // 标签背景色
          },
        },
      },
      dataZoom: [
        {
          type: 'inside',
          xAxisIndex: [0, 0],
          start: 20,
          end: 100,
        },
        {
          type: 'slider',
          show: false,
        },
      ],
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: [],
      },
      series: [
        {
          name: 'rsi1',
          type: 'line',
          data: [],
          symbol: 'none',
          smooth: true,
          // lineStyle: {
          //   width: 1,
          // },
          // areaStyle: {
          //   opacity: 0.5,
          // },
          // itemStyle: {
          //   color: 'rgba(0,128,255,1)',
          // },
        },
        {
          name: 'rsi2',
          type: 'line',
          data: [],
          symbol: 'none',
          smooth: true,
          //   lineStyle: {
          //     width: 1,
          //   },
          //   areaStyle: {
          //     opacity: 0.5,
          //   },
          //   itemStyle: {
          //     color: 'rgba(0,128,255,1)',
          //  },
        },
        {
          name: 'rsi3',
          type: 'line',
          data: [],
          symbol: 'none',
          smooth: true,
          //   lineStyle: {
          //     width: 1,
          //   },
          //   areaStyle: {
          //     opacity: 0.5,
          //   },
          //   itemStyle: {
          //     color: 'rgba(0,128,255,1)',
          //  },
        },
      ],
    },
  },
])

// 储存点击底部选项的状态的数据
const clicklist = ref([])

// 处理点击事件并添加图表
const addChart = (item) => {
  // 检查数组中是否已经存在具有相同domId的元素
  // let domToRemove = chartBoxList.value.find(element => element.domId === item.attId)
  //   if(domToRemove){
  //     domToRemove.chart.dispose()
  //   }

  //   let indexToRemove = chartBoxList.value.findIndex(element => element.domId === item.attId)

  //   // 如果找到了，移除那个元素
  //   if (indexToRemove !== -1) {
  //     chartBoxList.value.splice(indexToRemove, 1)
  //   }

  // 判断当前点击的图表的状态，如果已经存在则不进行操作
  if (clicklist.value.includes(item.name)) {
    // 先移除当前的图表信息
    // clicklist.value = clicklist.value.filter((content) => content !== item.name)

    // if (item.attId === 'charts1') {
    //   charts1.value.style.display = 'none'
    // }

    // 调用高度计算函数，重新分配高度
    dynamicsHeight()
    // 延迟执行，确保图表已经创建
    nextTick(() => {
      chartConfigs.value.forEach((element) => {
        if (element.name == item.name) {
          element.status = false

          // 调用configecharts函数，刷新图表，防止图形重叠
          configecharts()
        }
      })
    })
  } else {
    // 往数组里面添加参数信息
    // clicklist.value.push(item.name)
    // 遍历数组，找到对应名称的图表并设置状态为true
    chartConfigs.value.forEach((element) => {
      if (element.name == item.name) {
        element.status = true
      }
    })

    // 调用高度计算函数，重新分配高度
    dynamicsHeight()
    // 延迟执行，确保图表已经创建
    nextTick(() => {
      chartConfigs.value.forEach((element) => {
        if (element.name == item.name) {
          element.status = true

          // 调用configecharts函数，刷新图表，防止图形重叠
          configecharts()
          // 调用commonecharts函数，会根据传入的参数进行图表的绘制
          // commonecharts(item.attId, item.options)
          if (!clicklist.value.includes(item.name)) {
            commonecharts(item.attId, item.options)
            clicklist.value.push(item.name)
          }
          // if (item.attId === 'charts1') {
          //   charts1.value.style.display = 'block'
          // }
        }
      })
    })
  }
}

// 绘制初始的Echarts图表，始终会在页面中。并返回当前图表的实例化信息，便于使用echarts.connect()进行连接
const configecharts = (options = {}) => {
  // 先将容器中的_echarts_instance_清除，不处理会导致高度变化了但图表不刷新
  document.getElementById('main').removeAttribute('_echarts_instance_')
  // 初始化k线图图表
  let chartBox = echarts.init(document.getElementById('main'))
  // 直接使用pinia中储存的option数据
  const option = {
    animation: false,
    tooltip: {
      trigger: 'axis', // 触发类型为坐标轴
      axisPointer: {
        // 坐标轴指示器
        type: 'cross', // 类型为交叉
        label: {
          backgroundColor: '#6a7985', // 标签背景色
        },
        animation: false,
      },
      // formatter: (params)=> {
      //     let str = '<div style="padding: 3px 12px;width: 161px;background: #FFFFFF;border: 1px solid #DCDFE6;box-shadow:none; opacity: 1;border-radius: 4px;"><span style="color:#606062;font-size: 12px;">' + params[0].axisValue + "</span><br />";
      //     params.forEach((item) => {
      //       str +=
      //         '<span style="color:#f00;font-size: 12px;color: #1D1D20;"><span style="float:left; margin-top:8px; margin-right:5px;border-radius:50%;width:6px;height:6px;background-color:'+item.color+'"></span>' +  "&nbsp;&nbsp;&nbsp;&nbsp;" + item.data + "</span>";
      //     });
      //     str += '</div>'
      //     return str;

      //     // console.log(params[0]);

      //   }
    },
    legend: {
      data: ['KLine', 'MA5', 'BOLL1', 'BOLL2'],
    },
    grid: [
      {
        left: '3%',
        right: '3%',
        bottom: '5%',
      },
    ],
    xAxis: [
      {
        type: 'category',
        data: xdata.value,
        gridIndex: 0,
        scale: true,
        boundaryGap: false,
        axisLine: { onZero: false },
        splitLine: { show: false },
        splitNumber: 20,
        min: 'dataMin',
        max: 'dataMax',
        sampling: 'lttb', // 最大程度保证采样后线条的趋势，形状和极值。
      },
    ],
    yAxis: [
      {
        gridIndex: 0,
        scale: true,
        splitArea: {
          show: false,
        },
      },
    ],
    dataZoom: [
      {
        type: 'slider',
      },
      {
        type: 'inside',
      },
    ],
    series: [
      {
        name: 'KLine',
        type: 'candlestick',
        xAxisIndex: 0,
        yAxisIndex: 0,
        data: kdata.value,
        itemStyle: {
          normal: {
            color: '#ef232a',
            color0: '#14b143',
            borderColor: '#ef232a',
            borderColor0: '#14b143',
          },
        },
        // markArea: {
        //   silent: true,
        //   itemStyle: {
        //     normal: {
        //       color: 'Honeydew',
        //     },
        //   },
        //   data: [],
        // },
        // markPoint: {
        //   data: [
        //     { type: 'max', name: '最大值' },
        //     { type: 'min', name: '最小值' },
        //   ],
        // },
        // markLine: {
        //   label: {
        //     normal: {
        //       position: 'middle',
        //       textStyle: { color: 'Blue', fontSize: 12 },
        //     },
        //   },
        //   data: [],
        //   symbol: ['circle', 'none'],
        // },
      },
      {
        name: 'MA5',
        type: 'line',
        xAxisIndex: 0,
        yAxisIndex: 0,
        data: ma5.value,
        symbol: 'none',
        smooth: true,
        lineStyle: {
          normal: {
            opacity: 0.5,
          },
        },
      },
      {
        name: 'BOLL1',
        type: 'line',
        xAxisIndex: 0,
        yAxisIndex: 0,
        data: topStdDev.value,
        symbol: 'none',
        smooth: true,
        lineStyle: {
          normal: {
            opacity: 0.5,
            color: 'red',
          },
        },
        // areaStyle: {
        //   // 线条样式
        //   normal: {
        //     // 右，下，左，上
        //     color: new echarts.graphic.LinearGradient(0, 0, 0, 1,
        //       [
        //         // 渐变色
        //         {
        //           offset: 0,
        //           color: 'rgba(255, 46, 106, 0.21)'
        //         },
        //         {
        //           offset: 1,
        //           color: 'rgba(255, 46, 106, 0)'
        //         }
        //       ],
        //       false
        //     )
        //   }
        // }
      },
      {
        name: 'BOLL2',
        type: 'line',
        xAxisIndex: 0,
        yAxisIndex: 0,
        data: downStdDev.value,
        symbol: 'none',
        smooth: true,
        lineStyle: {
          normal: {
            opacity: 0.5,
            color: 'green',
          },
        },
        // areaStyle: {
        //   // 线条样式
        //   normal: {
        //     // 右，下，左，上
        //     color:'white'
        //   }
        // }
      },
      // {
      //   name: '',
      //   type: 'line',
      //   xAxisIndex: 0,
      //   yAxisIndex: 0,
      //   data: ma5.value,
      //   smooth: true,
      //   lineStyle: {
      //     normal: {
      //       opacity: 0.5,
      //     },
      //   },
      // },
    ],
  }
  // 配置图表数据信息
  chartBox.setOption(option)

  // mergeOptions方法可以合并两个对象，并返回合并后的对象。
  // 更新信息，可有可无?，调用时配置
  chartBox.setOption(options)

  // 图表的分组，用于联动
  chartBox.group = 'group1'
  // 根据页面大小自动响应图表大小
  window.addEventListener('resize', function () {
    chartBox.resize()
  })
}

// chart实例化数组
let chartBoxList = ref([])
//绘制一个点击事件传参的Echarts图表。并返回当前图表的实例化信息，便于使用echarts.connect()进行连接
const commonecharts = (containerId, options = {}) => {
  // 先将容器中的_echarts_instance_清除，不处理会导致高度变化了但图表不刷新
  document.getElementById(containerId).removeAttribute('_echarts_instance_')
  // 初始化图表
  const chart = echarts.init(document.getElementById(containerId))

  chartBoxList.value.push({
    chart,
    chartid: chart.id,
    domId: containerId,
  })

  console.log(chartBoxList.value)

  // 图表的配置信息
  const option = {
    xAxis: {
      type: 'category',
      data: xdata.value,
    },
    yAxis: {
      type: 'value',
    },
    grid: {
      top: '10%',
      left: '3%',
      right: '3%',
      bottom: '20%',
    },
    dataZoom: [
      {
        type: 'inside',
      },
    ],
    series: [
      {
        data: [1, 2, 3, 4, 5, 6, 7, 2, 12, 12, 34],
        type: 'line',
        smooth: true,
      },
    ],
  }
  // 设置图表实例的配置项
  chart.setOption(option)
  // mergeOptions方法可以合并两个对象，并返回合并后的对象。
  chart.setOption(options)

  // 图表的分组，用于联动
  chart.group = 'group1'

  // 根据页面大小自动响应图表大小
  window.addEventListener('resize', function () {
    chart.resize()
  })

  return chart
}
// 连接所有图表
echarts.connect('group1')

onMounted(() => {
  redata()
  const chart = echarts.init(charts1.value)
  console.log(chart)

  charts1.value.style.height = `${200}px`

  // 图表的配置信息
  const option = {
    xAxis: {
      type: 'category',
      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
    },
    yAxis: {
      type: 'value',
    },
    grid: {
      top: '10%',
      left: '3%',
      right: '3%',
      bottom: '20%',
    },
    dataZoom: [
      {
        type: 'inside',
      },
    ],
    series: [
      {
        data: [1, 2, 3, 4, 5, 6, 7, 2, 12, 12, 34],
        type: 'line',
        smooth: true,
      },
    ],
  }
  // 设置图表实例的配置项
  chart.setOption(option)
  // mergeOptions方法可以合并两个对象，并返回合并后的对象。
  // chart.setOption(options)

  // 图表的分组，用于联动
  chart.group = 'group1'

  // 根据页面大小自动响应图表大小
  window.addEventListener('resize', function () {
    chart.resize()
  })

})
onBeforeUnmount(() => {
  // echarts.disconnect()
})
</script>

<template>
  <div class="box">
    <div class="chartsinfo" ref="chartsInfo">
      <!-- K线图 -->
      <div
        id="main"
        ref="mKline"
        class="flex-item"
        :style="{ height: `${heightList[0]}px` }"
      ></div>

      <div
        id="charts1"
        ref="charts1"
        :style="{ height: `${heightList[1]}px` }"
      ></div>
      <!-- <div
        v-if="chartConfigs[1].status"
        id="charts2"
        ref="charts2"
        :style="{ height: `${heightList[1]}px` }"
      ></div>
      <div
        v-if="chartConfigs[2].status"
        id="charts3"
        ref="charts3"
        :style="{ height: `${heightList[1]}px` }"
      ></div>
      <div
        v-if="chartConfigs[3].status"
        id="charts4"
        ref="charts4"
        :style="{ height: `${heightList[1]}px` }"
      ></div> -->
    </div>

    <!-- 底部的各个图表选项信息 -->
    <ul class="typelist">
      <li
        v-for="(item, index) in chartConfigs"
        :key="index"
        @click="addChart(item)"
      >
        {{ item.name }}
      </li>
    </ul>
  </div>
</template>

<style  scoped>
.box {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.chartsinfo {
  height: calc(100vh - 20px);
}

.typelist {
  margin-top: auto; 
  position: relative;
  z-index: 99999999;
  width: 100%;
  color: #191919;
  font-size: 12px;
  display: flex;
  list-style: none;
  padding: 0; 
  
}
.typelist > li {
  padding: 2px 8px;
  cursor: pointer;
}
.typelist > li:hover {
  color: gold;
}

.active {
  color: #2d98b9;
}
</style>
