<template>
    <view class="match-odds-detail">
        <scroll-view scroll-x class="match-odds-detail__tabs" show-scrollbar="false">
            <view class="match-odds-detail__tabs-inner">
                <view v-for="item in platformOptions" :key="item.key" class="match-odds-detail__tab"
                    :class="{ 'match-odds-detail__tab--active': sourceSite === item.key }"
                    @tap="switchPlatform(item.key)">
                    <text>{{ item.label }}</text>
                </view>
            </view>
        </scroll-view>

        <view v-if="loading" class="match-odds-detail__state">
            <u-loading mode="circle" />
            <text>赔率加载中...</text>
        </view>

        <view v-else-if="loadError" class="match-odds-detail__state">
            <text>{{ loadError }}</text>
            <u-button size="mini" type="primary" @click="retryFetch">重新加载</u-button>
        </view>

        <view v-else-if="platforms.length" class="match-odds-detail__list">
            <view v-for="platform in platforms"
                :key="`${platform.platform_key}-${platform.source_match_id || platform.update_time || 0}`"
                class="match-odds-platform">
                <view class="match-odds-platform__head">
                    <view class="match-odds-platform__name">
                        <text>{{ platform.platform_name }}</text>
                        <text v-if="platform.show_type_text" class="match-odds-platform__tag">
                            {{ platform.show_type_text }}
                        </text>
                    </view>
                    <text class="match-odds-platform__update">{{ formatUpdateTime(platform.update_time) }}</text>
                </view>

                <view v-for="market in platform.markets" :key="`${platform.source_match_id}-${market.label}`"
                    class="match-odds-market">
                    <view class="match-odds-market__title">
                        <text>{{ market.label }}</text>
                        <text v-if="market.line" class="match-odds-market__line">{{ market.line }}</text>
                    </view>
                    <view class="match-odds-market__values">
                        <view v-for="item in market.values" :key="`${market.label}-${item.label}`"
                            class="match-odds-value">
                            <text class="match-odds-value__label">{{ item.label }}</text>
                            <text class="match-odds-value__number">{{ item.value }}</text>
                        </view>
                    </view>
                </view>
            </view>
        </view>

        <view v-else class="match-odds-detail__state">
            <u-empty text="暂无赔率" mode="data" />
        </view>
    </view>
</template>

<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue'
import {
    getMatchOdds,
    type WorldCupOddsPlatform,
    type MatchOddsMatchItem,
} from '@/api/match'
import { getLocalMatchDate } from '@/utils/match-time'

type PlatformOption = { key: string; label: string }

const props = withDefaults(defineProps<{
    homeTeam?: string
    awayTeam?: string
    matchTime?: number | string
    competitionId?: number | string
    leagueName?: string
}>(), {
    homeTeam: '',
    awayTeam: '',
    matchTime: 0,
    competitionId: 0,
    leagueName: '',
})

const defaultPlatformOptions: PlatformOption[] = [
    { key: '', label: '全部平台' },
    { key: 'hg', label: '皇冠' },
    { key: 'titan007', label: '球探' },
]

const oddsList = ref<MatchOddsMatchItem[]>([])
const platformOptions = ref<PlatformOption[]>([...defaultPlatformOptions])
const sourceSite = ref('')
const loading = ref(false)
const loaded = ref(false)
const loadError = ref('')
const requestSeq = ref(0)

const normalizePlatformLabel = (key: string, label: string) => {
    return key === 'hg' ? '皇冠' : label
}

const platforms = computed<WorldCupOddsPlatform[]>(() => {
    const result: WorldCupOddsPlatform[] = []
    const seen = new Set<string>()
    oddsList.value.forEach((match) => {
        const matchPlatforms = match.platforms || []
        matchPlatforms.forEach((platform) => {
            const key = `${platform.platform_key}-${platform.source_match_id || ''}`
            if (seen.has(key)) return
            seen.add(key)
            result.push({
                ...platform,
                platform_name: normalizePlatformLabel(platform.platform_key, platform.platform_name),
            })
        })
    })
    return result
})

const matchDate = computed(() => {
    const date = getLocalMatchDate(props.matchTime, {
        competition_id: props.competitionId,
        league_name: props.leagueName,
    })
    if (!date) return ''
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${year}-${month}-${day}`
})

const mergePlatformOptions = (options: unknown) => {
    const map = new Map<string, PlatformOption>()
    defaultPlatformOptions.forEach((item) => map.set(item.key, item))
    if (Array.isArray(options)) {
        options.forEach((item: any) => {
            const key = String(item?.key || '').trim()
            const label = String(item?.label || '').trim()
            if (key && label) map.set(key, { key, label: normalizePlatformLabel(key, label) })
        })
    }
    platformOptions.value = Array.from(map.values())
}

const fetchOdds = async (force = false) => {
    if (!force && (loaded.value || loading.value)) return
    if (!props.homeTeam.trim() || !props.awayTeam.trim() || !matchDate.value) {
        oddsList.value = []
        loaded.value = true
        return
    }

    const seq = requestSeq.value + 1
    requestSeq.value = seq
    loading.value = true
    loadError.value = ''
    try {
        const data = await getMatchOdds({
            home_team: props.homeTeam.trim(),
            away_team: props.awayTeam.trim(),
            match_date: matchDate.value,
            source_site: sourceSite.value || undefined,
            limit: 120,
        })
        if (seq !== requestSeq.value) return
        oddsList.value = Array.isArray(data?.list) ? data.list : []
        mergePlatformOptions(data?.platform_options)
        loaded.value = true
    } catch (error) {
        if (seq !== requestSeq.value) return
        console.error('获取比赛赔率失败', error)
        oddsList.value = []
        loaded.value = true
        loadError.value = '赔率加载失败，请稍后重试'
    } finally {
        if (seq === requestSeq.value) loading.value = false
    }
}

const switchPlatform = (platformKey: string) => {
    if (sourceSite.value === platformKey) return
    sourceSite.value = platformKey
    loaded.value = false
    void fetchOdds(true)
}

const retryFetch = () => {
    loaded.value = false
    void fetchOdds(true)
}

const formatUpdateTime = (timestamp?: number) => {
    const value = Number(timestamp || 0)
    if (!value) return ''
    const date = new Date(value * 1000)
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    const hour = String(date.getHours()).padStart(2, '0')
    const minute = String(date.getMinutes()).padStart(2, '0')
    return `${month}-${day} ${hour}:${minute}`
}

watch(
    () => [props.homeTeam, props.awayTeam, props.matchTime, props.competitionId, props.leagueName],
    () => {
        loaded.value = false
        oddsList.value = []
        loadError.value = ''
        void fetchOdds(true)
    },
)

onMounted(() => {
    void fetchOdds()
})
</script>

<style lang="scss" scoped>
.match-odds-detail {
    min-height: 100%;
    padding: 20rpx 24rpx 32rpx;
    box-sizing: border-box;
}

.match-odds-detail__tabs {
    width: 100%;
    margin-bottom: 20rpx;
    white-space: nowrap;
}

.match-odds-detail__tabs-inner {
    width: 100%;
    min-width: 100%;
    display: flex;
    gap: 24rpx;
}

.match-odds-detail__tab {
    position: relative;
    flex: 1 0 112rpx;
    min-width: 112rpx;
    height: 64rpx;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    color: #64748b;
    font-size: 24rpx;
    white-space: nowrap;
}

.match-odds-detail__tab--active {
    color: #2563eb;
    font-weight: 600;

    &::after {
        position: absolute;
        left: 50%;
        bottom: 0;
        width: 32rpx;
        height: 4rpx;
        border-radius: 2rpx;
        background: #2563eb;
        content: '';
        transform: translateX(-50%);
    }
}

.match-odds-detail__state {
    min-height: 360rpx;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18rpx;
    color: #94a3b8;
    font-size: 24rpx;
}

.match-odds-detail__list {
    display: flex;
    flex-direction: column;
    gap: 20rpx;
}

.match-odds-platform {
    padding: 22rpx;
    border: 1rpx solid #e2e8f0;
    border-radius: 8rpx;
    background: #ffffff;
}

.match-odds-platform__head,
.match-odds-platform__name,
.match-odds-market__title,
.match-odds-market__values {
    display: flex;
    align-items: center;
}

.match-odds-platform__head {
    justify-content: space-between;
    gap: 16rpx;
    margin-bottom: 18rpx;
}

.match-odds-platform__name {
    min-width: 0;
    gap: 12rpx;
    color: #0f172a;
    font-size: 28rpx;
    font-weight: 700;
}

.match-odds-platform__tag {
    padding: 4rpx 10rpx;
    border-radius: 6rpx;
    background: #eff6ff;
    color: #2563eb;
    font-size: 20rpx;
    font-weight: 500;
}

.match-odds-platform__update {
    flex-shrink: 0;
    color: #94a3b8;
    font-size: 20rpx;
}

.match-odds-market {
    padding: 16rpx 0;
    border-top: 1rpx solid #f1f5f9;
}

.match-odds-market__title {
    justify-content: space-between;
    margin-bottom: 12rpx;
    color: #334155;
    font-size: 24rpx;
    font-weight: 600;
}

.match-odds-market__line {
    color: #2563eb;
    font-size: 22rpx;
}

.match-odds-market__values {
    gap: 12rpx;
}

.match-odds-value {
    flex: 1;
    min-width: 0;
    min-height: 86rpx;
    padding: 12rpx 8rpx;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6rpx;
    box-sizing: border-box;
    border-radius: 6rpx;
    background: #f8fafc;
}

.match-odds-value__label {
    color: #64748b;
    font-size: 21rpx;
}

.match-odds-value__number {
    color: #0f172a;
    font-size: 27rpx;
    font-weight: 700;
}
</style>
