<script setup lang="ts">
import { nextTick, onMounted, onUnmounted, ref } from 'vue'
import { ArrowDown, Minus, RefreshRight, Setting } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import type { ECharts, EChartsOption } from 'echarts'

const scaleChart = ref<HTMLElement>()
const gapChart = ref<HTMLElement>()
const charts: ECharts[] = []

function createChart(el: HTMLElement | undefined, option: EChartsOption) {
  if (!el) return
  const chart = echarts.init(el)
  chart.setOption(option)
  charts.push(chart)
}

function resizeCharts() {
  charts.forEach((chart) => chart.resize())
}

function lineOption(series: echarts.SeriesOption[], yMin = 0, yMax = 200): EChartsOption {
  return {
    grid: { left: 56, right: 28, top: 46, bottom: 42 },
    legend: {
      top: 4,
      right: 8,
      icon: 'path://M0,4 L12,4',
      itemWidth: 16,
      itemHeight: 7,
      textStyle: { color: '#6e7787', fontSize: 11 },
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: ['05-15', '05-16', '05-17', '05-18', '05-20', '05-21'],
      axisTick: { show: false },
      axisLine: { lineStyle: { color: '#d6dde8' } },
      axisLabel: { color: '#6b7280', fontSize: 12 },
    },
    yAxis: {
      type: 'value',
      min: yMin,
      max: yMax,
      splitNumber: 4,
      axisLabel: { color: '#6b7280', fontSize: 12 },
      splitLine: { lineStyle: { color: '#e7ecf3' } },
    },
    series,
  }
}

function chartGradient(start: string, end: string) {
  return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
    { offset: 0, color: start },
    { offset: 1, color: end },
  ])
}

onMounted(async () => {
  await nextTick()
  createChart(scaleChart.value, lineOption([
      {
        name: '日头寸规模',
        type: 'line',
        smooth: false,
        symbolSize: 8,
        data: [120, 138, 91, 98, 88, 148],
        lineStyle: { color: '#1267f2', width: 2 },
        itemStyle: { color: '#1267f2' },
        areaStyle: {
          color: chartGradient('rgba(18, 103, 242, .28)', 'rgba(18, 103, 242, .02)'),
        },
      },
      {
        name: '最优头寸',
        type: 'line',
        symbol: 'none',
        data: [120, 138, 91, 98, 88, 148],
        lineStyle: { color: '#1267f2', width: 1, opacity: 0 },
      },
    ]))

  createChart(gapChart.value, lineOption([
      {
        name: '资金缺口',
        type: 'line',
        smooth: true,
        symbolSize: 8,
        data: [-18, 18, 62, 165, 122, 130],
        lineStyle: { color: '#16c5aa', width: 2 },
        itemStyle: { color: '#16c5aa' },
      },
      {
        name: '累计缺口',
        type: 'line',
        smooth: true,
        symbolSize: 8,
        data: [-65, -25, 60, 165, 120, 128],
        lineStyle: { color: '#1267f2', width: 2 },
        itemStyle: { color: '#1267f2' },
        areaStyle: {
          color: chartGradient('rgba(18, 103, 242, .25)', 'rgba(18, 103, 242, .03)'),
        },
      },
    ], -100, 200))

  window.addEventListener('resize', resizeCharts)
})

onUnmounted(() => {
  window.removeEventListener('resize', resizeCharts)
  charts.forEach((chart) => chart.dispose())
})
</script>

<template>
  <article class="board warning-board">
    <div class="board-head">
      <h2><span></span>头寸预警总览</h2>
      <div class="actions">
        <button>本月数据<el-icon><ArrowDown /></el-icon></button>
        <el-icon><RefreshRight /></el-icon>
        <el-icon><Setting /></el-icon>
        <el-icon><Minus /></el-icon>
      </div>
    </div>
    <div class="warning-layout">
      <div class="chart-box">
        <h3>全行头寸规模</h3>
        <small>(亿元)</small>
        <div ref="scaleChart" class="line-chart"></div>
      </div>
      <div class="chart-box">
        <h3>资金缺口</h3>
        <small>(亿元)</small>
        <div ref="gapChart" class="line-chart"></div>
      </div>
      <div class="stat-strip">
        <div><p>预警客户数(个)</p><strong class="blue-text">83</strong></div>
        <div><b>6.2% <em>↑</em></b></div>
        <div><p>较上月</p><strong>79</strong></div>
        <div><p>正常(个)</p><strong>76</strong></div>
        <div><p>关注(个)</p><strong>-</strong></div>
        <div><p>预警(个)</p><strong>19</strong></div>
        <div><p>严重(个)</p><strong>-</strong><span class="tiny-bar"></span></div>
      </div>
    </div>
  </article>
</template>

<style scoped>
.warning-board {
  --blue: #1267f2;
  --line: #dce4ef;
  min-width: 0;
  height: clamp(520px, 58vh, 640px);
  min-height: 520px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  background: rgba(255, 255, 255, .96);
  border-radius: 10px;
  box-shadow: 0 10px 22px rgba(34, 67, 123, .16);
}

.board-head {
  height: 38px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}

.board-head h2 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 20px;
  line-height: 1.1;
  font-weight: 900;
}

.board-head h2 span {
  width: 13px;
  height: 14px;
  border-radius: 4px;
  background: var(--blue);
  box-shadow: inset 0 0 4px rgba(255, 255, 255, .35);
}

.actions {
  display: flex;
  align-items: center;
  gap: 16px;
  color: #6c7480;
  font-size: 15px;
}

.actions button {
  height: 26px;
  display: flex;
  align-items: center;
  gap: 3px;
  border: 0;
  background: transparent;
  color: #6c7480;
  font-size: 13px;
  font-weight: 600;
}

.warning-layout {
  display: grid;
  flex: 1;
  margin-top: 8px;
  gap: 12px;
  grid-template-columns: 1.05fr .9fr;
  grid-template-rows: minmax(0, 1fr) auto;
}

.chart-box {
  min-width: 0;
  position: relative;
  height: 100%;
  min-height: 0;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
}

.chart-box h3 {
  position: absolute;
  left: 18px;
  top: 18px;
  z-index: 1;
  font-size: 18px;
  font-weight: 900;
}

.chart-box small {
  position: absolute;
  left: 18px;
  top: 56px;
  z-index: 1;
  color: #232a33;
  font-size: 12px;
}

.line-chart {
  position: absolute;
  inset: 72px 22px 22px 18px;
}

.stat-strip {
  grid-column: 1 / -1;
  min-height: 110px;
  display: grid;
  grid-template-columns: .8fr .7fr .8fr .8fr .8fr .8fr .8fr;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
}

.stat-strip > div {
  min-height: 50px;
  padding-left: 17px;
  border-right: 1px solid #dce4ef;
}

.stat-strip > div:last-child {
  border-right: 0;
}

.stat-strip p {
  color: #4d5868;
  font-size: 14px;
}

.stat-strip strong,
.stat-strip b {
  display: block;
  margin-top: 8px;
  font-size: 21px;
  font-weight: 900;
}

.blue-text {
  color: var(--blue) !important;
}

em {
  color: #10b990;
  font-style: normal;
}

.tiny-bar {
  display: block;
  width: 64px;
  height: 8px;
  margin-top: 7px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--blue) 0 56%, #e7ebf0 56%);
}

@media (max-width: 1200px) {
  .warning-board {
    height: auto;
    min-height: 0;
  }

  .warning-layout {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
  }

  .chart-box {
    height: auto;
    min-height: 230px;
  }

  .stat-strip {
    grid-template-columns: repeat(3, 1fr);
    height: auto;
  }

  .stat-strip > div {
    min-height: 72px;
  }
}

@media (max-width: 720px) {
  .actions {
    gap: 10px;
  }

  .board-head {
    height: auto;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 12px;
  }

  .warning-layout {
    gap: 10px;
  }

  .stat-strip {
    grid-template-columns: repeat(2, 1fr);
  }

  .stat-strip > div:nth-child(2n) {
    border-right: 0;
  }
}
</style>
