import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { get } from '@/utils/request'
import type { Ticker } from './futures'

const WS_URL = import.meta.env.VITE_WS_MARKET_URL as string

// 本地图标映射（API icon 字段目前均为 null）
const COIN_ICONS: Record<string, string> = {
  BTC:   '/coins/btc.png',
  ETH:   '/coins/eth.png',
  BNB:   '/coins/bnb.png',
  SOL:   '/coins/sol.png',
  XRP:   '/coins/xrp.png',
  ADA:   '/coins/ada.png',
  DOGE:  '/coins/doge.png',
  LTC:   '/coins/ltc.png',
  TRX:   '/coins/trx.png',
  DOT:   '/coins/dot.png',
  LINK:  '/coins/link.png',
  AVAX:  '/coins/avax.png',
  MATIC: '/coins/matic.png',
  UNI:   '/coins/uni.png',
  ATOM:  '/coins/atom.png',
  ETC:   '/coins/etc.png',
  FIL:   '/coins/fil.png',
  NEAR:  '/coins/near.png',
  OP:    '/coins/op.png',
  ARB:   '/coins/arb.png',
  BCH:   '/coins/bch.png',
  AAVE:  '/coins/aave.png',
  ALGO:  '/coins/algo.png',
  APE:   '/coins/ape.png',
  AXS:   '/coins/axs.png',
  CHZ:   '/coins/chz.png',
  SUSHI: '/coins/sushi.png',
  TRUMP: '/coins/trump.png',
}

// /swap/coin/enabled-list 返回的原始数据结构
interface RawCoinInfo {
  id: number
  name: string
  symbol: string       // "BTC/USDT"
  coinSymbol: string   // "BTC"
  baseSymbol: string   // "USDT"
  sort: number
  icon: string | null
  coinScale: number
  baseCoinScale: number
  stockType: number
}

// 内部维护的交易对对象
export interface CoinContract {
  id: number
  symbol: string       // "BTC/USDT"
  coinSymbol: string   // "BTC"
  baseSymbol: string   // "USDT"
  name: string
  icon: string
  sort: number
  coinScale: number
  baseCoinScale: number
  // 实时价格（WebSocket 更新）
  open: string
  high: string
  low: string
  close: string
  chg: string
  change: string
  volume: string
  turnover: string
  stockType: number
}

export const useCoinsStore = defineStore('coins', () => {
  const coins = ref<CoinContract[]>([])
  const loading = ref(false)
  const fetched = ref(false)

  let ws: WebSocket | null = null
  let wsDestroyed = false
  let pingTimer: ReturnType<typeof setInterval> | null = null
  let lastMsgTs = 0

  function startHeartbeat() {
    if (pingTimer !== null) clearInterval(pingTimer)
    lastMsgTs = Date.now()
    pingTimer = setInterval(() => {
      if (Date.now() - lastMsgTs > 30_000) {
        // 30s 无任何消息，触发重连
        stopHeartbeat()
        if (ws) { ws.onclose = null; ws.close(); ws = null }
        if (!wsDestroyed) startLivePrices()
        return
      }
      if (ws?.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify({ ping: Date.now() }))
      }
    }, 15_000)
  }

  function stopHeartbeat() {
    if (pingTimer !== null) { clearInterval(pingTimer); pingTimer = null }
  }

  function symSlug(sym: string) {
    return sym.toLowerCase().replace(/[/-]/g, '')
  }

  // Step 1: 请求接口获取交易对列表（名称、图标等静态信息）
  async function fetchCoins() {
    if (fetched.value && coins.value.length > 0) {
      // 允许外部在 stopLivePrices 后通过 fetchCoins 重新拉起订阅
      if (!ws || ws.readyState === WebSocket.CLOSED) {
        startLivePrices()
      }
      return
    }
    loading.value = true
    try {
      const data = await get<{ data: RawCoinInfo[] }>('/swap/coin/enabled-list')
      const list = data?.data ?? (Array.isArray(data) ? (data as RawCoinInfo[]) : [])
      if (list.length > 0) {
        coins.value = list
          .sort((a, b) => a.sort - b.sort)
          .map(raw => ({
            id: raw.id,
            symbol: raw.symbol,
            coinSymbol: raw.coinSymbol,
            baseSymbol: raw.baseSymbol,
            name: raw.name,
            icon: raw.icon ?? COIN_ICONS[raw.coinSymbol] ?? '',
            sort: raw.sort,
            coinScale: raw.coinScale ?? 2,
            baseCoinScale: raw.baseCoinScale ?? 4,
            // 价格字段初始为空，等 WebSocket 推送
            open: '0', high: '0', low: '0', close: '0',
            chg: '0', change: '0', volume: '0', turnover: '0',
			stockType: raw.stockType,
          }))
        fetched.value = true
        // Step 2: 订阅 WebSocket 获取实时价格和涨跌幅
        startLivePrices()
		// console.log("搜索列表数据：",coins.value)
      }
    } catch { /* silent */ }
    loading.value = false
  }

  // Step 2: WebSocket 订阅所有交易对的 ticker 数据
  function startLivePrices() {
    if (ws) { ws.onclose = null; ws.close() }
    wsDestroyed = false
    ws = new WebSocket(WS_URL)
    ws.onopen = () => {
      const topics = coins.value.map(c => `market.${symSlug(c.symbol)}.ticket`)
      if (topics.length) ws!.send(JSON.stringify({ sub: topics, id: 'coins-tickers' }))
      startHeartbeat()
    }
    ws.onmessage = (e) => {
      lastMsgTs = Date.now()
      let msg: any
      try { msg = JSON.parse(e.data) } catch { return }
      // 处理服务器 pong 回包
      if (msg.pong !== undefined) return
      const ch: string = msg.ch ?? ''
      const tick = msg.tick
      if (!ch.includes('.ticket') || !tick) return
      const coin = coins.value.find(c => `market.${symSlug(c.symbol)}.ticket` === ch)
      if (!coin) return
      const closeN = parseFloat(tick.c)
      const openN = parseFloat(tick.o)
      coin.close = tick.c
      coin.open = tick.o
      coin.high = tick.h
      coin.low = tick.l
      coin.volume = tick.v
      coin.turnover = tick.q
      coin.chg = openN > 0 ? String((closeN - openN) / openN) : '0'
      coin.change = openN > 0 ? String(closeN - openN) : '0'
    }
    ws.onerror = () => {}
    ws.onclose = () => {
      stopHeartbeat()
      if (wsDestroyed) return
      setTimeout(startLivePrices, 3000)
    }
  }

  function stopLivePrices() {
    wsDestroyed = true
    stopHeartbeat()
    if (ws) {
      if (ws.readyState === WebSocket.OPEN && coins.value.length > 0) {
        const topics = coins.value.map(c => `market.${symSlug(c.symbol)}.ticket`)
        ws.send(JSON.stringify({ unsub: topics, id: 'coins-tickers-unsub' }))
      }
      ws.onclose = null
      ws.close()
      ws = null
    }
  }

  // 转为 Ticker[] 格式，供 futures store 使用
  const asTickers = computed<Ticker[]>(() =>
    coins.value.map(c => ({
      symbol: c.symbol,
      open: c.open,
      high: c.high,
      low: c.low,
      close: c.close,
      chg: c.chg,
      change: c.change,
      volume: c.volume,
      turnover: c.turnover,
	  stockType: c.stockType,
    }))
  )

  return { coins, loading, fetched, asTickers, fetchCoins, stopLivePrices }
})
