<script setup lang="ts">
import type { Treaty } from "@elysiajs/eden";
import { client, safeClient } from "@/api";
import { tradeWebSocket } from "@/tradingview/websocket";

type Item = Treaty.Data<typeof client.api.trading_pairs.orderbook.get>;

const props = defineProps<{
  symbol: string;
}>();
const socket = tradeWebSocket.getSocket();

const { data } = await safeClient(client.api.trading_pairs.orderbook.get({ query: { symbol: props.symbol, depth: 5 } }));

const latestPrice = computed(() => {
  if (!data.value || !data.value.asks?.length || !data.value.bids?.length) {
    return "0.00";
  }
  const askPrice = Number(data.value.asks[0].price);
  const bidPrice = Number(data.value.bids[0].price);
  const price = ((askPrice + bidPrice) / 2).toFixed(2);
  return price;
});

function getTotal(item: Item["asks" | "bids"][number]) {
  const price = Number(item.price);
  const quantity = Number(item.quantity);
  return (price * quantity).toFixed(2);
}
function getDepthPercent(items?: Item["asks" | "bids"], index?: number) {
  if (!items || index === undefined)
    return 0;
  const totalValues = items.map(item => Number(item.price) * Number(item.quantity));
  const maxTotal = Math.max(...totalValues);
  const itemTotal = totalValues[index];
  return (itemTotal / maxTotal) * 100;
}
function subscribe() {
  socket.send({
    action: "subscribe",
    channels: [{
      name: "depth",
      symbol: props.symbol,
    }],
  });
}
function unsubscribe() {
  socket.send({
    action: "unsubscribe",
    channels: [{
      name: "depth",
      symbol: props.symbol,
    }],
  });
}

// 监听订单簿更新
socket.subscribe((message) => {
  const data = message.data;
});

watch(() => props.symbol, (newSymbol, oldSymbol) => {
  if (newSymbol === oldSymbol)
    return;
  unsubscribe();
  subscribe();
});

onMounted(() => {
  subscribe();
});

onUnmounted(() => {
  unsubscribe();
});
</script>

<template>
  <div class="order-book">
    <!-- 卖单 (asks) - 从下往上排列 -->
    <div class="asks-section">
      <div
        v-for="(ask, index) in data?.asks"
        :key="`ask-${index}`"
        class="order-item ask-item"
      >
        <div
          class="depth-bg ask-depth"
          :style="{ width: `${getDepthPercent(data?.asks, index)}%` }"
        />
        <div class="order-content">
          <span class="price text-danger-500">{{ Number(ask.price).toString() }}</span>
          <span class="amount">{{ Number(ask.quantity).toString() }}</span>
          <span class="total">{{ getTotal(ask) }}</span>
        </div>
      </div>
    </div>

    <!-- 中间分隔 - 显示最新成交价 -->
    <div class="spread-section">
      <div class="flex flex-col py-2">
        <div class="text-lg font-semibold text-success-500">
          {{ latestPrice }}
        </div>
        <div class="text-xs text-text-500">
          ≈ ${{ Number(latestPrice).toLocaleString('en-US') }}
        </div>
      </div>
    </div>

    <!-- 买单 (bids) -->
    <div class="bids-section">
      <div
        v-for="(bid, index) in data?.bids"
        :key="`bid-${index}`"
        class="order-item bid-item"
      >
        <div
          class="depth-bg bid-depth"
          :style="{ width: `${getDepthPercent(data?.bids, index)}%` }"
        />
        <div class="order-content">
          <span class="price text-success-500">{{ Number(bid.price).toString() }}</span>
          <span class="amount">{{ Number(bid.quantity).toString() }}</span>
          <span class="total">{{ getTotal(bid) }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.order-book {
  font-size: 12px;
  user-select: none;
  padding-left: 8px;
}

.asks-section,
.bids-section {
  position: relative;
}

.order-item {
  position: relative;
  height: 20px;
  display: flex;
  align-items: center;
}

.depth-bg {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  transition: width 0.3s ease;
}

.ask-depth {
  background: rgba(239, 68, 68, 0.1);
}

.bid-depth {
  background: rgba(34, 197, 94, 0.1);
}

.order-content {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  padding: 0 12px;
  z-index: 1;
}

.price {
  font-weight: 500;
}

.amount,
.total {
  color: var(--ion-text-color);
  text-align: right;
}

.spread-section {
  border-top: 1px solid var(--ion-border-color);
  border-bottom: 1px solid var(--ion-border-color);
  background: var(--ion-background-color);
}
</style>
