<template>
    <view class="index">
        <view class="top-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
            <view class="top-bar__content">
                <view class="top-bar__logo">
                    <image src="/static/images/logo.png" mode="aspectFit" class="top-bar__logo-img" />
                </view>
                <view class="top-bar__search" @tap="goSearch">
                    <UIcon name="search" size="30" color="#8C95A5" />
                    <text class="top-bar__search-text">搜索赛事、球队、球员</text>
                </view>
                <AiAssistantEntry size="compact" variant="orb" />
            </view>
        </view>

        <view class="channel-bar">
            <view class="channel-bar__list">
                <view v-for="item in primaryChannels" :key="item.channelKey" class="channel-bar__item"
                    :class="{ 'channel-bar__item--active': currentChannel === item.index }" @tap="switchChannel(item.index)">
                    <text>{{ item.name }}</text>
                </view>
            </view>
            <view class="channel-bar__more" @tap="goChannelManage">
                <text>更多</text>
                <UIcon name="arrow-down" size="22" color="#667085" />
            </view>
        </view>

        <scroll-view scroll-y class="feed-wrapper" @scrolltolower="loadMore" :lower-threshold="100">
            <view class="home-content">
                <view v-if="focusMatches.length" class="focus-section">
                    <view class="section-heading">
                        <text class="section-heading__title">今日焦点</text>
                        <view class="section-heading__action" @tap="goAllMatches">
                            <text>全部赛程</text>
                            <UIcon name="arrow-right" size="22" color="#1468F5" />
                        </view>
                    </view>
                    <view class="focus-section__list">
                        <view v-for="(match, index) in focusMatches" :key="match.id" class="focus-match"
                            @tap="goMatch(match.id)">
                            <view class="focus-match__head">
                                <text class="focus-match__league" :class="{ 'focus-match__league--warm': index % 2 }">
                                    {{ match.league_name || '赛事' }}
                                </text>
                                <text class="focus-match__time">{{ formatFocusMeta(match) }}</text>
                            </view>
                            <view class="focus-match__teams">
                                <view class="focus-match__team">
                                    <image v-if="match.home_icon" :src="match.home_icon" mode="aspectFit"
                                        class="focus-match__badge" referrerpolicy="no-referrer" />
                                    <view v-else class="focus-match__badge focus-match__badge--fallback">
                                        <text>{{ getTeamInitial(match.home_team) }}</text>
                                    </view>
                                    <text class="focus-match__team-name">{{ match.home_team || '主队' }}</text>
                                </view>
                                <text class="focus-match__versus">VS</text>
                                <view class="focus-match__team">
                                    <image v-if="match.away_icon" :src="match.away_icon" mode="aspectFit"
                                        class="focus-match__badge" referrerpolicy="no-referrer" />
                                    <view v-else class="focus-match__badge focus-match__badge--fallback">
                                        <text>{{ getTeamInitial(match.away_team) }}</text>
                                    </view>
                                    <text class="focus-match__team-name">{{ match.away_team || '客队' }}</text>
                                </view>
                            </view>
                        </view>
                    </view>
                </view>

                <navigator v-if="featuredArticle" :url="`/pages/news_detail/news_detail?id=${featuredArticle.id}`"
                    class="featured-card">
                    <image v-if="featuredArticle.image && !featuredImageFailed" class="featured-card__image"
                        :src="featuredArticle.image" mode="aspectFill" referrerpolicy="no-referrer"
                        @error="featuredImageFailed = true" />
                    <view class="featured-card__shade" />
                    <view class="featured-card__content">
                        <text class="featured-card__tag">{{ getArticleCategoryName(featuredArticle) }}</text>
                        <view class="featured-card__copy">
                            <text class="featured-card__title">{{ featuredArticle.title }}</text>
                            <text v-if="getArticleSummary(featuredArticle)" class="featured-card__desc">
                                {{ getArticleSummary(featuredArticle) }}
                            </text>
                        </view>
                        <view class="featured-card__meta">
                            <text>{{ getArticleAuthor(featuredArticle) }}</text>
                            <text>{{ formatRelativeTime(featuredArticle.create_time) }}</text>
                        </view>
                    </view>
                </navigator>

                <view class="latest-section">
                    <view class="section-heading latest-section__heading">
                        <text class="section-heading__title">最新资讯</text>
                        <view class="latest-section__filter">
                            <UIcon name="filter" size="28" color="#7A8494" />
                            <text>筛选</text>
                        </view>
                    </view>
                    <view class="latest-section__list">
                        <FeedCard v-for="item in regularFeedList" :key="item.id" :item="item" />
                    </view>
                </view>

                <view v-if="loading" class="feed-loading">
                    <ULoading mode="circle" />
                    <text class="feed-loading__text">加载中...</text>
                </view>
                <view v-if="noMore && feedList.length" class="feed-bottom">
                    <text>没有更多了</text>
                </view>
                <view v-if="!loading && !feedList.length" class="feed-empty">
                    <text>暂无内容</text>
                </view>
            </view>
        </scroll-view>

        <!--  #ifdef MP  -->
        <MpPrivacyPopup />
        <!--  #endif  -->

        <GlobalPopup />
    </view>
</template>

<script setup lang="ts">
import { onLoad, onShow, onUnload } from '@dcloudio/uni-app'
import { computed, ref } from 'vue'
import { getArticleList, getArticleCate } from '@/api/news'
import { getMatchList } from '@/api/match'
import { resolveShortLink } from '@/api/share'
import { getLocalMatchDate } from '@/utils/match-time'
import { useUserStore } from '@/stores/user'
import AiAssistantEntry from '@/components/ai-assistant-entry/ai-assistant-entry.vue'
import FeedCard from '@/components/feed-card/feed-card.vue'
import GlobalPopup from '@/components/global-popup/global-popup.vue'
import UIcon from '@/uni_modules/vk-uview-ui/components/u-icon/u-icon.vue'
import ULoading from '@/uni_modules/vk-uview-ui/components/u-loading/u-loading.vue'

const userStore = useUserStore()
// #ifdef MP
import MpPrivacyPopup from './component/mp-privacy-popup.vue'
// #endif

const statusBarHeight = ref(0)
uni.getSystemInfo({
    success: (res) => {
        // #ifdef APP-PLUS || MP
        statusBarHeight.value = res.statusBarHeight || 44
        // #endif
    }
})

const RECOMMEND_CHANNEL = {
    id: '__recommend__',
    name: '推荐',
    specialType: 'recommend',
    channelKey: '__recommend__'
}

const MY_CHANNEL = {
    id: '__mychannel__',
    name: '我的频道',
    specialType: 'mychannel',
    channelKey: '__mychannel__'
}

const articleChannels = ref<any[]>([])
const allChannels = ref<any[]>([])
const currentChannel = ref(0)
const feedList = ref<any[]>([])
const focusMatches = ref<any[]>([])
const featuredImageFailed = ref(false)
const loading = ref(false)
const noMore = ref(false)
const pageNo = ref(1)
const pageSize = 10

const primaryChannels = computed(() => {
    return allChannels.value
        .map((item, index) => ({ ...item, index }))
        .filter((item) => item.specialType !== 'mychannel')
        .slice(0, 5)
})

const featuredArticle = computed(() => {
    return feedList.value.find((item) => item.image) || feedList.value[0] || null
})

const regularFeedList = computed(() => {
    const featuredId = featuredArticle.value?.id
    return feedList.value.filter((item) => item.id !== featuredId)
})

const buildAllChannels = (channels: any[] = []) => {
    const merged = [{ ...RECOMMEND_CHANNEL }]
    if (userStore.isLogin) {
        merged.push({ ...MY_CHANNEL })
    }
    const dynamicChannels = (channels || []).map((item: any) => ({
        ...item,
        specialType: 'category',
        channelKey: `cate_${item.id}`
    }))
    return [...merged, ...dynamicChannels]
}

const syncAllChannels = (channels: any[] = articleChannels.value) => {
    const previousKey = allChannels.value[currentChannel.value]?.channelKey || RECOMMEND_CHANNEL.channelKey
    allChannels.value = buildAllChannels(channels)
    const nextIndex = allChannels.value.findIndex((item: any) => item.channelKey === previousKey)
    currentChannel.value = nextIndex >= 0 ? nextIndex : 0
}

const findChannelIndexById = (id: any) => {
    return allChannels.value.findIndex((item: any) => {
        return item.specialType === 'category' && String(item.id) === String(id)
    })
}

const loadChannels = async () => {
    try {
        articleChannels.value = (await getArticleCate()) || []
    } catch (error) {
        console.log('获取分类失败=>', error)
        articleChannels.value = []
    } finally {
        syncAllChannels()
    }
}

const loadFocusMatches = async () => {
    try {
        const data = await getMatchList()
        const priorityMatches = [...(data?.live || []), ...(data?.upcoming || [])]
        focusMatches.value = priorityMatches.slice(0, 2)
    } catch (error) {
        console.log('获取首页焦点赛程失败=>', error)
        focusMatches.value = []
    }
}

const switchChannel = (index: number) => {
    if (currentChannel.value === index) return
    currentChannel.value = index
    reloadFeed()
}

const reloadFeed = () => {
    pageNo.value = 1
    noMore.value = false
    feedList.value = []
    featuredImageFailed.value = false
    fetchFeedList()
}

const fetchFeedList = async () => {
    if (loading.value || noMore.value) return
    loading.value = true
    try {
        const params: Record<string, any> = {
            page_no: pageNo.value,
            page_size: pageSize
        }
        const currentChannelItem = allChannels.value[currentChannel.value]
        if (!currentChannelItem || currentChannelItem.specialType === 'recommend') {
            params.is_recommend = 1
        } else if (currentChannelItem.specialType === 'mychannel') {
            params.is_mychannel = 1
        } else if (currentChannelItem.id) {
            params.cid = currentChannelItem.id
        }
        const { lists, count } = await getArticleList(params)
        const newList = lists || []
        if (pageNo.value === 1) {
            feedList.value = newList
            featuredImageFailed.value = false
        } else {
            feedList.value = [...feedList.value, ...newList]
        }
        if (feedList.value.length >= count || newList.length < pageSize) {
            noMore.value = true
        }
        pageNo.value++
    } catch (error) {
        console.log('首页资讯加载失败=>', error)
        uni.showToast({ title: '加载失败，请稍后重试', icon: 'none' })
    } finally {
        loading.value = false
    }
}

const getArticleSummary = (item: any) => {
    return String(item?.desc || item?.content || '')
        .replace(/<[^>]+>/g, ' ')
        .replace(/&nbsp;/g, ' ')
        .replace(/\s+/g, ' ')
        .trim()
}

const getArticleAuthor = (item: any) => {
    return String(item?.author || 'SB 体育头条').replace(/@懂球帝/g, '').trim() || 'SB 体育头条'
}

const getArticleCategoryName = (item: any) => {
    return articleChannels.value.find((channel) => String(channel.id) === String(item?.cid))?.name || '体育'
}

const formatRelativeTime = (time: string) => {
    if (!time) return ''
    const date = new Date(String(time).replace(/-/g, '/'))
    const delta = Date.now() - date.getTime()
    if (Number.isNaN(date.getTime()) || delta < 0) return String(time)
    const minute = 60 * 1000
    if (delta < minute) return '刚刚'
    if (delta < 60 * minute) return `${Math.floor(delta / minute)}分钟前`
    if (delta < 24 * 60 * minute) return `${Math.floor(delta / (60 * minute))}小时前`
    if (delta < 7 * 24 * 60 * minute) return `${Math.floor(delta / (24 * 60 * minute))}天前`
    return `${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
}

const formatFocusMeta = (match: any) => {
    const date = getLocalMatchDate(match?.match_time, match)
    const time = date
        ? `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
        : '待定'
    return `${match?.round_name || '赛程'}  ${time}`
}

const getTeamInitial = (name: string) => String(name || '?').trim().slice(0, 1)

const loadMore = () => fetchFeedList()

const goSearch = () => uni.navigateTo({ url: '/pages/search/search' })
const goChannelManage = () => uni.navigateTo({ url: '/pages/channel/channel-manage' })
const goAllMatches = () => uni.switchTab({ url: '/packages_match/pages/worldcup' })
const goMatch = (id: number | string) => {
    if (id) uni.navigateTo({ url: `/pages/match_detail/match_detail?id=${id}` })
}

const handleRedirect = async (options: any) => {
    let slc = options?.slc || ''
    // #ifdef H5
    if (!slc) {
        const urlParams = new URLSearchParams(window.location.search)
        slc = urlParams.get('slc') || ''
    }
    // #endif
    if (!slc) return

    try {
        const res = await resolveShortLink({
            code: slc,
            fingerprint: generateFingerprint(),
            referer: typeof document === 'undefined' ? '' : document.referrer || ''
        })
        if (res.params?.invite_code) uni.setStorageSync('invite_code', res.params.invite_code)
        if (res.path && res.page_type !== 'invite') {
            setTimeout(() => uni.navigateTo({ url: res.path }), 300)
        }
    } catch (error) {
        console.error('短链接解析失败', error)
    }
}

const generateFingerprint = (): string => {
    // #ifdef H5
    try {
        const canvas = document.createElement('canvas')
        const context = canvas.getContext('2d')
        if (context) {
            context.textBaseline = 'top'
            context.font = '14px Arial'
            context.fillText('fp', 2, 2)
        }
        const raw = `${navigator.userAgent}${navigator.language}${screen.width}x${screen.height}${screen.colorDepth}${new Date().getTimezoneOffset()}${canvas.toDataURL()}`
        let hash = 0
        for (let index = 0; index < raw.length; index++) {
            hash = (hash << 5) - hash + raw.charCodeAt(index)
            hash |= 0
        }
        return Math.abs(hash).toString(16)
    } catch {
        return ''
    }
    // #endif
    // #ifndef H5
    return ''
    // #endif
}

let channelsLoaded = false
onLoad(async (options: any) => {
    handleRedirect(options)
    await Promise.all([loadChannels(), loadFocusMatches()])
    fetchFeedList()
})

onShow(async () => {
    syncAllChannels()
    if (!channelsLoaded && articleChannels.value.length === 0) {
        await loadChannels()
        fetchFeedList()
    }
    if (channelsLoaded && allChannels.value[currentChannel.value]?.specialType === 'mychannel') {
        reloadFeed()
    }
    channelsLoaded = true
})

const onChannelChanged = (data: any) => {
    if (data.channels) {
        articleChannels.value = data.channels
        syncAllChannels()
    }
    if (data.selectIndex >= 0) {
        const selectedChannel = articleChannels.value[data.selectIndex]
        const selectedIndex = findChannelIndexById(selectedChannel?.id)
        switchChannel(selectedIndex >= 0 ? selectedIndex : 0)
    } else {
        reloadFeed()
    }
}

uni.$on('channelChanged', onChannelChanged)
onUnload(() => uni.$off('channelChanged', onChannelChanged))
</script>

<style lang="scss" scoped>
.index {
    height: 100vh;
    background: #f6f7f9;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.top-bar {
    flex-shrink: 0;
    z-index: 10;
    background: #fff;

    &__content {
        display: flex;
        align-items: center;
        gap: 16rpx;
        padding: 16rpx 24rpx 14rpx;
    }

    &__logo {
        width: 76rpx;
        height: 76rpx;
        flex-shrink: 0;

        &-img {
            width: 100%;
            height: 100%;
            border-radius: 18rpx;
        }
    }

    &__search {
        flex: 1;
        min-width: 0;
        height: 72rpx;
        padding: 0 24rpx;
        gap: 14rpx;
        border-radius: 40rpx;
        display: flex;
        align-items: center;
        background: #f3f4f6;

        &-text {
            color: #8c95a5;
            font-size: 27rpx;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
    }
}

.channel-bar {
    height: 86rpx;
    display: flex;
    align-items: stretch;
    flex-shrink: 0;
    background: #fff;
    border-bottom: 1rpx solid #edf0f5;

    &__list {
        min-width: 0;
        flex: 1;
        display: flex;
        align-items: stretch;
    }

    &__item {
        flex: 1;
        min-width: 0;
        position: relative;
        display: flex;
        justify-content: center;
        align-items: center;
        color: #252b36;
        font-size: 29rpx;
        white-space: nowrap;
        overflow: hidden;

        text {
            overflow: hidden;
            text-overflow: ellipsis;
        }

        &--active {
            color: #1468f5;
            font-weight: 700;

            &::after {
                content: '';
                position: absolute;
                left: 50%;
                bottom: 0;
                width: 48rpx;
                height: 6rpx;
                border-radius: 999rpx;
                background: #1468f5;
                transform: translateX(-50%);
            }
        }
    }

    &__more {
        width: 104rpx;
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 2rpx;
        flex-shrink: 0;
        color: #252b36;
        font-size: 28rpx;
        background: #fff;
    }
}

.feed-wrapper {
    flex: 1;
    min-height: 0;
    background: #f6f7f9;
}

.home-content {
    padding: 16rpx 24rpx 42rpx;
}

.focus-section,
.latest-section {
    background: #fff;
    border-radius: 22rpx;
}

.focus-section {
    padding: 20rpx;
    box-shadow: 0 8rpx 30rpx rgba(29, 45, 78, 0.04);

    &__list {
        display: flex;
        gap: 14rpx;
    }
}

.section-heading {
    height: 54rpx;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 14rpx;

    &__title {
        color: #151b26;
        font-size: 34rpx;
        font-weight: 700;
        line-height: 1.2;
    }

    &__action {
        display: flex;
        align-items: center;
        gap: 2rpx;
        color: #1468f5;
        font-size: 25rpx;
    }
}

.focus-match {
    flex: 1;
    min-width: 0;
    padding: 16rpx 14rpx 18rpx;
    border: 1rpx solid #e7eaf0;
    border-radius: 16rpx;
    background: #fff;

    &__head {
        display: flex;
        align-items: center;
        gap: 10rpx;
        min-width: 0;
    }

    &__league {
        max-width: 92rpx;
        padding: 4rpx 10rpx;
        border-radius: 8rpx;
        color: #235bde;
        background: #eaf0ff;
        font-size: 21rpx;
        font-weight: 600;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;

        &--warm {
            color: #ef6321;
            background: #fff0e8;
        }
    }

    &__time {
        min-width: 0;
        flex: 1;
        color: #7d8797;
        font-size: 21rpx;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    &__teams {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
        align-items: center;
        gap: 8rpx;
        margin-top: 16rpx;
    }

    &__team {
        min-width: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 8rpx;
    }

    &__badge {
        width: 58rpx;
        height: 58rpx;

        &--fallback {
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            background: #edf2ff;
            color: #1468f5;
            font-size: 28rpx;
            font-weight: 700;
        }
    }

    &__team-name {
        width: 100%;
        color: #202633;
        font-size: 23rpx;
        line-height: 1.25;
        text-align: center;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    &__versus {
        color: #161d29;
        font-size: 28rpx;
        font-weight: 700;
    }
}

.featured-card {
    position: relative;
    display: block;
    height: 400rpx;
    margin-top: 18rpx;
    overflow: hidden;
    border-radius: 22rpx;
    background: linear-gradient(135deg, #164b91 0%, #142839 100%);
    box-shadow: 0 10rpx 30rpx rgba(20, 37, 65, 0.1);

    &__image,
    &__shade {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
    }

    &__shade {
        background: linear-gradient(180deg, rgba(8, 18, 29, 0.08) 20%, rgba(7, 15, 24, 0.82) 100%);
    }

    &__content {
        position: relative;
        z-index: 1;
        height: 100%;
        box-sizing: border-box;
        padding: 24rpx;
        display: flex;
        flex-direction: column;
    }

    &__tag {
        align-self: flex-start;
        padding: 6rpx 18rpx;
        border-radius: 10rpx;
        color: #fff;
        background: #1468f5;
        font-size: 24rpx;
        line-height: 1.25;
    }

    &__copy {
        margin-top: auto;
    }

    &__title {
        display: -webkit-box;
        overflow: hidden;
        color: #fff;
        font-size: 36rpx;
        font-weight: 700;
        line-height: 1.32;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }

    &__desc {
        display: -webkit-box;
        overflow: hidden;
        margin-top: 10rpx;
        color: rgba(255, 255, 255, 0.92);
        font-size: 25rpx;
        line-height: 1.5;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }

    &__meta {
        display: flex;
        align-items: center;
        gap: 28rpx;
        margin-top: 16rpx;
        color: rgba(255, 255, 255, 0.88);
        font-size: 23rpx;
        line-height: 1.2;
    }
}

.latest-section {
    margin-top: 18rpx;
    overflow: hidden;

    &__heading {
        padding: 20rpx 20rpx 8rpx;
        margin-bottom: 0;
    }

    &__filter {
        display: flex;
        align-items: center;
        gap: 6rpx;
        color: #7a8494;
        font-size: 24rpx;
    }
}

.feed-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12rpx;
    padding: 30rpx 0;

    &__text {
        color: #98a2b3;
        font-size: 24rpx;
    }
}

.feed-bottom,
.feed-empty {
    color: #98a2b3;
    font-size: 24rpx;
    text-align: center;
}

.feed-bottom {
    padding: 30rpx 0;
}

.feed-empty {
    padding: 100rpx 0;
}
</style>
