<template>
  <div class="hot-coin">
    <div class="coin-title pf600 fs18 fc121212">热门币种</div>
    <div class="coin-head">
      <div class="name">
        <div class="name-text pf400 fs12 fc666666">交易对</div>
        <div class="list-sort">
          <div class="sort-up">
            <img src="../../../assets/icon/index/Triangle.svg" alt="" />
          </div>
          <div class="sort-bottom">
            <img src="../../../assets/icon/index/Triangle 2.svg" alt="" />
          </div>
        </div>
      </div>
      <div class="name price">
        <div class="name-text pf400 fs12 fc666666">最新价</div>
        <div class="list-sort">
          <div class="sort-up">
            <img src="../../../assets/icon/index/Triangle.svg" alt="" />
          </div>
          <div class="sort-bottom">
            <img src="../../../assets/icon/index/Triangle 2.svg" alt="" />
          </div>
        </div>
      </div>
      <div class="name today">
        <div class="name-text pf400 fs12 fc666666">今日涨跌幅</div>
        <div class="list-sort">
          <div class="sort-up">
            <img src="../../../assets/icon/index/Triangle.svg" alt="" />
          </div>
          <div class="sort-bottom">
            <img src="../../../assets/icon/index/Triangle 2.svg" alt="" />
          </div>
        </div>
      </div>
    </div>
    <div class="coin-body" >
     <div v-show="item.change_rate" class="body-item" v-for="(item, index) in coinList" :key="index">
      <div class="item-left" @click="router.push({ path: '/marketDetails', query: { id: item.id,type: item.symbol.toLowerCase()} })">
        <div class="coin-img" >
          <img :src="item.logo" alt="" />
        </div>
        <div class="coin-name">
          <div class="upper-name pf500 fs14 fc2C3131">{{ formatSymbol(item.symbol) }}</div>
          <div class="letter-name pf400 fs10 fcA9A9A9">{{ item.name }}</div>
        </div>
        <div class="coin-echars"></div>
        <div class="coin-price">
          <div class="upper-price pf500 fs14 fc2C3131">{{ formatPrice(item.price) }}</div>
          <div class="letter-price pf400 fs10 fcA9A9A9">≈ ${{ formatPrice(item.price) }}</div>
        </div>
      </div>
      <div class="item-right pf500 fs12 fcFFFFFF" :class="getChangeColor(item.change_rate)">{{ formatChange(item.change_rate) }}</div>
    </div>
    </div>
  </div>
</template>
<script setup>
import { GetCoins } from '@/api/index'
import { ref, onMounted, onUnmounted } from 'vue'
 import { useRoute, useRouter } from "vue-router";

const router = useRouter();

const coinList = ref([])
let socket = null
let heartbeatTimer = null
let reconnectTimer = null
let isUnmounted = false

// --- 辅助函数 ---
const formatSymbol = (symbol) => symbol ? symbol.replace('USDT', '') : ''
const formatPrice = (price) => price ? parseFloat(price).toFixed(2) : '0.00'

// 格式化涨跌幅：+9.01%
const formatChange = (val) => {
  if (!val) return '+0.00%'
  const num = parseFloat(val)
  // 正数加 + 号，负数自带 - 号
  return (num > 0 ? '+' : '') + num.toFixed(2) + '%'
}

// 获取颜色：涨绿跌红
const getChangeColor = (val) => {
  if (!val) return 'bg-gray' // 没有数据时显示灰色
  return parseFloat(val) >= 0 ? 'bg-green' : 'bg-red'
}

// --- 1. WebSocket 核心逻辑 ---

const initWebSocket = () => {
  // 🔒【防死循环】清理旧连接
  if (socket) {
    socket.onclose = null
    socket.close()
    socket = null
  }

  if (coinList.value.length === 0) return

  // 🔒【参数生成】
  // 列表里是 BTCUSDT (大写) -> 转成 btcusdt (小写) -> 用 / 拼接
  // 结果: "btcusdt/ethusdt/bnbusdt..."
  const symbolsParam = coinList.value
    .map(item => item.symbol.toLowerCase())
    .join('/')

  const query = `?symbol=${symbolsParam}`

  // 2. 确定地址
  // 暂时直连真实 IP，排除本地代理干扰
  // const host = '63.141.230.43:57676'
  // const host = 'http://localhost:8080'
  // 等调试通了，以后上线前可以改回这样：
  const host = process.env.NODE_ENV === 'production'
    ? 'backend.66linknow.com'
    : 'localhost:8080' // 开发环境走代理
    const wsUrl = `ws://${host}/ws/kline/${query}`

  // console.log('🚀 开始连接:', wsUrl)

  try {
    socket = new WebSocket(wsUrl)
  } catch (err) {
    // console.error('WS 初始化失败:', err)
    reconnect()
    return
  }

  socket.onopen = () => {
    // console.log('✅ 连接成功')
    startHeartbeat()
    if (reconnectTimer) clearTimeout(reconnectTimer)
  }

  socket.onmessage = (event) => {
    if (event.data === 'pong' || event.data === 'ping') return
    try {
      const msg = JSON.parse(event.data)

      // 兼容两种数据结构 (有时候后端会包一层 data)
      if (msg.data) {
        updateCoinData(msg.data)
      } else {
        updateCoinData(msg)
      }
    } catch (e) {}
  }

  socket.onerror = (err) => {
    console.error('❌ WS 报错')
  }

  socket.onclose = (e) => {
    // console.log(`⚠️ 断开 (Code: ${e.code})`)
    // console.log('关闭原因:', e)
    // console.log('是否正常关闭:', e.wasClean)
    if (e.code === 1000) return
    socket = null
    reconnect()
  }
}

// --- 2. 更新数据 (核心适配) ---
const updateCoinData = (ticker) => {
  // ticker 是 WS 推送的数据:
  // { s: "ASTERUSDT", c: "1.016", P: "9.013", ... }

  if (!ticker || !ticker.s) return

  // 1. 找到列表里对应的币
  // 列表里是 "BTCUSDT"，WS 推送里 s 也是 "BTCUSDT"
  // 统一转大写对比，确保匹配
  const targetCoin = coinList.value.find(item =>
    item.symbol.toUpperCase() === ticker.s.toUpperCase()
  )

  if (targetCoin) {
    // 2. 更新价格 (c = current price)
    if (ticker.c) targetCoin.price = ticker.c

    // 3. 更新涨跌幅 (P = percentage change)
    // 把 WS 里的 P 字段赋值给列表项的 change_rate
    if (ticker.P) targetCoin.change_rate = ticker.P
  }
}

// --- 3. 自动重连 ---
const reconnect = () => {
  if (isUnmounted) return
  if (reconnectTimer) return
  reconnectTimer = setTimeout(() => {
    reconnectTimer = null
    initWebSocket()
  }, 3000)
}

// --- 4. 心跳保活 ---
const startHeartbeat = () => {
  if (heartbeatTimer) clearInterval(heartbeatTimer)
  heartbeatTimer = setInterval(() => {
    if (socket && socket.readyState === WebSocket.OPEN) {
      socket.send('ping')
    }
  }, 10000)
}

// --- 生命周期 ---

onMounted(async () => {
  try {
    // 1. 先拿列表 (只有价格，没有涨跌幅)
    const res = await GetCoins()
    coinList.value = Array.isArray(res) ? res : (res.data || [])

    // 2. 再连 WS (获取实时数据)
    if (coinList.value.length > 0) {
      initWebSocket()
    }
  } catch (error) {
    console.error('API 失败:', error)
  }
})

onUnmounted(() => {
  isUnmounted = true
  if (heartbeatTimer) clearInterval(heartbeatTimer)
  if (reconnectTimer) clearTimeout(reconnectTimer)
  if (socket) {
    socket.onclose = null
    socket.close()
    socket = null
  }
})
</script>
<style lang="less" scoped>
  .hot-coin {
    margin-top: 20px;
    width: 346px;
    height: 333px;
    .coin-title {
      height: 24px;
      line-height: 24px;
    }

    .coin-head {
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      align-items: center;
      margin-top: 6px;
      width: 100%;
      height: 24px;

      .name {
        display: flex;
        flex-direction: row;
        justify-content: flex-start;
        align-items: center;
        height: 24px;

        .list-sort {
          display: flex;
          flex-direction: column;
          justify-content: flex-start;
          margin-left: 4px;
          width: 8px;
          height: 16px;

          .sort-up,
          .sort-bottom {
            display: flex;
            flex-direction: row;
            justify-content: center;
            align-items: center;
            width: 8px;
            height: 8px;

            img {
              width: 8px;
              height: 4px;
            }
          }
        }
      }

      .price {
        margin-left: 128px;
      }

      .today {
        margin-left: 47px;
      }
    }

    .coin-body {
      margin-top: 9px;
      width: 100%;

      .body-item {
        display: flex;
        flex-direction: row;
        justify-content: flex-start;
        align-items: center;
        margin-top: 23.5px;
        width: 100%;
        height: 38px;

        &:nth-child(1) {
          margin-top: 0;
        }

        .item-left {
          display: flex;
          flex-direction: row;
          justify-content: flex-start;
          align-items: center;
          width: 276px;
          height: 100%;

          .coin-img {
            width: 32px;
            height: 32px;

            img {
              width: 32px;
              height: 32px;
            }
          }

          .coin-name {
            margin-left: 10px;
            width: 85px;
            height: 34px;

            .upper-name {
              height: 20px;
              line-height: 20px;
            }

            .letter-name {
              height: 14px;
              line-height: 14px;
            }
          }

          .coin-echars {
            width: 60px;
            height: 35px;
          }

          .coin-price {
            margin-left: 13px;
            width: 75px;
            height: 38px;

            .upper-price {
              height: 20px;
              line-height: 20px;
              text-align: right;
            }

            .letter-price {
              height: 16px;
              line-height: 16px;
              text-align: right;
            }
          }
        }

        .item-right {
          margin-left: 8px;
          width: 61px;
          height: 25px;
          line-height: 25px;
          text-align: center;
          background: #45b26b;
          border-radius: 5px;
        }
      }
    }
  }

//
//  //xin
//.body-item {
//  display: flex;
//  justify-content: space-between;
//  align-items: center;
//  padding: 10px 15px;
//  border-bottom: 1px solid #f5f5f5;
//}
//.item-left {
//  display: flex;
//  align-items: center;
//  gap: 10px;
//}
//.coin-img img {
//  width: 32px;
//  height: 32px;
//  border-radius: 50%;
//  object-fit: cover;
//}
///* .upper-name { font-weight: bold; font-size: 15px; color: #333; }
//.letter-name { font-size: 12px; color: #999; }
//.upper-price { font-weight: bold; font-size: 15px; margin-left: 10px; color: #333; } */
//
///* 右侧涨跌幅按钮 */
//.item-right {
//  padding: 6px 12px;
//  border-radius: 4px;
//  /* color: white; */
//  /* font-weight: 500;
//  font-size: 13px; */
//  min-width: 75px;
//  text-align: center;
//  transition: background-color 0.3s;
//}
/* 颜色配置 */
.bg-green { background-color: #2EBD85; }
.bg-red { background-color: #F6465D; }
.bg-gray { background-color: #C0C0C0; }
</style>
