<template>
    <view class="detail-page">
        <!-- 状态栏占位 -->
        <view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>

        <!-- 导航栏 -->
        <view class="navbar">
            <view class="navbar__back" @tap="goBack">
                <u-icon name="arrow-left" size="36" color="#333" />
            </view>
            <view class="navbar__center">
                <view class="navbar__logo" :style="{ background: coinColor + '18' }">
                    <text class="navbar__logo-text" :style="{ color: coinColor }">{{ coinIcon }}</text>
                </view>
                <text class="navbar__title">{{ symbol }}/USDT</text>
            </view>
            <view class="navbar__right" @tap="showSharePopup = true">
                <u-icon name="share" size="36" color="#333" />
            </view>
        </view>

        <scroll-view scroll-y class="detail-scroll" :style="{ height: scrollHeight + 'px' }">
            <!-- 价格区域 -->
            <view class="price-section">
                <view class="price-section__main">
                    <text class="price-section__value">${{ tickerData?.price || '--' }}</text>
                    <view class="price-section__badge" :class="changeClass">
                        <text class="price-section__badge-arrow">{{ changeArrow }}</text>
                        <text class="price-section__badge-text">{{ changeText }}</text>
                    </view>
                </view>
                <text class="price-section__name">{{ coinName }}</text>
            </view>

            <!-- 时间周期切换 -->
            <scroll-view scroll-x class="period-scroll">
                <view class="period-tabs">
                    <view v-for="(p, i) in periods" :key="p.key" class="period-tab"
                        :class="{ active: currentPeriod === i }" @tap="switchPeriod(i)">
                        <text>{{ p.label }}</text>
                    </view>
                </view>
            </scroll-view>

            <!-- K线走势图 -->
            <view class="chart-section" :style="{ minHeight: chartHeight + 'px' }">
                <view v-if="chartLoading" class="chart-loading" :style="{ height: chartHeight + 'px' }">
                    <u-loading mode="circle" />
                </view>
                <canvas v-else canvas-id="klineCanvas" id="klineCanvas" class="chart-canvas"
                    :style="{ width: chartWidth + 'px', height: chartHeight + 'px' }" />
            </view>

            <!-- 24h 数据 -->
            <view class="stats-section">
                <view class="stats-row">
                    <view class="stat-item">
                        <text class="stat-item__label">24h 最高</text>
                        <text class="stat-item__value up">${{ tickerData?.highPrice || '--' }}</text>
                    </view>
                    <view class="stat-item">
                        <text class="stat-item__label">24h 最低</text>
                        <text class="stat-item__value down">${{ tickerData?.lowPrice || '--' }}</text>
                    </view>
                </view>
                <view class="stats-row">
                    <view class="stat-item">
                        <text class="stat-item__label">24h 成交额</text>
                        <text class="stat-item__value">{{ tickerData?.volume || '--' }}</text>
                    </view>
                    <view class="stat-item">
                        <text class="stat-item__label">24h 涨跌</text>
                        <text class="stat-item__value" :class="changeClass">{{ changeText }}</text>
                    </view>
                </view>
            </view>

            <!-- K线数据概览 -->
            <view class="kline-summary" v-if="klineData.length">
                <view class="section-title">
                    <text>走势概览</text>
                </view>
                <view class="stats-row">
                    <view class="stat-item">
                        <text class="stat-item__label">区间最高</text>
                        <text class="stat-item__value up">${{ klineHigh }}</text>
                    </view>
                    <view class="stat-item">
                        <text class="stat-item__label">区间最低</text>
                        <text class="stat-item__value down">${{ klineLow }}</text>
                    </view>
                </view>
                <view class="stats-row">
                    <view class="stat-item">
                        <text class="stat-item__label">开盘价</text>
                        <text class="stat-item__value">${{ klineOpen }}</text>
                    </view>
                    <view class="stat-item">
                        <text class="stat-item__label">最新价</text>
                        <text class="stat-item__value">${{ klineClose }}</text>
                    </view>
                </view>
            </view>

            <!-- 币种信息 -->
            <view class="info-section">
                <view class="section-title">
                    <text>币种信息</text>
                </view>
                <view class="info-rows">
                    <view class="info-row">
                        <text class="info-row__label">交易对</text>
                        <text class="info-row__value">{{ symbol }}/USDT</text>
                    </view>
                    <view class="info-row">
                        <text class="info-row__label">全称</text>
                        <text class="info-row__value">{{ coinName }}</text>
                    </view>
                    <view class="info-row">
                        <text class="info-row__label">数据来源</text>
                        <text class="info-row__value">Binance</text>
                    </view>
                </view>
            </view>

            <view style="height: 60rpx"></view>
        </scroll-view>

        <share-popup v-if="showSharePopup" v-model:show="showSharePopup" page-type="crypto" :page-id="symbol"
            :path="`/pages/crypto/crypto_detail?symbol=${symbol}`" :title="symbol + '/USDT 行情'" />
    </view>
</template>

<script lang="ts" setup>
import { ref, computed, nextTick, onUnmounted } from 'vue'
import { onLoad, onShow, onHide } from '@dcloudio/uni-app'
import SharePopup from '@/components/share-popup/share-popup.vue'
import {
    getBinanceSingleTicker,
    getBinanceKline,
    getCoinConfig,
    formatPrice,
    type CoinTicker,
    type KlinePoint
} from '@/api/crypto'

const statusBarHeight = ref(0)
const scrollHeight = ref(600)
const chartWidth = ref(350)

const symbol = ref('')
const coinName = ref('')
const coinIcon = ref('')
const coinColor = ref('#666')

const tickerData = ref<CoinTicker | null>(null)
const klineData = ref<KlinePoint[]>([])
const chartLoading = ref(true)
const showSharePopup = ref(false)

const periods = [
    { label: '1H', key: '1h', interval: '5m', limit: 12 },
    { label: '4H', key: '4h', interval: '15m', limit: 16 },
    { label: '1D', key: '1d', interval: '1h', limit: 24 },
    { label: '1W', key: '1w', interval: '4h', limit: 42 },
    { label: '1M', key: '1m', interval: '1d', limit: 30 },
    { label: '3M', key: '3m', interval: '1d', limit: 90 },
    { label: '6M', key: '6m', interval: '3d', limit: 60 },
    { label: '1Y', key: '1y', interval: '1w', limit: 52 },
    { label: 'ALL', key: 'all', interval: '1M', limit: 100 }
]
const currentPeriod = ref(2)
const chartHeight = computed(() => currentPeriod.value >= 5 ? 280 : 200)

const changeClass = computed(() => {
    if (!tickerData.value) return ''
    return tickerData.value.change >= 0 ? 'up' : 'down'
})
const changeArrow = computed(() => {
    if (!tickerData.value) return ''
    return tickerData.value.change >= 0 ? '▲' : '▼'
})
const changeText = computed(() => {
    if (!tickerData.value) return '--'
    return Math.abs(tickerData.value.change).toFixed(2) + '%'
})

const klineHigh = computed(() => {
    if (!klineData.value.length) return '--'
    return formatPrice(Math.max(...klineData.value.map((k) => k.high)))
})
const klineLow = computed(() => {
    if (!klineData.value.length) return '--'
    return formatPrice(Math.min(...klineData.value.map((k) => k.low)))
})
const klineOpen = computed(() => {
    if (!klineData.value.length) return '--'
    return formatPrice(klineData.value[0].open)
})
const klineClose = computed(() => {
    if (!klineData.value.length) return '--'
    return formatPrice(klineData.value[klineData.value.length - 1].close)
})

const goBack = () => {
    const pages = getCurrentPages()
    if (pages.length > 1) {
        uni.navigateBack({ delta: 1 })
    } else {
        uni.switchTab({ url: '/pages/crypto/crypto' })
    }
}

const fetchTicker = async () => {
    console.log('[CryptoDetail] fetchTicker symbol=>', symbol.value)
    try {
        tickerData.value = await getBinanceSingleTicker(symbol.value)
        console.log('[CryptoDetail] ticker ok price=>', tickerData.value?.price)
    } catch (e) {
        console.error('[CryptoDetail] fetchTicker error=>', e)
    }
}

const fetchKline = async () => {
    const p = periods[currentPeriod.value]
    console.log('[CryptoDetail] fetchKline symbol=>', symbol.value, 'interval=>', p.interval, 'limit=>', p.limit)
    chartLoading.value = true
    try {
        klineData.value = await getBinanceKline(symbol.value, p.interval, p.limit)
        console.log('[CryptoDetail] kline ok count=>', klineData.value.length)
        await nextTick()
        setTimeout(() => drawChart(), 50)
    } catch (e) {
        console.error('[CryptoDetail] fetchKline error=>', e)
    } finally {
        chartLoading.value = false
    }
}

const switchPeriod = (i: number) => {
    if (currentPeriod.value === i) return
    currentPeriod.value = i
    fetchKline()
}

const drawChart = () => {
    const data = klineData.value
    if (!data.length) return

    const ctx = uni.createCanvasContext('klineCanvas')
    const w = chartWidth.value
    const h = chartHeight.value
    const padding = { top: 20, bottom: 40, left: 10, right: 10 }
    const drawW = w - padding.left - padding.right
    const drawH = h - padding.top - padding.bottom

    const closes = data.map((k) => k.close)
    const minVal = Math.min(...data.map((k) => k.low))
    const maxVal = Math.max(...data.map((k) => k.high))
    const range = maxVal - minVal || 1

    ctx.clearRect(0, 0, w, h)

    // 背景网格
    ctx.setStrokeStyle('rgba(0,0,0,0.04)')
    ctx.setLineWidth(0.5)
    for (let i = 0; i <= 4; i++) {
        const y = padding.top + (drawH / 4) * i
        ctx.beginPath()
        ctx.moveTo(padding.left, y)
        ctx.lineTo(w - padding.right, y)
        ctx.stroke()
    }

    // 价格刻度
    ctx.setFillStyle('#999')
    ctx.setFontSize(9)
    for (let i = 0; i <= 4; i++) {
        const val = maxVal - (range / 4) * i
        const y = padding.top + (drawH / 4) * i
        ctx.fillText(formatPrice(val), padding.left, y - 3)
    }

    // 渐变面积
    const stepX = drawW / (data.length - 1 || 1)
    const getY = (val: number) => padding.top + drawH - ((val - minVal) / range) * drawH

    // 面积填充
    const isUp = closes[closes.length - 1] >= closes[0]
    const areaColor = isUp ? 'rgba(255,44,88,0.08)' : 'rgba(0,196,130,0.08)'
    ctx.beginPath()
    ctx.moveTo(padding.left, getY(closes[0]))
    for (let i = 1; i < data.length; i++) {
        ctx.lineTo(padding.left + stepX * i, getY(closes[i]))
    }
    ctx.lineTo(padding.left + stepX * (data.length - 1), h - padding.bottom)
    ctx.lineTo(padding.left, h - padding.bottom)
    ctx.closePath()
    ctx.setFillStyle(areaColor)
    ctx.fill()

    // 折线
    const lineColor = isUp ? '#ff2c58' : '#00c482'
    ctx.beginPath()
    ctx.setStrokeStyle(lineColor)
    ctx.setLineWidth(2)
    ctx.moveTo(padding.left, getY(closes[0]))
    for (let i = 1; i < data.length; i++) {
        ctx.lineTo(padding.left + stepX * i, getY(closes[i]))
    }
    ctx.stroke()

    // 最新价格点
    const lastX = padding.left + stepX * (data.length - 1)
    const lastY = getY(closes[closes.length - 1])
    ctx.beginPath()
    ctx.arc(lastX, lastY, 4, 0, Math.PI * 2)
    ctx.setFillStyle(lineColor)
    ctx.fill()
    ctx.beginPath()
    ctx.arc(lastX, lastY, 2, 0, Math.PI * 2)
    ctx.setFillStyle('#fff')
    ctx.fill()

    // 时间刻度（历史周期显示日期标签）
    if (currentPeriod.value >= 5 && data.length > 1) {
        ctx.setFillStyle('#999')
        ctx.setFontSize(9)
        const labelCount = Math.min(5, data.length)
        const step = Math.floor((data.length - 1) / (labelCount - 1))
        for (let i = 0; i < labelCount; i++) {
            const idx = Math.min(i * step, data.length - 1)
            const d = new Date(data[idx].time)
            const label = `${d.getMonth() + 1}/${d.getDate()}`
            const x = padding.left + stepX * idx
            ctx.fillText(label, x - 10, h - 8)
        }
    }

    ctx.draw()
}

let refreshTimer: ReturnType<typeof setInterval> | null = null
const startRefresh = () => {
    stopRefresh()
    refreshTimer = setInterval(() => {
        fetchTicker()
    }, 15000)
}
const stopRefresh = () => {
    if (refreshTimer) {
        clearInterval(refreshTimer)
        refreshTimer = null
    }
}

onLoad((options: any) => {
    symbol.value = options?.symbol || 'BTC'
    console.log('[CryptoDetail] onLoad symbol=>', symbol.value)

    const config = getCoinConfig()
    const meta = config[symbol.value]
    if (meta) {
        coinName.value = meta.name
        coinIcon.value = meta.icon
        coinColor.value = meta.color
    } else {
        coinName.value = symbol.value
        coinIcon.value = symbol.value.charAt(0)
    }

    uni.getSystemInfo({
        success: (res) => {
            // #ifdef APP-PLUS || MP
            statusBarHeight.value = res.statusBarHeight || 44
            // #endif
            // #ifdef H5
            statusBarHeight.value = 0
            // #endif
            const navH = statusBarHeight.value + 44
            scrollHeight.value = res.windowHeight - navH
            chartWidth.value = res.windowWidth - 32
        }
    })

    fetchTicker()
    fetchKline()
})

onShow(() => startRefresh())
onHide(() => stopRefresh())
onUnmounted(() => stopRefresh())
</script>

<style lang="scss" scoped>
$bg: #ffffff;
$text-primary: #000000;
$text-secondary: #999999;
$border: rgba(0, 0, 0, 0.06);
$up: #ff2c58;
$down: #00c482;

.detail-page {
    background: $bg;
    min-height: 100vh;
}

.status-bar {
    background: $bg;
}

/* 导航栏 */
.navbar {
    display: flex;
    align-items: center;
    height: 88rpx;
    padding: 0 24rpx;
    background: $bg;

    &__back {
        width: 64rpx;
        height: 64rpx;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    &__center {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 12rpx;
    }

    &__logo {
        width: 56rpx;
        height: 56rpx;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    &__logo-text {
        font-size: 24rpx;
        font-weight: 700;
    }

    &__title {
        font-size: 32rpx;
        font-weight: 700;
        color: $text-primary;
    }

    &__right {
        width: 64rpx;
        height: 64rpx;
        display: flex;
        align-items: center;
        justify-content: center;
    }
}

/* 价格区域 */
.price-section {
    padding: 24rpx 32rpx 16rpx;

    &__main {
        display: flex;
        align-items: center;
        gap: 16rpx;
    }

    &__value {
        font-size: 56rpx;
        font-weight: 700;
        color: $text-primary;
        font-family: DINAlternate, 'Helvetica Neue', sans-serif;
    }

    &__badge {
        display: flex;
        align-items: center;
        gap: 4rpx;
        padding: 6rpx 16rpx;
        border-radius: 8rpx;

        &.up {
            background: rgba(255, 44, 88, 0.1);
        }

        &.down {
            background: rgba(0, 196, 130, 0.1);
        }
    }

    &__badge-arrow {
        font-size: 18rpx;

        .up & {
            color: $up;
        }

        .down & {
            color: $down;
        }
    }

    &__badge-text {
        font-size: 26rpx;
        font-weight: 600;

        .up & {
            color: $up;
        }

        .down & {
            color: $down;
        }
    }

    &__name {
        font-size: 26rpx;
        color: $text-secondary;
        margin-top: 8rpx;
    }
}

/* 时间周期 */
.period-scroll {
    white-space: nowrap;
    margin-bottom: 16rpx;
}

.period-tabs {
    display: inline-flex;
    padding: 0 32rpx;
    gap: 8rpx;
}

.period-tab {
    min-width: 80rpx;
    height: 60rpx;
    padding: 0 20rpx;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 24rpx;
    color: $text-secondary;
    background: #f5f5f5;
    border-radius: 12rpx;
    transition: all 0.2s;

    &.active {
        color: #fff;
        background: #333;
        font-weight: 600;
    }
}

/* 图表区 */
.chart-section {
    padding: 0 16rpx;
    margin-bottom: 24rpx;
    min-height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.chart-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 200px;
}

.chart-canvas {
    display: block;
}

/* 数据面板 */
.stats-section,
.kline-summary {
    padding: 0 32rpx;
    margin-bottom: 24rpx;
}

.section-title {
    font-size: 30rpx;
    font-weight: 700;
    color: $text-primary;
    margin-bottom: 20rpx;
    padding-bottom: 12rpx;
    border-bottom: 1rpx solid $border;
}

.stats-row {
    display: flex;
    gap: 24rpx;
    margin-bottom: 20rpx;
}

.stat-item {
    flex: 1;
    background: #f8f8f8;
    border-radius: 16rpx;
    padding: 20rpx 24rpx;

    &__label {
        font-size: 22rpx;
        color: $text-secondary;
        display: block;
        margin-bottom: 8rpx;
    }

    &__value {
        font-size: 28rpx;
        font-weight: 600;
        color: $text-primary;
        font-family: DINAlternate, 'Helvetica Neue', sans-serif;

        &.up {
            color: $up;
        }

        &.down {
            color: $down;
        }
    }
}

/* 币种信息 */
.info-section {
    padding: 0 32rpx;
    margin-bottom: 24rpx;
}

.info-rows {
    background: #f8f8f8;
    border-radius: 16rpx;
    overflow: hidden;
}

.info-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 24rpx;
    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);

    &:last-child {
        border-bottom: none;
    }

    &__label {
        font-size: 26rpx;
        color: $text-secondary;
    }

    &__value {
        font-size: 26rpx;
        font-weight: 500;
        color: $text-primary;
    }
}
</style>
