<template>
    <u-popup v-model="showPopup" mode="bottom" safe-area-inset-bottom border-radius="24" closeable @close="handleClose">
        <view class="match-live-popup">
            <view class="match-live-popup__header">
                <text class="match-live-popup__title">{{ popupTitle }}</text>
                <text class="match-live-popup__desc">{{ popupDesc }}</text>
            </view>

            <view class="match-live-popup__section">
                <text class="match-live-popup__section-title">直播线路</text>
                <view v-if="lineOptions.length" class="match-live-popup__options">
                    <view
                        v-for="item in lineOptions"
                        :key="item.key"
                        class="match-live-popup__option"
                        :class="{ 'match-live-popup__option--active': item.key === selectedLineKey }"
                        @tap="selectLine(item)"
                    >
                        <view class="match-live-popup__option-main">
                            <text class="match-live-popup__option-title">{{ item.title }}</text>
                            <text class="match-live-popup__option-meta">{{ item.meta }}</text>
                            <text class="match-live-popup__option-url">{{ item.url }}</text>
                        </view>
                        <text v-if="item.key === selectedLineKey" class="match-live-popup__option-tag">当前</text>
                    </view>
                </view>
                <view v-else class="match-live-popup__empty">
                    <text>暂无可用直播线路</text>
                </view>
            </view>

            <view class="match-live-popup__actions">
                <u-button type="primary" shape="circle" @click="openSelected">打开当前线路</u-button>
                <u-button shape="circle" plain @click="openSource">打开源站</u-button>
            </view>
        </view>
    </u-popup>
</template>

<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import type { MatchLiveLineItem } from '@/api/match'

type PopupLiveLineOption = MatchLiveLineItem & {
    key: string
    title: string
    meta: string
    url: string
    directUrl: string
    sourceUrl: string
}

const props = defineProps<{
    show: boolean
    matchTitle?: string
    lines: MatchLiveLineItem[]
}>()

const emit = defineEmits(['update:show', 'close'])

const showPopup = computed({
    get: () => props.show,
    set: (value: boolean) => emit('update:show', value),
})

const selectedLineKey = ref('')

const normalizeText = (value: unknown) => String(value || '').trim()

const getFetchStatusText = (value: unknown) => {
    const text = normalizeText(value)
    if (!text) return ''
    const normalized = text.toLowerCase()
    if (normalized === 'pending' || normalized === '0') return '待抓取'
    if (normalized === 'success' || normalized === '1') return '已抓取'
    if (normalized === 'failed' || normalized === 'error' || normalized === '2') return '抓取失败'
    return text
}

const formatMetaTime = (value: unknown) => {
    const text = normalizeText(value)
    if (!text) return ''
    const hhmmss = text.match(/(\d{2}:\d{2}:\d{2})$/)
    if (hhmmss) return hhmmss[1]
    const hhmm = text.match(/(\d{2}:\d{2})$/)
    if (hhmm) return hhmm[1]
    if (/^\d{10,13}$/.test(text)) {
        const raw = text.length === 13 ? Number(text) : Number(text) * 1000
        const date = new Date(raw)
        if (!Number.isNaN(date.getTime())) {
            const hour = String(date.getHours()).padStart(2, '0')
            const minute = String(date.getMinutes()).padStart(2, '0')
            return `${hour}:${minute}`
        }
    }
    return text
}

const collectLineUrls = (line: MatchLiveLineItem) => {
    const candidates: string[] = []
    const seen = new Set<string>()
    const push = (value: unknown) => {
        const url = normalizeText(value)
        if (!url || seen.has(url)) return
        seen.add(url)
        candidates.push(url)
    }

    push(line.default_play_url)
    if (Array.isArray(line.stream_options)) {
        line.stream_options.forEach((option) => {
            push(option.default_play_url)
            push(option.play_url_m3u8)
            push(option.play_url_hd_m3u8)
            push(option.play_url_flv)
            push(option.play_url_hd_flv)
            push(option.play_url)
            push(option.url)
            push(option.live_url)
        })
    }
    push(line.play_url_m3u8)
    push(line.play_url_hd_m3u8)
    push(line.play_url_flv)
    push(line.play_url_hd_flv)
    push(line.play_url)

    return candidates
}

const buildLineOption = (line: MatchLiveLineItem, index: number) => {
    const directUrl = collectLineUrls(line)[0] || ''
    const sourceUrl = normalizeText(line.source_url || line.live_url)
    const url = directUrl || sourceUrl
    if (!url) return null

    const title = (
        normalizeText(line.title) ||
        normalizeText(line.name) ||
        normalizeText(line.label) ||
        normalizeText(line.live_tag) ||
        normalizeText(line.source_name) ||
        `线路${index + 1}`
    )
    const metaParts = [
        getFetchStatusText(line.fetch_status),
        formatMetaTime(line.last_fetch_at || line.update_time),
    ].filter(Boolean)

    return {
        ...line,
        key: normalizeText(line.id) || `${title}-${index}`,
        title,
        meta: metaParts.length ? metaParts.join(' · ') : (directUrl ? '可直接播放' : '源站兜底'),
        url,
        directUrl,
        sourceUrl,
    } satisfies PopupLiveLineOption
}

const lineOptions = computed(() => {
    return (props.lines || [])
        .map((line, index) => buildLineOption(line, index))
        .filter((item): item is PopupLiveLineOption => !!item)
})

const selectedLine = computed(() => {
    return lineOptions.value.find((item) => item.key === selectedLineKey.value) || lineOptions.value[0] || null
})

const popupTitle = computed(() => normalizeText(props.matchTitle) || '切换线路')

const popupDesc = computed(() => {
    if (!lineOptions.value.length) return '暂无可切换的直播线路'
    return selectedLine.value?.meta || `共 ${lineOptions.value.length} 条直播线路`
})

const resetSelected = () => {
    selectedLineKey.value = lineOptions.value[0]?.key || ''
}

watch(
    () => [props.lines, props.show],
    () => {
        resetSelected()
    },
    { immediate: true, deep: true }
)

const navigateToWebview = (url: string) => {
    uni.navigateTo({ url: `/pages/webview/webview?url=${encodeURIComponent(url)}` })
}

const selectLine = (item: PopupLiveLineOption) => {
    selectedLineKey.value = item.key
}

const openSelected = () => {
    const url = selectedLine.value?.directUrl || selectedLine.value?.sourceUrl || ''
    if (!url) {
        uni.showToast({ title: '暂无可用直播链接', icon: 'none' })
        return
    }
    navigateToWebview(url)
}

const openSource = () => {
    const url = selectedLine.value?.sourceUrl || selectedLine.value?.directUrl || ''
    if (!url) {
        uni.showToast({ title: '暂无源站链接', icon: 'none' })
        return
    }
    navigateToWebview(url)
}

const handleClose = () => {
    emit('close')
}
</script>

<style lang="scss" scoped>
.match-live-popup {
    padding: 40rpx 28rpx calc(28rpx + env(safe-area-inset-bottom));
    background: #fff;

    &__header {
        display: flex;
        flex-direction: column;
        gap: 10rpx;
        margin-bottom: 28rpx;
    }

    &__title {
        font-size: 32rpx;
        font-weight: 700;
        color: #111827;
    }

    &__desc {
        font-size: 24rpx;
        color: #6b7280;
        line-height: 1.5;
    }

    &__section {
        margin-bottom: 32rpx;
    }

    &__section-title {
        display: block;
        margin-bottom: 18rpx;
        font-size: 26rpx;
        font-weight: 600;
        color: #1f2937;
    }

    &__options {
        display: flex;
        flex-direction: column;
        gap: 16rpx;
    }

    &__option {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 18rpx;
        padding: 20rpx 22rpx;
        border-radius: 20rpx;
        background: #f8fafc;
        border: 2rpx solid transparent;

        &--active {
            border-color: #3552ff;
            background: rgba(53, 82, 255, 0.08);
        }
    }

    &__option-main {
        min-width: 0;
        display: flex;
        flex-direction: column;
        gap: 6rpx;
        flex: 1;
    }

    &__option-title {
        font-size: 28rpx;
        font-weight: 600;
        color: #0f172a;
        line-height: 1.4;
    }

    &__option-meta {
        font-size: 22rpx;
        color: #64748b;
        line-height: 1.4;
    }

    &__option-url {
        font-size: 22rpx;
        color: #3552ff;
        line-height: 1.4;
        word-break: break-all;
    }

    &__option-tag {
        flex-shrink: 0;
        padding: 8rpx 16rpx;
        border-radius: 999rpx;
        background: #3552ff;
        color: #fff;
        font-size: 22rpx;
        line-height: 1;
    }

    &__empty {
        padding: 30rpx 0;
        text-align: center;
        color: #94a3b8;
        font-size: 24rpx;
    }

    &__actions {
        display: flex;
        gap: 18rpx;
    }

    :deep(.u-btn) {
        flex: 1;
    }
}
</style>
