'use client'

import Lottie from 'lottie-react'
import { useEffect, useState, type CSSProperties, type Ref } from 'react'
import { isLottieAnimationData } from '@/lib/media/mediaGuards'

export type VipBadgeLevel = 'vip' | 'vvip' | 'svip' | 'royal'

const VIP_BADGE_URL: Record<VipBadgeLevel, string> = {
    royal: '/lotties/badge/royal.json',
    vip: '/lotties/badge/vip.json',
    vvip: '/lotties/badge/vvip.json',
    svip: '/lotties/badge/svip.json',
}

const cache = new Map<VipBadgeLevel, object>()
const inflight = new Map<VipBadgeLevel, Promise<object | null>>()

export function normalizeVipBadgeLevel(raw: string | null | undefined): VipBadgeLevel | null {
    const v = String(raw ?? '').trim().toLowerCase()
    if (v === 'royal' || v === 'vip' || v === 'vvip' || v === 'svip') return v
    return null
}

async function loadVipBadgeLottie(level: VipBadgeLevel): Promise<object | null> {
    const cached = cache.get(level)
    if (cached) return cached

    let pending = inflight.get(level)
    if (!pending) {
        pending = fetch(VIP_BADGE_URL[level])
            .then(async (res) => {
                if (!res.ok) return null
                const data: unknown = await res.json()
                return isLottieAnimationData(data) ? data : null
            })
            .then((data) => {
                if (data) cache.set(level, data)
                return data
            })
            .catch(() => null)
            .finally(() => {
                inflight.delete(level)
            })
        inflight.set(level, pending)
    }

    return pending
}

type Props = {
    vipLevel?: string | null
    className?: string
    style?: CSSProperties
    innerRef?: Ref<HTMLSpanElement>
}

/** 依 vipLevel 僅請求對應的 badge Lottie JSON（含快取） */
export default function VipBadgeLottie({ vipLevel, className, style, innerRef }: Props) {
    const level = normalizeVipBadgeLevel(vipLevel)
    const [data, setData] = useState<object | null>(() => (level ? cache.get(level) ?? null : null))

    useEffect(() => {
        if (!level) {
            setData(null)
            return
        }
        const cached = cache.get(level)
        if (cached) {
            setData(cached)
            return
        }
        let cancelled = false
        setData(null)
        loadVipBadgeLottie(level).then((json) => {
            if (!cancelled) setData(json)
        })
        return () => {
            cancelled = true
        }
    }, [level])

    if (!level || !data) return null

    return (
        <span ref={innerRef} className={className}>
            <Lottie animationData={data} loop autoplay style={style} />
        </span>
    )
}
