<template>
  <div class="market-conditions" @click="closePopups">
    <!-- 1. 头部行情 -->
    <div class="market-price">
      <div class="price-left">
        <div class="left-price pf400 fs14 fc333333">实时价格</div>
        <div
          class="left-number pf600 fs20 fc1F2937"
          :class="getPriceColor(marketInfo.change)">
          {{ formatNumber(marketInfo.price) }}
        </div>
        <div class="left-appro pf500 fs14 fcA8A8A8">
          ≈{{ formatNumber(marketInfo.fiatPrice) }}
          <span class="appro pf500 fs14" :class="getUpDownClass(marketInfo.change)">
            {{ marketInfo.change > 0 ? "+" : "" }}{{ marketInfo.change }}%
          </span>
        </div>
      </div>
      <div class="price-right">
        <div class="right-number-top">
          <div class="right-number-top-price">
            <div class="pf400 fs10 fcA8A8A8">24h 最高价</div>
            <div class="pf400 fs10 fc2C3131">{{ formatNumber(marketInfo.high) }}</div>
          </div>
          <div class="right-number-top-number">
            <div class="pf400 fs10 fcA8A8A8">24h 成交量</div>
            <div class="pf400 fs10 fc2C3131">{{ abbreviateNumber(marketInfo.vol) }}</div>
          </div>
        </div>
        <div class="right-number-bottom">
          <div class="right-number-top-price">
            <div class="pf400 fs10 fcA8A8A8">24h 最低价</div>
            <div class="pf400 fs10 fc2C3131">{{ formatNumber(marketInfo.low) }}</div>
          </div>
          <div class="right-number-top-number">
            <div class="pf400 fs10 fcA8A8A8">24h 成交额</div>
            <div class="pf400 fs10 fc2C3131">
              {{ abbreviateNumber(marketInfo.amount) }}
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 2. 周期切换 Tab -->
    <nav class="time-tabs">
      <div
        v-for="tab in visibleTabs"
        :key="tab"
        class="tab-item"
        :style="currentTab === tab ? { backgroundColor: '#F6465D', color: '#fff' } : {}"
        @click.stop="switchPeriod(tab)">
        {{ getTabLabel(tab) }}
      </div>

      <div
        class="tab-item icon-btn"
        @click.stop="toggleMore"
        :style="isMoreActive ? { backgroundColor: '#F6465D', color: '#fff' } : {}">
        <span :class="{ 'active-text': isMoreActive }">{{
          isMoreActive ? getTabLabel(currentTab) : "更多"
        }}</span>
        <span class="triangle" :style="isMoreActive ? { color: '#fff' } : {}">◢</span>
        <div class="dropdown-menu" v-show="showMoreMenu">
          <div
            v-for="mt in moreTabs"
            :key="mt"
            class="drop-item"
            :class="{ active: currentTab === mt }"
            @click.stop="switchPeriod(mt)">
            {{ getTabLabel(mt) }}
          </div>
        </div>
      </div>

      <div class="tab-item icon-btn" @click.stop="toggleIndicators">
        <img src="@/assets/icon/bitcoin/lishidingdan.svg" alt="" />
      </div>
    </nav>

    <!-- 3. 指标设置面板 -->
    <div class="indicator-panel" v-show="showIndicatorMenu" @click.stop>
      <div class="panel-section">
        <div class="section-title">主图指标</div>
        <div class="btn-group">
          <div
            v-for="m in ['MA', 'EMA', 'BOLL', 'SAR']"
            :key="m"
            class="idx-btn"
            :class="{ active: mainIdx === m }"
            @click="changeMain(m)">
            {{ m }}
          </div>
          <div
            class="idx-btn"
            :class="{ active: mainIdx === 'Hide' }"
            @click="changeMain('Hide')">
            隐藏
          </div>
        </div>
      </div>
      <div class="panel-section">
        <div class="section-title">副图指标 (可多选)</div>
        <div class="btn-group">
          <div
            v-for="s in ['VOL', 'MACD', 'KDJ', 'RSI', 'WR', 'CCI', 'OBV']"
            :key="s"
            class="idx-btn"
            :class="{ active: subIdx.includes(s) }"
            @click="toggleSub(s)">
            {{ s }}
          </div>
          <div class="idx-btn" :class="{ active: subIdx.length === 0 }" @click="clearSub">
            隐藏
          </div>
        </div>
      </div>
    </div>

    <!-- 4. K线图组件 -->
    <div class="k-line-main">
      <KLineChart
        ref="klineRef"
        :data="kLineData"
        height="70vh"
        :precision="{ price: getPricePrecision(marketInfo.price), volume: 2 }"
        @load-more="handleLoadMore" />
    </div>

    <!-- 5. 底部原有的 委托挂单/最新成交 -->
    <div class="notifi-classifi">
      <div
        class="pf600 fs14"
        :class="current === 'entrustingOrder' ? 'fc121212' : 'fcA8A8A8'"
        @click="messageChange('entrustingOrder')">
        委托挂单
      </div>
      <div
        class="sys-notifi pf600 fs14"
        :class="current === 'latestTransactions' ? 'fc121212' : 'fcA8A8A8'"
        @click="messageChange('latestTransactions')">
        最新成交
      </div>
    </div>

    <component
      :is="currentComponent"
      :symbol-id="symbolId"
      :latestTransactionData="latestTransactionData"
      :orderPlacement="orderPlacement" />

    <div
      style="
        box-shadow: 0 -0.05333rem 0.26667rem rgba(109 109 109 / 5%);
        box-sizing: border-box;
        margin-top: 20px;
        width: 100%;
        z-index: 99;
        position: sticky;
        bottom: 0;
        background-color: #ffffff;
        padding: 20px;
      ">
      <div
        @click="router.push('/bitcoin/CryptocurrencyTrading')"
        style="
          font-size: 17px;
          margin: 0 auto;
          border-radius: 19px;
          color: #ffffff;
          text-align: center;
          width: 80%;
          line-height: 38px;
          font-weight: 500;
          background-color: #f6465d;
        ">
        交易
      </div>
    </div>
  </div>
</template>

<script setup>
  import { ref, computed, onMounted, onBeforeUnmount, watch } from "vue";
  import { useRoute, useRouter } from "vue-router";
  import { GetCandlestickChart } from "@/api/index.js";

  const router = useRouter(); // 【新增】 实例化路由

  // 引入组件
  import KLineChart from "@/views/bitcoin/lever/components/KLineChart.vue";
  import EntrustingOrder from "./EntrustingOrder.vue";
  import LatestTransactions from "./LatestTransactions.vue";

  const route = useRoute();
  const symbolId = computed(() => route.query.id || "6");

  // --- 周期 ---
  const currentTab = ref("1d");
  const visibleTabs = ["15m", "1h", "4h", "1d"];
  const moreTabs = ["1m", "5m", "30m", "1w", "1M"];
  const isMoreActive = computed(() => moreTabs.includes(currentTab.value));
  const getTabLabel = (t) =>
    ({
      "1m": "1分",
      "5m": "5分",
      "15m": "15分",
      "30m": "30分",
      "1h": "1小时",
      "4h": "4小时",
      "1d": "日线",
      "1w": "周线",
      "1M": "月线",
    }[t] || t);

  // --- 指标管理 ---
  const showMoreMenu = ref(false);
  const showIndicatorMenu = ref(false);
  const klineRef = ref(null);
  const mainIdx = ref("MA");
  const subIdx = ref(["VOL", "MACD"]);

  const changeMain = (name) => {
    mainIdx.value = name;
    if (klineRef.value) klineRef.value.setMainIndicator(name);
  };
  const toggleSub = (name) => {
    const index = subIdx.value.indexOf(name);
    if (index > -1) subIdx.value.splice(index, 1);
    else {
      if (subIdx.value.length >= 3) subIdx.value.shift();
      subIdx.value.push(name);
    }
    if (klineRef.value) klineRef.value.setSubIndicators(subIdx.value);
  };
  const clearSub = () => {
    subIdx.value = [];
    if (klineRef.value) klineRef.value.setSubIndicators([]);
  };

  const toggleMore = () => {
    showIndicatorMenu.value = false;
    showMoreMenu.value = !showMoreMenu.value;
  };
  const toggleIndicators = () => {
    showMoreMenu.value = false;
    showIndicatorMenu.value = !showIndicatorMenu.value;
  };
  const closePopups = () => {
    showMoreMenu.value = false;
    showIndicatorMenu.value = false;
  };

  const switchPeriod = (period) => {
    if (currentTab.value === period) return;
    currentTab.value = period;
    showMoreMenu.value = false;
    kLineData.value = [];
    getKlineData();
  };

  // --- 数据/WS ---
  const kLineData = ref([]);
  const socket = ref(null);
  const WS_BASE_URL = "wss://test2.66linknow.com/ws/kline/";
  const HEARTBEAT_INTERVAL = 15000;
  const RECONNECT_DELAY = 3000;
  let heartbeatTimer = null,
    reconnectTimer = null,
    isUnmounted = false;
  const isLoadingMore = ref(false);

  const marketInfo = ref({
    price: "0.00",
    fiatPrice: "0.00",
    change: 0.0,
    high: "0.00",
    low: "0.00",
    vol: "0",
    amount: "0",
  });

  const orderPlacement = ref();
  const latestTransactionData = ref();
  const current = ref("entrustingOrder");
  const componentsMap = {
    entrustingOrder: EntrustingOrder,
    latestTransactions: LatestTransactions,
  };
  const currentComponent = computed(() => componentsMap[current.value]);
  const messageChange = (key) => (current.value = key);

  // --- 获取 K线数据 (核心) ---
  const getKlineData = async (endTime = null) => {
    if (typeof GetCandlestickChart !== "function") return;

    try {
      const params = {
        symbol: symbolId.value,
        period: currentTab.value,
        limit: 150,
        to: endTime || undefined,
      };

      const res = await GetCandlestickChart(params);

      let rawList = Array.isArray(res) ? res : res && res.data ? res.data : [];

      if (rawList.length > 0) {
        const formattedData = rawList.map((item) => ({
          timestamp: Number(item[0]),
          open: parseFloat(item[1]),
          high: parseFloat(item[2]),
          low: parseFloat(item[3]),
          close: parseFloat(item[4]),
          volume: parseFloat(item[5]),
        }));

        // 保证按时间升序
        formattedData.sort((a, b) => a.timestamp - b.timestamp);

        if (endTime) {
          // --- 加载历史模式 ---
          if (klineRef.value) {
            const hasMore = formattedData.length >= 150;
            // 核心点：子组件 KLineChart 内部现在会自动处理 overlap
            klineRef.value.applyHistoryData(formattedData, hasMore);
          }
        } else {
          // --- 初始化/重置模式 ---
          kLineData.value = formattedData;
          if (formattedData.length > 0) {
            const lastBar = formattedData[formattedData.length - 1];
            marketInfo.value = {
              ...marketInfo.value,
              price: lastBar.close,
              fiatPrice: lastBar.close,
              high: lastBar.high,
              low: lastBar.low,
            };
          }
        }
      } else {
        // 没数据了
        if (endTime && klineRef.value) {
          klineRef.value.applyHistoryData([], false);
        }
      }
    } catch (error) {
      console.error("API Error", error);
      if (endTime && klineRef.value) {
        // 发生错误时也要告知 KLineChart 停止加载，否则 loading 动画会一直转
        klineRef.value.applyHistoryData([], false);
      }
    } finally {
      isLoadingMore.value = false;
    }
  };

  const handleLoadMore = (timestamp) => {
    if (isLoadingMore.value) return;
    isLoadingMore.value = true;
    getKlineData(timestamp);
  };

  // --- WebSocket ---
  const connectWebSocket = () => {
    closeWebSocket();
    const symbolStr = String(route.query.type || "btcusdt").toLowerCase();
    const url = `${WS_BASE_URL}?symbol=${symbolStr}`;
    try {
      socket.value = new WebSocket(url);
      socket.value.onopen = () => startHeartbeat();
      socket.value.onmessage = (event) => handleSocketMessage(event.data);
      socket.value.onclose = () => {
        stopHeartbeat();
        if (!isUnmounted) {
          clearTimeout(reconnectTimer);
          reconnectTimer = setTimeout(() => connectWebSocket(), RECONNECT_DELAY);
        }
      };
    } catch (e) {
      if (!isUnmounted)
        reconnectTimer = setTimeout(() => connectWebSocket(), RECONNECT_DELAY);
    }
  };

  const closeWebSocket = () => {
    if (socket.value) {
      socket.value.close();
      socket.value = null;
    }
    stopHeartbeat();
    clearTimeout(reconnectTimer);
  };
  const startHeartbeat = () => {
    stopHeartbeat();
    heartbeatTimer = setInterval(() => {
      socket.value?.readyState === 1 && socket.value.send("ping");
    }, HEARTBEAT_INTERVAL);
  };
  const stopHeartbeat = () => {
    clearInterval(heartbeatTimer);
    heartbeatTimer = null;
  };

  const handleSocketMessage = (msgStr) => {
    try {
      if (msgStr === "pong") return;
      const rawData = JSON.parse(msgStr);
      const msg = rawData.data || rawData;
      if (msg.e === "kline") {
        const k = msg.k;
        if (k.i !== currentTab.value) return;
        const newBar = {
          timestamp: Number(k.t),
          open: parseFloat(k.o),
          high: parseFloat(k.h),
          low: parseFloat(k.l),
          close: parseFloat(k.c),
          volume: parseFloat(k.v),
        };
        updateKlineData(newBar);
        marketInfo.value.price = newBar.close;
        marketInfo.value.fiatPrice = newBar.close;
      } else if (msg.e === "24hrTicker") {
        marketInfo.value.change = parseFloat(msg.P).toFixed(2);
        marketInfo.value.high = msg.h;
        marketInfo.value.low = msg.l;
        marketInfo.value.vol = msg.v;
        marketInfo.value.amount = msg.q;
      } else if (rawData.stream?.includes("@depth20"))
        orderPlacement.value = rawData.data;
      else if (rawData.stream?.includes("@aggTrade"))
        latestTransactionData.value = rawData.data;
    } catch (e) {}
  };

  const updateKlineData = (newBar) => {
    if (!kLineData.value?.length) {
      kLineData.value = [newBar];
      return;
    }
    const lastIndex = kLineData.value.length - 1;
    const lastBar = kLineData.value[lastIndex];
    // 简单的 WebSocket 去重
    if (newBar.timestamp === lastBar.timestamp)
      kLineData.value.splice(lastIndex, 1, newBar);
    else if (newBar.timestamp > lastBar.timestamp) kLineData.value.push(newBar);
  };

  const handleVisibilityChange = () => {
    if (document.visibilityState === "visible" && socket.value?.readyState !== 1)
      connectWebSocket();
  };
  onMounted(() => {
    isUnmounted = false;
    getKlineData();
    connectWebSocket();
    document.addEventListener("visibilitychange", handleVisibilityChange);
  });
  onBeforeUnmount(() => {
    isUnmounted = true;
    closeWebSocket();
    document.removeEventListener("visibilitychange", handleVisibilityChange);
  });
  watch(symbolId, () => {
    kLineData.value = [];
    getKlineData();
    connectWebSocket();
  });
  const formatNumber = (num) =>
    num
      ? Number(num).toLocaleString("en-US", {
          minimumFractionDigits: 2,
          maximumFractionDigits: 6,
        })
      : "0.00";
  const abbreviateNumber = (v) => {
    if (!v) return "0.00";
    let n = parseFloat(v);
    if (n >= 1e9) return (n / 1e9).toFixed(2) + "B";
    if (n >= 1e6) return (n / 1e6).toFixed(2) + "M";
    if (n >= 1e3) return (n / 1e3).toFixed(2) + "K";
    return n.toFixed(2);
  };
  const getPricePrecision = (p) => (p < 1 ? 6 : p < 10 ? 4 : 2);
  const getPriceColor = (c) => (c >= 0 ? "fc45B26B" : "fcF6465D");
  const getUpDownClass = (c) => (c >= 0 ? "fc45B26B" : "fcF6465D");
</script>

<style lang="less" scoped>
  .fc45B26B {
    color: #2ebd85 !important;
  }
  .fcF6465D {
    color: #f6465d !important;
  }
  .fc1F2937 {
    color: #1f2937;
  }
  .time-tabs {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    box-sizing: border-box;
    padding: 5px 0 15px 15px;
    position: relative;
    z-index: 20;
  }
  .tab-item {
    font-size: 14px;
    color: #929aa5;
    padding: 4px 8px;
    border-radius: 4px;
    cursor: pointer;
    font-weight: 500;
    display: flex;
    align-items: center;
    position: relative;
  }
  .tab-item.icon-btn {
    padding: 4px 4px;
  }
  .active-text {
    color: #fff;
    font-weight: 600;
  }
  .triangle {
    font-size: 8px;
    margin-left: 2px;
    transform: scale(0.9);
  }
  .tab-item img {
    display: block;
    height: 16px;
    width: auto;
  }
  .dropdown-menu {
    position: absolute;
    top: 30px;
    left: -20px;
    width: 80px;
    background: #fff;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    border-radius: 6px;
    padding: 5px 0;
    z-index: 100;
    display: flex;
    flex-direction: column;
  }
  .drop-item {
    padding: 8px 15px;
    font-size: 13px;
    color: #666;
    text-align: center;
  }
  .drop-item.active {
    color: #f6465d;
    background: #fff5f5;
  }
  .indicator-panel {
    position: absolute;
    top: 155px;
    left: 15px;
    right: 15px;
    background: #fff;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
    border-radius: 8px;
    padding: 15px;
    z-index: 99;
  }
  .panel-section {
    margin-bottom: 15px;
  }
  .section-title {
    font-size: 12px;
    color: #999;
    margin-bottom: 8px;
  }
  .btn-group {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }
  .idx-btn {
    padding: 4px 12px;
    border: 1px solid #eee;
    border-radius: 14px;
    font-size: 12px;
    color: #666;
    cursor: pointer;
  }
  .idx-btn.active {
    border-color: #f6465d;
    color: #f6465d;
    background-color: #fff5f5;
  }
  .market-conditions {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    position: relative;
    min-height: 100vh;
    background: #fff;
  }
  .market-price {
    display: flex;
    justify-content: space-between;
    margin-top: 4px;
    width: 100%;
    padding: 0 15px;
    box-sizing: border-box;
    .price-left {
      display: flex;
      line-height: 20px;
      flex-direction: column;
      width: 144px;
      .left-price {
        height: 18px;
        line-height: 18px;
      }
      .left-number {
        margin-top: 5px;
      }
      .left-appro {
        margin-top: 3px;
        .appro {
          margin-left: 9px;
        }
      }
    }
    .price-right {
      display: flex;
      flex-direction: column;
      height: 100%;
      .right-number-top,
      .right-number-bottom {
        display: flex;
        justify-content: flex-end;
        width: 100%;
        height: 32px;
        .right-number-top-price,
        .right-number-top-number {
          margin-left: 10px;
          text-align: right;
          div {
            height: 16px;
            line-height: 16px;
            text-align: end;
          }
        }
      }
    }
  }
  .k-line-main {
    height: 50vh;
    min-height: 350px;
    width: 100%;
    padding: 0 15px;
  }
  .notifi-classifi {
    display: flex;
    align-items: flex-end;
    margin-top: 140px;
    width: 100%;
    padding: 0 15px 0 15px;
    box-sizing: border-box;
    height: 24px;
    .sys-notifi {
      margin-left: 47px;
    }
  }
</style>
