<template>
    <view class="page" :style="rootStyle">
        <!-- ===== 统一运动律动视区 (Canvas 律动舞台) ===== -->
        <view class="stage-canvas-wrapper">
            <WalkerCanvas
                ref="walkerCanvasRef"
                :bpm="currentBpm"
                :is-playing="isPlaying"
                @toggle-play="onCenterTap"
            />
        </view>

        <!-- ===== 推荐档位(3 选 1) ===== -->
        <view class="presets">
            <view
                v-for="p in LOOP_PRESETS"
                :key="p.id"
                class="preset"
                :class="{ active: currentLoop === p.id }"
                @click="onPresetTap(p.id)"
            >
                <text class="preset-name">{{ p.label }}</text>
                <text class="preset-bpm">{{ p.bpm }} BPM</text>
                <text class="preset-desc">{{ p.desc }}</text>
            </view>
        </view>

        <!-- ===== 自定义节奏区域(含标题栏+折叠内容) ===== -->
        <view class="custom-section">
            <!-- 标题栏(始终显示) -->
            <view class="custom-header" @click="onToggleCustom">
                <text class="custom-title">{{ customExpanded ? '✕ 收起自定义' : '⚙ 自定义节奏' }}</text>
            </view>

            <!-- 折叠内容(仅展开时显示) -->
            <view v-if="customExpanded" class="custom-content">
                <!-- BPM 微调 -->
                <view class="row">
                    <text class="row-label">BPM</text>
                    <view class="bpm-stepper">
                        <view class="step-btn" @click="onBpmDelta(-5)">−5</view>
                        <view class="step-btn" @click="onBpmDelta(-1)">−1</view>
                        <view class="step-val">{{ currentBpm }}</view>
                        <view class="step-btn" @click="onBpmDelta(1)">+1</view>
                        <view class="step-btn" @click="onBpmDelta(5)">+5</view>
                    </view>
                </view>

                <!-- 拍号 -->
                <view class="row">
                    <text class="row-label">拍号</text>
                    <view class="meter-tabs">
                        <view
                            v-for="n in [2, 3, 4]"
                            :key="n"
                            class="meter-tab"
                            :class="{ active: customAccent === n }"
                            @click="onAccentSelect(n)"
                        >{{ n }}/4</view>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { onShow, onHide } from '@dcloudio/uni-app'
import { useMetronome } from '../hooks/useMetronome'
import WalkerCanvas from './components/walker-canvas.vue'

type LoopId = 'slow' | 'normal' | 'brisk'
interface LoopPreset {
    id: LoopId
    bpm: number
    label: string
    desc: string
}

const LOOP_PRESETS: readonly LoopPreset[] = [
    { id: 'slow', bpm: 80, label: '慢走', desc: '热身 · 恢复' },
    { id: 'normal', bpm: 110, label: '健走', desc: '日常 · 通勤' },
    { id: 'brisk', bpm: 130, label: '快走', desc: '提速 · 燃脂' },
]

const customExpanded = ref<boolean>(false)
const currentLoop = ref<LoopId | null>('normal')
const walkerCanvasRef = ref<any>(null)

/* click-wood.mp3 (CDN), 木鱼质感的敲击音 */
const CLICK_WOOD_URL =
    'https://gz-1349751149.cos.ap-guangzhou.myqcloud.com/uploads/file/20260526/202605261051282a0a94508.mp3'

// 统一采用高精度引擎，彻底抛弃卡顿的后台播放引擎
const fg = useMetronome({
    initialBpm: 110,
    accentEvery: 2,
    clickSrc: CLICK_WOOD_URL,
    accentSrc: CLICK_WOOD_URL,
    poolSize: 4,
    // 【完美音画同步核心】
    onBeat: (index, isAccent) => {
        if (walkerCanvasRef.value && walkerCanvasRef.value.triggerBeat) {
            walkerCanvasRef.value.triggerBeat()
        }
    }
})

const isPlaying = computed(() => fg.isPlaying.value)
const currentBpm = computed(() => fg.bpm.value)
const customAccent = computed(() => fg.accentEvery.value)
const intervalMs = computed(() => 60000 / fg.bpm.value)

/* ============================================================
 * 中央圆按钮
 * ============================================================ */
const onCenterTap = () => {
    if (fg.isPlaying.value) {
        fg.stop()
        uni.setKeepScreenOn({ keepScreenOn: false })
    } else {
        fg.start()
        uni.setKeepScreenOn({ keepScreenOn: true })
    }
}

/* ============================================================
 * 档位卡片
 * ============================================================ */
const onPresetTap = (id: LoopId) => {
    const preset = LOOP_PRESETS.find(p => p.id === id)
    if (!preset) return
    
    currentLoop.value = id
    fg.setBpm(preset.bpm)
    if (!fg.isPlaying.value) {
        fg.start()
        uni.setKeepScreenOn({ keepScreenOn: true })
    }
}

/* ============================================================
 * 自定义折叠区切换
 * ============================================================ */
const onToggleCustom = () => {
    customExpanded.value = !customExpanded.value
    if (customExpanded.value) {
        fg.preload()
    } else {
        // 收起时，如果当前 BPM 刚好匹配某个档位，高亮对应档位卡片
        const matched = LOOP_PRESETS.find(p => p.bpm === fg.bpm.value)
        currentLoop.value = matched ? matched.id : null
    }
}

const onBpmDelta = (delta: number) => {
    fg.setBpm(fg.bpm.value + delta)
    currentLoop.value = null // 用户手动微调后取消档位高亮
}

const onAccentSelect = (n: number) => {
    fg.setAccentEvery(n)
}

const rootStyle = computed(() => ({
    '--beat-duration': `${intervalMs.value}ms`,
}))

onShow(() => {
    fg.preload()
})

onHide(() => {
    fg.stop()
    uni.setKeepScreenOn({ keepScreenOn: false })
})

onUnmounted(() => {
    fg.stop()
    uni.setKeepScreenOn({ keepScreenOn: false })
})
</script>

<style lang="scss" scoped>
/* ============================================================
 * 设计 token —— 浅色清爽
 * ============================================================ */
$bg-color: #f8fafc;
$card-bg: #ffffff;
$card-border: rgba(15, 23, 42, 0.06);
$text-1: #0f172a;
$text-2: #475569;
$text-3: #94a3b8;
$brand: #10b981;
$brand-soft: #d1fae5;
$brand-deep: #047857;
$warn: #f59e0b;
$warn-soft: #fef3c7;
$radius-card: 24rpx;
$shadow-sm: 0 4rpx 12rpx rgba(15, 23, 42, 0.04);

/* ============================================================
 * 页面容器
 * ============================================================ */
.page {
    position: relative;
    min-height: 100vh;
    box-sizing: border-box;
    padding: 30rpx 28rpx 50rpx;
    background: $bg-color;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20rpx;
    color: $text-1;
}

/* ============================================================
 * 统一运动律动视区 (Canvas)
 * ============================================================ */
.stage-canvas-wrapper {
    width: 100vw;
    margin-left: -28rpx;
    margin-right: -28rpx;
    flex-shrink: 0; /* 防止被压缩 */
    height: 600rpx; /* 固定高度，不随内容变化 */
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 24rpx;
    position: relative;
}

/* ============================================================
 * 三档位推荐
 * ============================================================ */
.presets {
    width: 100%;
    display: flex;
    gap: 14rpx;
}

.preset {
    flex: 1;
    background: $card-bg;
    border: 2rpx solid $card-border;
    border-radius: $radius-card;
    padding: 26rpx 8rpx;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8rpx;
    box-shadow: $shadow-sm;
    transition: all 0.18s;

    .preset-name {
        font-size: 28rpx;
        font-weight: 700;
        color: $text-1;
        letter-spacing: 2rpx;
    }
    .preset-bpm {
        font-size: 22rpx;
        color: $text-2;
        font-weight: 600;
        font-variant-numeric: tabular-nums;
    }
    .preset-desc {
        font-size: 18rpx;
        color: $text-3;
        letter-spacing: 1rpx;
        margin-top: 2rpx;
    }

    &:active {
        transform: scale(0.97);
    }

    &.active {
        background: $brand-soft;
        border-color: $brand;
        box-shadow:
            0 8rpx 20rpx rgba(16, 185, 129, 0.18),
            inset 0 0 0 2rpx rgba(16, 185, 129, 0.4);

        .preset-name {
            color: $brand-deep;
        }
        .preset-bpm {
            color: $brand-deep;
        }
        .preset-desc {
            color: $brand;
        }
    }
}

/* ============================================================
 * 自定义节奏区域(标题栏 + 折叠内容)
 * ============================================================ */
.custom-section {
    width: 100%;
    margin-top: 12rpx;
}

.custom-header {
    width: 100%;
    padding: 16rpx 6rpx;
    display: flex;
    align-items: center;
    justify-content: center;

    .custom-title {
        font-size: 22rpx;
        color: $text-3;
        letter-spacing: 0.5rpx;

        &:active {
            color: $text-2;
        }
    }
}

.custom-content {
    width: 100%;
    background: $card-bg;
    border: 2rpx solid rgba(245, 158, 11, 0.25);
    border-radius: $radius-card;
    box-shadow: 0 6rpx 18rpx rgba(245, 158, 11, 0.08);
    padding: 20rpx 24rpx 22rpx;
    display: flex;
    flex-direction: column;
    gap: 16rpx;
    margin-top: 8rpx;
}

.custom-warn {
    display: flex;
    align-items: center;
    gap: 8rpx;
    margin-bottom: 4rpx;

    .warn-dot {
        font-size: 18rpx;
        color: $warn;
    }
    .warn-text {
        font-size: 22rpx;
        color: #b45309;
        letter-spacing: 0.5rpx;
        font-weight: 600;
    }
}

.row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12rpx;

    .row-label {
        font-size: 24rpx;
        color: $text-2;
        font-weight: 600;
        letter-spacing: 1rpx;
        flex-shrink: 0;
        width: 70rpx;
    }
}

.bpm-stepper {
    display: flex;
    align-items: center;
    gap: 6rpx;
    flex: 1;
    justify-content: flex-end;

    .step-btn {
        min-width: 56rpx;
        height: 52rpx;
        line-height: 52rpx;
        text-align: center;
        font-size: 22rpx;
        color: $text-2;
        background: #f1f5f9;
        border-radius: 10rpx;
        font-weight: 600;
        padding: 0 10rpx;
        font-variant-numeric: tabular-nums;

        &:active {
            background: #e2e8f0;
            transform: scale(0.94);
        }
    }
    .step-val {
        min-width: 84rpx;
        height: 52rpx;
        line-height: 52rpx;
        text-align: center;
        font-size: 30rpx;
        font-weight: 800;
        color: $text-1;
        font-variant-numeric: tabular-nums;
        background: $warn-soft;
        border-radius: 10rpx;
    }
}

.meter-tabs {
    display: flex;
    gap: 8rpx;

    .meter-tab {
        height: 52rpx;
        line-height: 52rpx;
        padding: 0 18rpx;
        font-size: 22rpx;
        color: $text-2;
        background: #f1f5f9;
        border-radius: 10rpx;
        font-weight: 600;
        letter-spacing: 1rpx;

        &.active {
            background: $warn;
            color: #fff;
            box-shadow: 0 4rpx 10rpx rgba(245, 158, 11, 0.3);
        }
        &:active {
            transform: scale(0.94);
        }
    }
}

/* ============================================================
 * 底部行(已废弃,保留样式以防引用)
 * ============================================================ */
.bottom-row {
    width: 100%;
    margin-top: 6rpx;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 6rpx;
}

.bottom-link {
    font-size: 22rpx;
    color: $text-3;
    letter-spacing: 0.5rpx;
    padding: 8rpx 4rpx;

    &:active {
        color: $text-2;
    }
}

.bottom-hint {
    font-size: 22rpx;
    color: $text-3;
    letter-spacing: 0.5rpx;
}
</style>
