'use client'

import { useCallback, useEffect, useMemo, useRef, useState, type PointerEvent as ReactPointerEvent, type MouseEvent as ReactMouseEvent, type CSSProperties } from 'react'
import { useRouter, usePathname } from 'next/navigation'
import Link from 'next/link'
import Image from 'next/image'
import { useTranslation } from 'react-i18next'
import { FaStar, FaExternalLinkAlt } from 'react-icons/fa'
import { FaXmark, FaThumbtack, FaUser } from 'react-icons/fa6'
import { BsPlayBtn } from 'react-icons/bs'
import { FiStar, FiUser, FiUserX, FiInfo, FiTrendingUp, FiGlobe, FiEdit, FiLock, FiArrowLeft, FiChevronRight } from 'react-icons/fi'
import { FaRegStar } from "react-icons/fa";
import { MdVerified } from 'react-icons/md'
// components
import AvatarWithFrame, { AVATAR_FRAME_RING_PX } from '@/components/AvatarWithFrame'
import UserAvatarFrameCollectionModal from '@/app/user/_components/UserAvatarFrameCollectionModal'
import UserProfileFamiliesSection from '@/app/user/_components/UserProfileFamiliesSection'
import type { UserGroupListItem } from '@/server/groups/fetchUserGroups'
import UserCreateBoardPostModal from '@/app/user/_components/UserCreateBoardPostModal'
import { toAvatarFramePayload } from '@/lib/avatarFrames/resolveUrl'
import type { UserAvatarFrameListItem } from '@/lib/avatarFrames/types'
import VipBadgeLottie from '@/components/VipBadgeLottie'
import LiveCard, { type LiveStream } from '@/components/LiveCard'
import LivePreviewPlayer from '@/components/LivePreviewPlayer'
import Footer from '@/components/Footer'
import CommentInput from '@/app/catch/_components/CommentInput'
import CommentItem from '@/app/catch/_components/CommentItem'
import CommentsListSkeleton from '@/app/catch/_components/Skeletons/CommentsListSkeleton'
import type { Comment } from '@/app/catch/_components/types'

// utils
import { formatViews } from '@/utils/format'
import { formatDateTime } from '@/utils/formatDate'
import { hasValidImageSrc } from '@/lib/media/mediaGuards'

type UserVod = {
    id: string
    title: string
    thumb: string
    views: number
    startedAt: string
    startedTs: number
    duration: string
    category: string
    tags: string[]
}

type UserProfile = {
    id: string
    /** 個人頁網址路徑（有 display_id 時與 id 不同） */
    profileUrlPath?: string
    displayName: string
    avatar: string
    banner: string
    description: string
    followersCount: number
    totalViewsCount: number
    isVerified?: boolean
    vipLevel?: 'none' | 'vip' | 'vvip' | 'svip' | 'royal'
    avatarFrame?: {
        id: string
        image: string
        type: 'LOTTIE' | 'IMG'
    } | null
    live?: {
        isLive: boolean
        roomId: string
        title: string
        viewers: number
        startedAt: string
        thumbnail: string
        src?: string
    }
}

type UserBoardPost = {
    id: string
    authorName: string
    authorAvatar: string
    date: string
    pinned?: boolean
    content: string
    comments: number
    views: number
    thumb: string
    thumbCount?: number
}

export type { UserVod, UserProfile }

function countCommentsFlat(comments: Comment[]): number {
    let n = comments.length
    comments.forEach((c) => {
        if (c.nestedReplies?.length) n += countCommentsFlat(c.nestedReplies)
    })
    return n
}

export type ProfileTab = 'home' | 'replay' | 'board'

function getTabFromPathname(pathname: string | null, userId: string): ProfileTab | null {
    if (!pathname || !userId) return null
    const base = `/user/${encodeURIComponent(userId)}`
    if (pathname === base || pathname === `${base}/`) return 'home'
    if (pathname.startsWith(`${base}/replay`)) return 'replay'
    if (pathname.startsWith(`${base}/posts`)) return 'board'
    return 'home'
}

export default function UserPageClient({
    initialProfile,
    initialVods,
    initialBoardPosts,
    currentUserId,
    initialIsFollowing = false,
    initialIsBlocked = false,
    initialIsBlockedByTarget = false,
    initialSelectedPostId = null,
    initialSelectedPost = null,
    initialCurrentUserAvatar = null,
    initialTab = 'home',
    initialGroups = [],
}: {
    initialProfile: UserProfile
    initialVods: UserVod[]
    initialBoardPosts: UserBoardPost[]
    initialGroups?: UserGroupListItem[]
    currentUserId?: string | null
    initialIsFollowing?: boolean
    initialIsBlocked?: boolean
    initialIsBlockedByTarget?: boolean
    initialSelectedPostId?: string | null
    initialSelectedPost?: UserBoardPost | null
    initialCurrentUserAvatar?: string | null
    initialTab?: ProfileTab
}) {
    const { t } = useTranslation()
    const router = useRouter()
    const pathname = usePathname()

    const ownerUserId = initialProfile.id
    const profilePathSegment = initialProfile.profileUrlPath ?? ownerUserId
    const profileTab: ProfileTab =
        (pathname != null ? getTabFromPathname(pathname, profilePathSegment) : null) ??
        (initialSelectedPostId ? 'board' : initialTab)

    // Ref
    const livePreviewCloseTimerRef = useRef<number | null>(null)
    const mainRef = useRef<HTMLElement | null>(null)
    const livePreviewRef = useRef<HTMLDivElement | null>(null)
    const livePreviewConstraintRef = useRef<{
        mainRect: DOMRect
        cardW: number
        cardH: number
        margin: number
    } | null>(null)
    const livePreviewDragRef = useRef<{
        pointerId: number | null
        startX: number
        startY: number
        startLeft: number
        startTop: number
    }>({ pointerId: null, startX: 0, startY: 0, startLeft: 0, startTop: 0 })
    const livePreviewDragMovedRef = useRef(false)
    const profileFollowFxTimerRef = useRef<number | null>(null)
    const profileInfoCloseTimerRef = useRef<number | null>(null)
    const blockCloseTimerRef = useRef<number | null>(null)

    // State
    const [origin, setOrigin] = useState('')
    const [livePreviewHidden, setLivePreviewHidden] = useState(false)
    const [livePreviewClosing, setLivePreviewClosing] = useState(false)
    const [livePreviewBounds, setLivePreviewBounds] = useState<{
        leftMin: number
        leftMax: number
        topMin: number
        topMax: number
        cardW: number
        cardH: number
        margin: number
    } | null>(null)
    const [livePreviewSide, setLivePreviewSide] = useState<'left' | 'right'>('right')
    const [livePreviewTop, setLivePreviewTop] = useState<number | null>(null)
    const [livePreviewLeftOverride, setLivePreviewLeftOverride] = useState<number | null>(null)
    const [livePreviewDragging, setLivePreviewDragging] = useState(false)
    const [livePreviewSourceError, setLivePreviewSourceError] = useState(false)
    const [profileFlyingStars, setProfileFlyingStars] = useState<number[]>([])
    const [isProfileFollowing, setIsProfileFollowing] = useState(initialIsFollowing)
    const [followersCount, setFollowersCount] = useState(initialProfile.followersCount)
    const [profileInfoOpen, setProfileInfoOpen] = useState(false)
    const [profileInfoClosing, setProfileInfoClosing] = useState(false)
    const [profileInfoEntering, setProfileInfoEntering] = useState(false)
    const [blockOpen, setBlockOpen] = useState(false)
    const [blockClosing, setBlockClosing] = useState(false)
    const [blockEntering, setBlockEntering] = useState(false)
    const [isBlocked, setIsBlocked] = useState(initialIsBlocked)
    const [blockMode, setBlockMode] = useState<'block' | 'unblock'>('block')
    const [imageLightboxUrl, setImageLightboxUrl] = useState<string | null>(null)
    const [viewingPostId, setViewingPostId] = useState<string | null>(initialSelectedPostId ?? null)

    const selectedPost = useMemo(() => {
        if (!viewingPostId) return null
        return initialBoardPosts.find((p) => p.id === viewingPostId) ?? initialSelectedPost ?? null
    }, [viewingPostId, initialBoardPosts, initialSelectedPost])
    const [postComments, setPostComments] = useState<Comment[]>([])
    const [postCommentsLoading, setPostCommentsLoading] = useState(!!initialSelectedPostId)
    const [postCommentCount, setPostCommentCount] = useState(initialSelectedPost?.comments ?? 0)
    const [avatarFrameCollectionOpen, setAvatarFrameCollectionOpen] = useState(false)
    const [avatarFrameCollection, setAvatarFrameCollection] = useState<UserAvatarFrameListItem[] | null>(null)
    const [avatarFrameCollectionLoading, setAvatarFrameCollectionLoading] = useState(false)
    const [avatarFrameCollectionError, setAvatarFrameCollectionError] = useState<string | null>(null)
    const [activeAvatarFrame, setActiveAvatarFrame] = useState(initialProfile.avatarFrame ?? null)
    const [avatarFrameActionLoading, setAvatarFrameActionLoading] = useState(false)
    const [boardPosts, setBoardPosts] = useState(initialBoardPosts)
    const [createPostOpen, setCreatePostOpen] = useState(false)
    const [createPostSubmitting, setCreatePostSubmitting] = useState(false)
    const [createPostError, setCreatePostError] = useState<string | null>(null)

    const loadAvatarFrameCollection = useCallback(async () => {
        setAvatarFrameCollectionLoading(true)
        setAvatarFrameCollectionError(null)
        try {
            const res = await fetch(
                `/api/users/${encodeURIComponent(profilePathSegment)}/avatar-frames`
            )
            const data = (await res.json()) as {
                ok?: boolean
                data?: { frames?: UserAvatarFrameListItem[] }
                error?: string
            }
            if (!res.ok || !data.ok) {
                throw new Error(data.error || 'failed')
            }
            setAvatarFrameCollection(data.data?.frames ?? [])
        } catch {
            setAvatarFrameCollectionError(t('user.avatarFrames.loadError'))
        } finally {
            setAvatarFrameCollectionLoading(false)
        }
    }, [profilePathSegment, t])

    const openAvatarFrameCollection = useCallback(() => {
        setAvatarFrameCollectionOpen(true)
        if (avatarFrameCollection === null) {
            void loadAvatarFrameCollection()
        }
    }, [avatarFrameCollection, loadAvatarFrameCollection])

    useEffect(() => {
        if (!imageLightboxUrl) return
        const onKeyDown = (e: KeyboardEvent) => {
            if (e.key === 'Escape') setImageLightboxUrl(null)
        }
        window.addEventListener('keydown', onKeyDown)
        return () => window.removeEventListener('keydown', onKeyDown)
    }, [imageLightboxUrl])

    const fetchPostComments = useCallback(async () => {
        if (!viewingPostId) return
        setPostCommentsLoading(true)
        try {
            const res = await fetch(`/api/board-posts/${encodeURIComponent(viewingPostId)}/comments`)
            const data = await res.json()
            if (data.ok && data.data) {
                setPostComments(data.data)
                setPostCommentCount(countCommentsFlat(data.data))
            }
        } catch (e) {
            console.error('Failed to fetch comments:', e)
        } finally {
            setPostCommentsLoading(false)
        }
    }, [viewingPostId])

    useEffect(() => {
        if (viewingPostId) fetchPostComments()
    }, [viewingPostId, fetchPostComments])

    const handleCreateComment = useCallback(
        async (content: string) => {
            if (!viewingPostId) return
            const res = await fetch(`/api/board-posts/${encodeURIComponent(viewingPostId)}/comments`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ content }),
            })
            const data = await res.json()
            if (!data.ok) throw new Error(data.message || 'Failed to create comment')
            await fetchPostComments()
        },
        [viewingPostId, fetchPostComments]
    )

    const handleReply = useCallback(
        async (commentId: string, replyText: string, replyTo: string) => {
            if (!viewingPostId) return
            const res = await fetch(`/api/board-posts/${encodeURIComponent(viewingPostId)}/comments`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ content: replyText, parentId: commentId, replyTo }),
            })
            const data = await res.json()
            if (!data.ok) throw new Error(data.message || 'Failed to reply')
            await fetchPostComments()
        },
        [viewingPostId, fetchPostComments]
    )

    const handleDeleteComment = useCallback(
        async (commentId: string) => {
            if (!viewingPostId) return
            const res = await fetch(
                `/api/board-posts/${encodeURIComponent(viewingPostId)}/comments?commentId=${encodeURIComponent(commentId)}`,
                { method: 'DELETE' }
            )
            const data = await res.json()
            if (!data.ok) throw new Error(data.message || 'Failed to delete')
            await fetchPostComments()
        },
        [viewingPostId, fetchPostComments]
    )

    const closeLivePreview = useCallback(() => {
        if (livePreviewHidden) return
        if (livePreviewClosing) return
        setLivePreviewClosing(true)
        if (livePreviewCloseTimerRef.current !== null) {
            window.clearTimeout(livePreviewCloseTimerRef.current)
        }
        livePreviewCloseTimerRef.current = window.setTimeout(() => {
            setLivePreviewHidden(true)
            setLivePreviewClosing(false)
            livePreviewCloseTimerRef.current = null
        }, 200)
    }, [livePreviewClosing, livePreviewHidden])

    const triggerProfileStars = () => {
        const newStars = Array.from({ length: 5 }, (_, i) => Date.now() + i)
        setProfileFlyingStars(newStars)
        if (profileFollowFxTimerRef.current !== null) {
            window.clearTimeout(profileFollowFxTimerRef.current)
        }
        profileFollowFxTimerRef.current = window.setTimeout(() => {
            setProfileFlyingStars([])
            profileFollowFxTimerRef.current = null
        }, 1000)
    }

    const handleProfileFollowClick = async () => {
        if (isOwnProfile || !currentUserId) return

        try {
            const response = await fetch(`/api/users/${encodeURIComponent(profile.id)}/follow`, {
                method: 'POST',
            })
            const data = await response.json()
            if (data.ok && data.data) {
                const nextFollowing = Boolean(data.data.isFollowing)
                const nextFollowers = Number(data.data.followersCount ?? 0)
                setIsProfileFollowing(nextFollowing)
                setFollowersCount(nextFollowers)
                if (nextFollowing) triggerProfileStars()
                return
            }
        } catch (error) {
            console.error('Failed to toggle follow:', error)
        }

        setIsProfileFollowing((prev) => {
            if (!prev) triggerProfileStars()
            setFollowersCount((c) => (prev ? Math.max(0, c - 1) : c + 1))
            return !prev
        })
    }

    const openProfileInfo = useCallback(() => {
        if (profileInfoCloseTimerRef.current !== null) {
            window.clearTimeout(profileInfoCloseTimerRef.current)
            profileInfoCloseTimerRef.current = null
        }
        setProfileInfoEntering(true)
        setProfileInfoOpen(true)
        setProfileInfoClosing(false)
        requestAnimationFrame(() => requestAnimationFrame(() => setProfileInfoEntering(false)))
    }, [])

    const closeProfileInfo = useCallback((immediate?: boolean) => {
        if (!profileInfoOpen) return
        if (profileInfoCloseTimerRef.current !== null) {
            window.clearTimeout(profileInfoCloseTimerRef.current)
            profileInfoCloseTimerRef.current = null
        }

        if (immediate) {
            setProfileInfoEntering(false)
            setProfileInfoOpen(false)
            setProfileInfoClosing(false)
            return
        }

        if (profileInfoClosing) return
        setProfileInfoEntering(false)
        setProfileInfoClosing(true)
        profileInfoCloseTimerRef.current = window.setTimeout(() => {
            setProfileInfoOpen(false)
            setProfileInfoClosing(false)
            profileInfoCloseTimerRef.current = null
        }, 200)
    }, [profileInfoClosing, profileInfoOpen])

    const openBlock = useCallback(() => {
        if (blockCloseTimerRef.current !== null) {
            window.clearTimeout(blockCloseTimerRef.current)
            blockCloseTimerRef.current = null
        }
        setBlockMode(isBlocked ? 'unblock' : 'block')
        setBlockEntering(true)
        setBlockOpen(true)
        setBlockClosing(false)
        requestAnimationFrame(() => requestAnimationFrame(() => setBlockEntering(false)))
    }, [isBlocked])

    const closeBlock = useCallback((immediate?: boolean) => {
        if (!blockOpen) return
        if (blockCloseTimerRef.current !== null) {
            window.clearTimeout(blockCloseTimerRef.current)
            blockCloseTimerRef.current = null
        }

        if (immediate) {
            setBlockEntering(false)
            setBlockOpen(false)
            setBlockClosing(false)
            return
        }

        if (blockClosing) return
        setBlockEntering(false)
        setBlockClosing(true)
        blockCloseTimerRef.current = window.setTimeout(() => {
            setBlockOpen(false)
            setBlockClosing(false)
            blockCloseTimerRef.current = null
        }, 200)
    }, [blockClosing, blockOpen])

    useEffect(() => {
        if (typeof window !== 'undefined') {
            setOrigin(window.location.origin)
        }
        return () => {
            if (profileFollowFxTimerRef.current !== null) {
                window.clearTimeout(profileFollowFxTimerRef.current)
                profileFollowFxTimerRef.current = null
            }
            if (profileInfoCloseTimerRef.current !== null) {
                window.clearTimeout(profileInfoCloseTimerRef.current)
                profileInfoCloseTimerRef.current = null
            }
            if (blockCloseTimerRef.current !== null) {
                window.clearTimeout(blockCloseTimerRef.current)
                blockCloseTimerRef.current = null
            }
        }
    }, [])

    const profile = initialProfile
    const isOwnProfile = currentUserId !== null && currentUserId === profile.id
    const showCreatePostFab =
        isOwnProfile && profileTab === 'board' && !viewingPostId && !initialSelectedPostId

    const handleCreateBoardPost = useCallback(
        async (content: string, thumbnailUrl: string | null) => {
            setCreatePostSubmitting(true)
            setCreatePostError(null)
            try {
                const res = await fetch(
                    `/api/users/${encodeURIComponent(profilePathSegment)}/board-posts`,
                    {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ content, thumbnailUrl }),
                    }
                )
                const data = (await res.json()) as {
                    ok?: boolean
                    data?: { post?: UserBoardPost }
                    error?: string
                }
                if (!res.ok || !data.ok || !data.data?.post) {
                    throw new Error(data.error || 'failed')
                }
                const newPost = data.data.post
                setBoardPosts((prev) => {
                    const pinned = prev.filter((p) => p.pinned)
                    const rest = prev.filter((p) => !p.pinned)
                    return [...pinned, newPost, ...rest]
                })
                setCreatePostOpen(false)
            } catch {
                setCreatePostError(t('user.board.createPostError'))
            } finally {
                setCreatePostSubmitting(false)
            }
        },
        [profilePathSegment, t]
    )

    useEffect(() => {
        if (!isOwnProfile || avatarFrameCollection !== null) return
        void loadAvatarFrameCollection()
    }, [isOwnProfile, avatarFrameCollection, loadAvatarFrameCollection])

    const avatarFrameCollectionCount = avatarFrameCollection?.length ?? 0

    const applyAvatarFrameEquip = useCallback(
        async (frameId: string | null) => {
            if (!isOwnProfile) return
            setAvatarFrameActionLoading(true)
            setAvatarFrameCollectionError(null)
            try {
                const res = await fetch(
                    `/api/users/${encodeURIComponent(profilePathSegment)}/avatar-frames`,
                    {
                        method: 'PATCH',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ frameId }),
                    }
                )
                const data = (await res.json()) as {
                    ok?: boolean
                    data?: {
                        frames?: UserAvatarFrameListItem[]
                        activeFrame?: { id: string; image: string } | null
                    }
                    error?: string
                }
                if (!res.ok || !data.ok) {
                    throw new Error(data.error || 'failed')
                }
                setAvatarFrameCollection(data.data?.frames ?? [])
                setActiveAvatarFrame(
                    data.data?.activeFrame ? toAvatarFramePayload(data.data.activeFrame) : null
                )
            } catch {
                setAvatarFrameCollectionError(t('user.avatarFrames.actionError'))
            } finally {
                setAvatarFrameActionLoading(false)
            }
        },
        [isOwnProfile, profilePathSegment, t]
    )

    const handleUseAvatarFrame = useCallback(
        (frameId: string) => {
            void applyAvatarFrameEquip(frameId)
        },
        [applyAvatarFrameEquip]
    )

    const handleUnequipAvatarFrame = useCallback(() => {
        void applyAvatarFrameEquip(null)
    }, [applyAvatarFrameEquip])

    useEffect(() => {
        if (!profile?.live?.isLive) return
        if (livePreviewHidden) return

        const compute = () => {
            const mainEl = mainRef.current
            const cardEl = livePreviewRef.current
            if (!mainEl || !cardEl) return
            const mainRect = mainEl.getBoundingClientRect()
            const cardRect = cardEl.getBoundingClientRect()
            const margin = 16
            livePreviewConstraintRef.current = {
                mainRect,
                cardW: cardRect.width,
                cardH: cardRect.height,
                margin,
            }
            const topMin = Math.max(0, mainRect.top) + margin
            const bottomEdge = Math.min(window.innerHeight, mainRect.bottom) - margin
            const topMax = Math.max(topMin, bottomEdge - cardRect.height)
            const visLeft = Math.max(0, mainRect.left)
            const visRight = Math.min(window.innerWidth, mainRect.right)
            const leftMin = visLeft + margin
            const leftMax = Math.max(leftMin, (visRight - margin) - cardRect.width)
            setLivePreviewBounds((prev) => {
                const next = {
                    leftMin,
                    leftMax,
                    topMin,
                    topMax,
                    cardW: cardRect.width,
                    cardH: cardRect.height,
                    margin,
                }
                if (!prev) return next
                const same =
                    Math.abs(prev.leftMin - next.leftMin) < 0.5 &&
                    Math.abs(prev.leftMax - next.leftMax) < 0.5 &&
                    Math.abs(prev.topMin - next.topMin) < 0.5 &&
                    Math.abs(prev.topMax - next.topMax) < 0.5 &&
                    Math.abs(prev.cardW - next.cardW) < 0.5 &&
                    Math.abs(prev.cardH - next.cardH) < 0.5
                return same ? prev : next
            })
            setLivePreviewTop((prev) => {
                const desired = prev == null ? topMax : prev
                return Math.min(Math.max(desired, topMin), topMax)
            })
            setLivePreviewLeftOverride((prev) => {
                if (prev == null) return null
                return Math.min(Math.max(prev, leftMin), leftMax)
            })
        }

        const raf = window.requestAnimationFrame(compute)
        window.addEventListener('resize', compute)
        return () => {
            window.cancelAnimationFrame(raf)
            window.removeEventListener('resize', compute)
        }
    }, [livePreviewHidden, profile?.live?.isLive])

    const handleLivePreviewPointerDown = useCallback(
        (e: ReactPointerEvent<HTMLDivElement>) => {
            if (e.button !== 0) return
            const target = e.target as HTMLElement | null
            if (target?.closest?.('[data-live-preview-nodrag="1"]')) return
            const mainEl = mainRef.current
            const cardEl = livePreviewRef.current
            if (!mainEl || !cardEl) return
            const rect = cardEl.getBoundingClientRect()
            try {
                const mainRect = mainEl.getBoundingClientRect()
                const cardRect = rect
                const margin = 16
                livePreviewConstraintRef.current = {
                    mainRect,
                    cardW: cardRect.width,
                    cardH: cardRect.height,
                    margin,
                }
                const topMin = Math.max(0, mainRect.top) + margin
                const bottomEdge = Math.min(window.innerHeight, mainRect.bottom) - margin
                const topMax = Math.max(topMin, bottomEdge - cardRect.height)
                const visLeft = Math.max(0, mainRect.left)
                const visRight = Math.min(window.innerWidth, mainRect.right)
                const leftMin = visLeft + margin
                const leftMax = Math.max(leftMin, (visRight - margin) - cardRect.width)
                setLivePreviewBounds({ leftMin, leftMax, topMin, topMax, cardW: cardRect.width, cardH: cardRect.height, margin })
                setLivePreviewTop((prev) => {
                    const desired = prev == null ? topMax : prev
                    return Math.min(Math.max(desired, topMin), topMax)
                })
            } catch {
            }
            livePreviewDragMovedRef.current = false
            livePreviewDragRef.current = {
                pointerId: e.pointerId,
                startX: e.clientX,
                startY: e.clientY,
                startLeft: rect.left,
                startTop: rect.top,
            }
        },
        []
    )

    const handleLivePreviewPointerMove = useCallback((e: ReactPointerEvent<HTMLDivElement>) => {
        if (livePreviewDragRef.current.pointerId !== e.pointerId) return
        const c = livePreviewConstraintRef.current
        if (!c) return
        const dx = e.clientX - livePreviewDragRef.current.startX
        const dy = e.clientY - livePreviewDragRef.current.startY
        const moved = Math.abs(dx) + Math.abs(dy) > 3
        if (!livePreviewDragging) {
            if (!moved) return
            livePreviewDragMovedRef.current = true
            setLivePreviewDragging(true)
            try {
                ; (e.currentTarget as HTMLDivElement).setPointerCapture(e.pointerId)
            } catch {
            }
        } else if (moved) {
            livePreviewDragMovedRef.current = true
        }
        const visLeft = Math.max(0, c.mainRect.left)
        const visRight = Math.min(window.innerWidth, c.mainRect.right)
        const leftMin = visLeft + c.margin
        const leftMax = Math.max(leftMin, (visRight - c.margin) - c.cardW)
        const topMin = Math.max(0, c.mainRect.top) + c.margin
        const bottomEdge = Math.min(window.innerHeight, c.mainRect.bottom) - c.margin
        const topMax = Math.max(topMin, bottomEdge - c.cardH)
        const nextLeft = Math.min(Math.max(livePreviewDragRef.current.startLeft + dx, leftMin), leftMax)
        const nextTop = Math.min(Math.max(livePreviewDragRef.current.startTop + dy, topMin), topMax)
        setLivePreviewLeftOverride(nextLeft)
        setLivePreviewTop(nextTop)
    }, [livePreviewDragging])

    const endLivePreviewDrag = useCallback((e?: ReactPointerEvent<HTMLDivElement>) => {
        livePreviewDragRef.current.pointerId = null
        if (!livePreviewDragging) return
        setLivePreviewDragging(false)
        const c = livePreviewConstraintRef.current
        if (c && livePreviewLeftOverride != null) {
            const centerX = livePreviewLeftOverride + c.cardW / 2
            const visLeft = Math.max(0, c.mainRect.left)
            const visRight = Math.min(window.innerWidth, c.mainRect.right)
            const mainCenter = (visLeft + visRight) / 2
            setLivePreviewSide(centerX < mainCenter ? 'left' : 'right')
        }
        setLivePreviewLeftOverride(null)
        if (e) {
            try {
                ; (e.currentTarget as HTMLDivElement).releasePointerCapture(e.pointerId)
            } catch {
            }
        }
    }, [livePreviewDragging, livePreviewLeftOverride])

    const handleLivePreviewClickCapture = useCallback((e: ReactMouseEvent<HTMLDivElement>) => {
        if (!livePreviewDragMovedRef.current) return
        e.preventDefault()
        e.stopPropagation()
        livePreviewDragMovedRef.current = false
    }, [])

    const livePreviewStyle = useMemo(() => {
        const b = livePreviewBounds
        if (!b || livePreviewTop == null) {
            return { right: 16, bottom: 16 } as CSSProperties
        }
        const snapLeftRaw = livePreviewSide === 'left' ? b.leftMin : b.leftMax
        const snapLeft = Math.min(Math.max(snapLeftRaw, b.leftMin), b.leftMax)
        const left =
            livePreviewLeftOverride != null
                ? Math.min(Math.max(livePreviewLeftOverride, b.leftMin), b.leftMax)
                : snapLeft
        return {
            top: livePreviewTop,
            left,
            willChange: livePreviewDragging ? undefined : 'top, left',
        } as CSSProperties
    }, [livePreviewBounds, livePreviewDragging, livePreviewLeftOverride, livePreviewSide, livePreviewTop])

    useEffect(() => {
        if (!profileInfoOpen) return
        const onKeyDown = (e: KeyboardEvent) => {
            if (e.key === 'Escape') closeProfileInfo()
        }
        window.addEventListener('keydown', onKeyDown)
        return () => window.removeEventListener('keydown', onKeyDown)
    }, [profileInfoOpen, closeProfileInfo])

    useEffect(() => {
        return () => {
            if (livePreviewCloseTimerRef.current !== null) {
                window.clearTimeout(livePreviewCloseTimerRef.current)
                livePreviewCloseTimerRef.current = null
            }
        }
    }, [])

    useEffect(() => {
        if (!blockOpen) return
        const onKeyDown = (e: KeyboardEvent) => {
            if (e.key === 'Escape') closeBlock()
        }
        window.addEventListener('keydown', onKeyDown)
        return () => window.removeEventListener('keydown', onKeyDown)
    }, [blockOpen, closeBlock])

    const vodList = initialVods

    useEffect(() => {
        setBoardPosts(initialBoardPosts)
    }, [initialBoardPosts])

    const profileUrl =
        origin && profilePathSegment
            ? `${origin}/user/${encodeURIComponent(profilePathSegment)}`
            : `/user/${encodeURIComponent(profilePathSegment)}`
    const live = profile.live
    useEffect(() => {
        setLivePreviewSourceError(false)
    }, [live?.src, live?.roomId])
    useEffect(() => {
        if (!live?.isLive || !live?.src) return
        const src = live.src
        const ac = new AbortController()
        fetch(src, { method: 'GET', signal: ac.signal, mode: 'cors' })
            .then((res) => {
                if (res.status === 404) {
                    setLivePreviewSourceError(true)
                }
            })
            .catch(() => {})
        return () => ac.abort()
    }, [live?.isLive, live?.src])
    const handleLivePreviewSourceError = useCallback(() => {
        setLivePreviewSourceError(true)
    }, [])

    const confirmBlock = useCallback(async () => {
        if (isOwnProfile || !currentUserId) return
        try {
            const response = await fetch(`/api/users/${encodeURIComponent(profile.id)}/block`, {
                method: 'POST',
            })
            const data = await response.json()
            if (data.ok && data.data) {
                const nextBlocked = Boolean(data.data.isBlocked)
                setIsBlocked(nextBlocked)
                if (nextBlocked) {
                    setIsProfileFollowing(false)
                    if (data.data.followersCount !== undefined) {
                        setFollowersCount(Number(data.data.followersCount))
                    }
                }
                closeBlock()
                return
            }
        } catch (error) {
            console.error('Failed to toggle block:', error)
        }
        setIsBlocked((prev) => {
            if (blockMode === 'unblock') return false
            return true
        })
        closeBlock()
    }, [blockMode, closeBlock, profile.id, currentUserId, isOwnProfile])

    const tipBelowOnlyClass =
        "relative overflow-visible " +
        "before:content-[''] before:absolute before:left-1/2 before:top-[calc(100%+2px)] before:w-0 before:h-0 before:border-x-[5px] before:border-x-transparent before:border-b-[5px] before:border-b-[#525661] " +
        "before:z-10 before:pointer-events-none before:opacity-0 before:-translate-x-[60%] before:transition-all before:duration-200 before:ease-in " +
        "after:content-[attr(tip)] after:absolute after:left-1/2 after:top-[calc(100%+6px)] after:px-2.5 after:py-[7px] after:rounded-xl after:bg-[#525661] " +
        "after:text-[#fcfcfd] after:text-[13px] after:font-semibold after:leading-[1.2] after:whitespace-nowrap after:z-10 after:pointer-events-none " +
        "after:opacity-0 after:-translate-x-[60%] after:transition-all after:duration-200 after:ease-in " +
        "hover:before:opacity-100 hover:before:-translate-x-1/2 hover:after:opacity-100 hover:after:-translate-x-1/2 " +
        "focus-visible:before:opacity-100 focus-visible:before:-translate-x-1/2 focus-visible:after:opacity-100 focus-visible:after:-translate-x-1/2"

    return (
        <div className="flex flex-col flex-1 min-w-0">
        <main ref={mainRef} className="flex-1 min-w-0 overflow-visible">
            <section className="relative w-full overflow-visible">
                <div
                    className="w-full min-h-[220px] sm:min-h-[260px] md:min-h-[290px] bg-cover bg-center"
                    style={{
                        backgroundImage:
                            `url("${profile.banner || '/images/user/default_cover_v3.png'}")`,
                    }}
                />

                <div className="relative -mt-14 sm:-mt-[68px] md:-mt-[80px] px-4 sm:px-8 md:px-[120px] overflow-visible">
                    <div className="mx-auto max-w-[1600px] pointer-events-auto overflow-visible">
                        <div className="rounded-2xl sm:rounded-3xl border border-gray-200 dark:border-white/10 bg-white/90 dark:bg-[rgba(5,5,10,0.2)] backdrop-blur px-4 sm:px-6 md:px-8 py-3 sm:py-4 md:py-5 shadow-[0_18px_45px_rgba(0,0,0,0.18)] dark:shadow-[0_18px_45px_rgba(0,0,0,0.45)] overflow-visible">
                            <div className="flex flex-col overflow-visible">
                                <div className="flex items-start gap-5 sm:gap-6 min-w-0 overflow-visible">
                                    <div className="flex flex-col items-center flex-shrink-0">
                                        <div
                                            className="relative z-20 -mt-5 shrink-0 sm:-mt-12 md:-mt-8"
                                            style={{
                                                width: AVATAR_FRAME_RING_PX,
                                                height: AVATAR_FRAME_RING_PX,
                                                minWidth: AVATAR_FRAME_RING_PX,
                                                minHeight: AVATAR_FRAME_RING_PX,
                                            }}
                                        >
                                            <AvatarWithFrame
                                                avatarSrc={profile.avatar}
                                                alt={profile.displayName}
                                                frame={activeAvatarFrame}
                                                placeholderIconClassName="h-[52px] w-[52px]"
                                            />
                                        </div>
                                    </div>
                                    <div className="min-w-0 flex flex-col flex-1 pb-0.5 sm:pb-1">
                                        <div className="inline-flex items-center gap-1 flex-wrap">
                                            <h1 className="text-lg sm:text-xl md:text-2xl font-semibold truncate flex items-center gap-1.5">
                                                {profile.displayName}
                                                {profile.isVerified && (
                                                    <MdVerified
                                                        className="w-5 h-5 text-cyan-400 flex-shrink-0"
                                                        title={t('catch.verified')}
                                                    />
                                                )}
                                            </h1>
                                            <VipBadgeLottie
                                                vipLevel={profile.vipLevel}
                                                className="flex items-center flex-shrink-0 h-[28px] w-auto pointer-events-none"
                                                style={{ height: 24 }}
                                            />
                                        </div>
                                        <p className="text-gray-500 dark:text-white/70 text-sm truncate">
                                            @{profilePathSegment}
                                        </p>
                                        <div className="mt-1.5 flex flex-wrap items-center gap-2 select-none">
                                            <span className="inline-flex items-center rounded-full bg-gray-100 px-2.5 py-1 text-xs font-medium text-gray-700 dark:bg-neutral-800 dark:text-gray-200 sm:px-3 sm:py-1.5 sm:text-sm">
                                                {t('user.stats.followers', { value: formatViews(followersCount) })}
                                            </span>
                                            <span className="inline-flex items-center rounded-full bg-gray-100 px-2.5 py-1 text-xs font-medium text-gray-700 dark:bg-neutral-800 dark:text-gray-200 sm:px-3 sm:py-1.5 sm:text-sm">
                                                {t('user.stats.videos', { value: vodList.length })}
                                            </span>
                                        </div>
                                    </div>
                                </div>
                                <div className="mt-4 flex items-center gap-2 flex-shrink-0">
                                    {isOwnProfile ? (
                                        <button
                                            type="button"
                                            onClick={openAvatarFrameCollection}
                                            className="inline-flex h-10 max-w-full items-center justify-center gap-1.5 rounded-[12px] border border-gray-200 bg-white/90 px-3 text-xs font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 dark:border-white/15 dark:bg-black/25 dark:text-gray-100 dark:hover:bg-white/10 sm:px-4"
                                            aria-label={t('user.avatarFrames.collection')}
                                        >
                                            <span className="min-w-0 truncate">
                                                {avatarFrameCollection === null &&
                                                avatarFrameCollectionLoading
                                                    ? t('user.avatarFrames.loading')
                                                    : t('user.avatarFrames.collectionSummary', {
                                                          count: avatarFrameCollectionCount,
                                                      })}
                                            </span>
                                            <span className="inline-flex shrink-0 items-center gap-0.5 text-gray-500 dark:text-gray-400">
                                                {t('user.avatarFrames.viewCollection')}
                                                <FiChevronRight className="h-3.5 w-3.5" aria-hidden />
                                            </span>
                                        </button>
                                    ) : null}
                                    <div className="ml-auto flex items-center gap-2">
                                        {isOwnProfile ? (
                                            <div className="flex items-center gap-2">
                                                <button
                                                    type="button"
                                                    onClick={() => router.push('/my/profile')}
                                                    className="inline-flex h-10 items-center gap-2 rounded-[12px] border border-gray-200 dark:border-white/20 bg-white dark:bg-black/20 px-4 text-xs font-medium text-gray-700 dark:text-gray-100 hover:bg-[rgba(145,150,161,0.1)] transition-colors"
                                                >
                                                    <FiEdit className="w-4 h-4" />
                                                    <span>{t('user.actions.editProfile')}</span>
                                                </button>
                                                <button
                                                    type="button"
                                                    tip={t('user.actions.about')}
                                                    className={`inline-flex h-10 w-10 items-center justify-center rounded-[12px] border border-gray-200 dark:border-white/20 bg-white dark:bg-black/20 text-gray-700 dark:text-gray-100 hover:bg-[rgba(145,150,161,0.1)] transition-colors ${tipBelowOnlyClass}`}
                                                    onClick={openProfileInfo}
                                                    aria-label={t('user.actions.about')}
                                                >
                                                    <FiInfo className="w-5 h-5" />
                                                </button>
                                            </div>
                                        ) : (
                                            <>
                                                {currentUserId ? (
                                                    <div className="flex items-center gap-2">
                                                        {!isBlocked ? (
                                                            <button
                                                                type="button"
                                                                tip={isProfileFollowing ? t('room.unfollow') : t('room.follow')}
                                                                className={`group inline-flex h-10 items-center gap-2 rounded-[12px] border border-gray-200 dark:border-white/20 bg-white dark:bg-black/20 px-3 text-xs font-medium text-gray-700 dark:text-gray-100 hover:bg-[rgba(145,150,161,0.1)] transition-colors ${tipBelowOnlyClass}`}
                                                                onClick={handleProfileFollowClick}
                                                            >
                                                                <span className="relative inline-flex items-center justify-center w-5 h-5 mr-0.5">
                                                                    {profileFlyingStars.map((id, index) => {
                                                                        const animations = [
                                                                            'animate-heart-fly-1',
                                                                            'animate-heart-fly-2',
                                                                            'animate-heart-fly-3',
                                                                            'animate-heart-fly-4',
                                                                            'animate-heart-fly-5',
                                                                        ]
                                                                        return (
                                                                            <span
                                                                                // eslint-disable-next-line react/no-array-index-key
                                                                                key={`${id}-${index}`}
                                                                                className={`absolute inset-0 flex items-center justify-center pointer-events-none drop-shadow ${animations[index] || animations[0]
                                                                                    }`}
                                                                            >
                                                                                <FaStar className="w-5 h-5 text-yellow-500 dark:text-yellow-400" />
                                                                            </span>
                                                                        )
                                                                    })}
                                                                    {isProfileFollowing ? (
                                                                        <FaStar className="w-5 h-5 text-yellow-500 dark:text-yellow-400" />
                                                                    ) : (
                                                                        <FiStar className="w-5 h-5" />
                                                                    )}
                                                                </span>
                                                                <span className="leading-none">
                                                                    {isProfileFollowing ? t('user.actions.following') : t('room.follow')}
                                                                </span>
                                                            </button>
                                                        ) : null}
                                                        <button
                                                            type="button"
                                                            tip={isBlocked ? t('user.actions.unblock') : t('user.actions.block')}
                                                            className={`inline-flex h-10 w-10 items-center justify-center rounded-[12px] border border-gray-200 dark:border-white/20 bg-white dark:bg-black/20 text-gray-700 dark:text-gray-100 hover:bg-[rgba(145,150,161,0.1)] transition-colors ${tipBelowOnlyClass}`}
                                                            onClick={openBlock}
                                                            aria-label={isBlocked ? t('user.actions.unblock') : t('user.actions.block')}
                                                        >
                                                            <FiUserX className={`w-5 h-5 ${isBlocked ? 'text-red-600 dark:text-red-400' : ''}`} />
                                                        </button>
                                                    </div>
                                                ) : null}
                                                <button
                                                    type="button"
                                                    tip={t('user.actions.about')}
                                                    className={`inline-flex h-10 w-10 items-center justify-center rounded-[12px] border border-gray-200 dark:border-white/20 bg-white dark:bg-black/20 text-gray-700 dark:text-gray-100 hover:bg-[rgba(145,150,161,0.1)] transition-colors ${tipBelowOnlyClass}`}
                                                    onClick={openProfileInfo}
                                                    aria-label={t('user.actions.about')}
                                                >
                                                    <FiInfo className="w-5 h-5" />
                                                </button>
                                            </>
                                        )}
                                    </div>
                                </div>
                                <UserProfileFamiliesSection
                                    groups={initialGroups}
                                    title={t('user.families.title')}
                                    emptyText={t('user.families.empty')}
                                    leaderLabel={t('user.families.leader')}
                                    deputyLabel={t('user.families.deputy')}
                                    membersLabel={(count) => t('user.families.members', { count })}
                                />
                            </div>
                        </div>
                    </div>
                </div>
            </section>

            {profileInfoOpen && (
                <div
                    className={`fixed inset-0 z-[300] flex items-center justify-center bg-black/55 backdrop-blur-sm p-4 transition-opacity duration-200 ease-out ${profileInfoEntering || profileInfoClosing ? 'opacity-0' : 'opacity-100'
                        }`}
                    onClick={() => closeProfileInfo()}
                    role="dialog"
                    aria-modal="true"
                    aria-label={t('user.a11y.streamerInfo')}
                >
                    <div
                        className={`w-full max-w-[520px] rounded-2xl bg-white dark:bg-[#0c0d0e] border border-gray-200 dark:border-white/10 shadow-2xl transition-[opacity,transform] duration-200 ease-out ${profileInfoEntering || profileInfoClosing
                            ? 'opacity-0 scale-[0.97] translate-y-1'
                            : 'opacity-100 scale-100 translate-y-0'
                            }`}
                        onClick={(e) => e.stopPropagation()}
                    >
                        <div className="flex items-center justify-between px-5 py-4 border-b border-gray-200 dark:border-white/10">
                            <div className="text-base font-semibold text-gray-900 dark:text-white truncate flex items-center gap-1.5">
                                {profile.displayName}
                                {profile.isVerified && (
                                    <MdVerified
                                        className="w-5 h-5 text-cyan-400 flex-shrink-0"
                                        title={t('catch.verified')}
                                    />
                                )}
                            </div>
                            <button
                                type="button"
                                className="w-9 h-9 rounded-full inline-flex items-center justify-center hover:bg-[rgba(145,150,161,0.1)] transition-colors"
                                onClick={() => closeProfileInfo()}
                                aria-label={t('common.close')}
                            >
                                <FaXmark className="w-4 h-4" aria-hidden="true" />
                            </button>
                        </div>

                        <div className="px-5 py-5 space-y-3 text-sm text-gray-700 dark:text-gray-200">
                            <div className="flex items-center gap-3">
                                <span className="w-9 h-9 rounded-xl bg-gray-100 dark:bg-white/5 border border-gray-200 dark:border-white/10 inline-flex items-center justify-center">
                                    <FiGlobe className="w-5 h-5 text-gray-600 dark:text-white/80" />
                                </span>
                                <div className="min-w-0">
                                    <a
                                        href={profileUrl}
                                        className="text-gray-900 dark:text-gray-100 underline decoration-black/20 dark:decoration-white/20 underline-offset-4 break-all hover:decoration-black/50 dark:hover:decoration-white/60"
                                    >
                                        {profileUrl}
                                    </a>
                                </div>
                            </div>

                            <div className="flex items-center gap-3">
                                <span className="w-9 h-9 rounded-xl bg-gray-100 dark:bg-white/5 border border-gray-200 dark:border-white/10 inline-flex items-center justify-center">
                                    <FaRegStar className="w-5 h-5 text-gray-600 dark:text-white/80" />
                                </span>
                                <div className="min-w-0">
                                    <div className="text-gray-900 dark:text-gray-100">
                                        {t('user.stats.followers', { value: formatViews(followersCount) })}
                                    </div>
                                </div>
                            </div>

                            <div className="flex items-center gap-3">
                                <span className="w-9 h-9 rounded-xl bg-gray-100 dark:bg-white/5 border border-gray-200 dark:border-white/10 inline-flex items-center justify-center">
                                    <BsPlayBtn className="w-5 h-5 text-gray-600 dark:text-white/80" />
                                </span>
                                <div className="min-w-0">
                                    <div className="text-gray-900 dark:text-gray-100">
                                        {t('user.stats.videos', { value: vodList.length })}
                                    </div>
                                </div>
                            </div>

                            <div className="flex items-center gap-3">
                                <span className="w-9 h-9 rounded-xl bg-gray-100 dark:bg-white/5 border border-gray-200 dark:border-white/10 inline-flex items-center justify-center">
                                    <FiTrendingUp className="w-5 h-5 text-gray-600 dark:text-white/80" />
                                </span>
                                <div className="min-w-0">
                                    <div className="text-gray-900 dark:text-gray-100">
                                        {t('user.stats.totalViews', { value: profile.totalViewsCount.toLocaleString() })}
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            )}

            {blockOpen && (
                <div
                    className={`fixed inset-0 z-[310] flex items-center justify-center bg-black/55 backdrop-blur-sm p-4 transition-opacity duration-200 ease-out ${blockEntering || blockClosing ? 'opacity-0' : 'opacity-100'
                        }`}
                    onClick={() => closeBlock()}
                    role="dialog"
                    aria-modal="true"
                    aria-label={t('user.blockModal.title')}
                >
                    <div
                        className={`w-full max-w-[520px] rounded-2xl bg-white dark:bg-[#0c0d0e] border border-gray-200 dark:border-white/10 shadow-2xl transition-[opacity,transform] duration-200 ease-out ${blockEntering || blockClosing
                            ? 'opacity-0 scale-[0.97] translate-y-1'
                            : 'opacity-100 scale-100 translate-y-0'
                            }`}
                        onClick={(e) => e.stopPropagation()}
                    >
                        <div className="flex items-center justify-between px-5 py-4 border-b border-gray-200 dark:border-white/10">
                            <div className="text-base font-semibold text-gray-900 dark:text-white truncate">
                                {blockMode === 'unblock'
                                    ? t('user.actions.unblock')
                                    : t('user.actions.block')}
                            </div>
                            <button
                                type="button"
                                className="w-9 h-9 rounded-full inline-flex items-center justify-center hover:bg-[rgba(145,150,161,0.1)] transition-colors"
                                onClick={() => closeBlock()}
                                aria-label={t('common.close')}
                            >
                                <FaXmark className="w-4 h-4" aria-hidden="true" />
                            </button>
                        </div>

                        <div className="px-5 py-5 text-sm text-gray-700 dark:text-gray-200 text-center">
                            <div className="text-[15px] font-medium text-gray-900 dark:text-white">
                                {blockMode === 'unblock'
                                    ? t('user.blockModal.confirmTextUnblock', { name: profile.displayName })
                                    : t('user.blockModal.confirmTextBlock', { name: profile.displayName })}
                            </div>
                            <div className="mt-2 text-sm text-gray-600 dark:text-gray-300">
                                {blockMode === 'unblock'
                                    ? t('user.blockModal.descUnblock')
                                    : t('user.blockModal.descBlock')}
                            </div>

                            <div className="mt-6 flex gap-3">
                                <button
                                    type="button"
                                    onClick={() => closeBlock()}
                                    className="flex-1 h-10 rounded-xl border border-gray-300 dark:border-gray-700 bg-white dark:bg-[#0c0d0e] text-gray-900 dark:text-gray-100 text-sm hover:bg-gray-50 dark:hover:bg-[#121317] transition-colors"
                                >
                                    {t('common.cancel')}
                                </button>
                                <button
                                    type="button"
                                    onClick={confirmBlock}
                                    className={`flex-1 h-10 rounded-xl text-white text-sm transition-colors ${blockMode === 'unblock'
                                        ? 'bg-[#525661] hover:bg-[#3f424c] active:bg-[#2f3139]'
                                        : 'bg-red-600 hover:bg-red-700 active:bg-red-800'
                                        }`}
                                >
                                    {t('common.confirm')}
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            )}

            {isBlocked ? (
                <section className="mt-8 sm:mt-10 md:mt-12 px-4 sm:px-8 md:px-[120px]">
                    <div className="mx-auto max-w-[1600px] min-h-[40vh] flex items-center justify-center border-t border-gray-200 dark:border-white/10 py-12">
                        <div className="flex flex-col items-center gap-4 text-center">
                            <div className="w-16 h-16 rounded-full bg-gray-100 dark:bg-neutral-900 flex items-center justify-center">
                                <FiLock className="w-8 h-8 text-gray-500 dark:text-gray-400" />
                            </div>
                            <p className="text-base sm:text-lg text-gray-700 dark:text-gray-300">
                                {t('user.blocked.message')}
                            </p>
                        </div>
                    </div>
                </section>
            ) : (
                (() => {
                    const hasVod = vodList.length > 0
                    const hasBoard = boardPosts.length > 0

                    return (
                        <section className="mt-8 sm:mt-10 md:mt-12 px-4 sm:px-8 md:px-[120px] pb-12">
                            <div className="mx-auto max-w-[1600px]">
                                <div className="flex border-b border-gray-200 dark:border-white/10">
                                    <Link
                                        href={`/user/${encodeURIComponent(profilePathSegment)}`}
                                        className={`px-4 py-3 text-sm font-medium border-b-2 -mb-px transition-colors ${profileTab === 'home'
                                            ? 'border-gray-900 dark:border-white text-gray-900 dark:text-white'
                                            : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200'
                                            }`}
                                    >
                                        {t('user.tabs.home')}
                                    </Link>
                                    <Link
                                        href={`/user/${encodeURIComponent(profilePathSegment)}/replay`}
                                        className={`px-4 py-3 text-sm font-medium border-b-2 -mb-px transition-colors ${profileTab === 'replay'
                                            ? 'border-gray-900 dark:border-white text-gray-900 dark:text-white'
                                            : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200'
                                            }`}
                                    >
                                        {t('user.tabs.replay')}
                                    </Link>
                                    <Link
                                        href={`/user/${encodeURIComponent(profilePathSegment)}/posts`}
                                        className={`px-4 py-3 text-sm font-medium border-b-2 -mb-px transition-colors ${profileTab === 'board'
                                            ? 'border-gray-900 dark:border-white text-gray-900 dark:text-white'
                                            : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200'
                                            }`}
                                    >
                                        {t('user.tabs.board')}
                                    </Link>
                                </div>

                                {profileTab === 'home' && (
                                    <div className="pt-4">
                                        <div className="flex items-center justify-between mb-4">
                                            <h2 className="text-base sm:text-lg font-semibold text-gray-900 dark:text-white">
                                                {t('user.home.latestPosts')}
                                            </h2>
                                        </div>
                                        {boardPosts.length === 0 ? (
                                            <div className="flex items-center justify-center py-12">
                                                <p className="text-base sm:text-lg text-gray-700 dark:text-gray-300">
                                                    {t('user.emptyContent')}
                                                </p>
                                            </div>
                                        ) : (
                                            <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                                                {boardPosts.slice(0, 4).map((boardPost) => (
                                                    <div key={boardPost.id} className="rounded-xl border border-gray-200 dark:border-white/10 bg-white dark:bg-[#0c0d0e] shadow-sm overflow-hidden">
                                                        {initialSelectedPostId ? (
                                                            <Link
                                                                href={`/user/${encodeURIComponent(profilePathSegment)}/posts/${encodeURIComponent(boardPost.id)}`}
                                                                className="block w-full text-left p-4"
                                                            >
                                                                <p className="text-xs text-gray-500 dark:text-gray-400 mb-1">
                                                                    {boardPost.date}
                                                                </p>
                                                                <p className="text-sm text-gray-700 dark:text-gray-300 line-clamp-3 mb-3">
                                                                    {boardPost.content}
                                                                </p>
                                                                <div className="flex items-center gap-3 text-sm text-gray-600 dark:text-gray-400">
                                                                    <span className="inline-flex items-center gap-1" aria-label={t('user.board.likesCount')}>
                                                                        <svg viewBox="0 0 24 24" className="w-4 h-4" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" /></svg>
                                                                        {boardPost.views}
                                                                    </span>
                                                                    <span className="inline-flex items-center gap-1" aria-label={t('user.board.commentsCount')}>
                                                                        <svg viewBox="0 0 24 24" className="w-4 h-4" fill="currentColor"><path d="M5 4h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-5.59l-2.7 2.7A1 1 0 0 1 9 17.99V15H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z" /></svg>
                                                                        {boardPost.comments}
                                                                    </span>
                                                                </div>
                                                                {boardPost.thumb && (
                                                                    <div className="relative mt-3 aspect-square max-h-48 w-full overflow-hidden rounded-lg bg-gray-100 dark:bg-neutral-900">
                                                                        <Image src={boardPost.thumb} alt="" fill className="object-cover" unoptimized />
                                                                    </div>
                                                                )}
                                                            </Link>
                                                        ) : (
                                                            <Link href={`/user/${encodeURIComponent(profilePathSegment)}/posts/${encodeURIComponent(boardPost.id)}`} className="block w-full text-left p-4">
                                                                <p className="text-xs text-gray-500 dark:text-gray-400 mb-1">
                                                                    {boardPost.date}
                                                                </p>
                                                                <p className="text-sm text-gray-700 dark:text-gray-300 line-clamp-3 mb-3">
                                                                    {boardPost.content}
                                                                </p>
                                                                <div className="flex items-center gap-3 text-sm text-gray-600 dark:text-gray-400">
                                                                    <span className="inline-flex items-center gap-1" aria-label={t('user.board.likesCount')}>
                                                                        <svg viewBox="0 0 24 24" className="w-4 h-4" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" /></svg>
                                                                        {boardPost.views}
                                                                    </span>
                                                                    <span className="inline-flex items-center gap-1" aria-label={t('user.board.commentsCount')}>
                                                                        <svg viewBox="0 0 24 24" className="w-4 h-4" fill="currentColor"><path d="M5 4h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-5.59l-2.7 2.7A1 1 0 0 1 9 17.99V15H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z" /></svg>
                                                                        {boardPost.comments}
                                                                    </span>
                                                                </div>
                                                                {boardPost.thumb && (
                                                                    <div className="relative mt-3 aspect-square max-h-48 w-full overflow-hidden rounded-lg bg-gray-100 dark:bg-neutral-900">
                                                                        <Image src={boardPost.thumb} alt="" fill className="object-cover" unoptimized />
                                                                    </div>
                                                                )}
                                                            </Link>
                                                        )}
                                                    </div>
                                                ))}
                                            </div>
                                        )}
                                    </div>
                                )}

                                {profileTab === 'replay' && (
                                    <div className="pt-4">
                                        {!hasVod ? (
                                            <div className="flex items-center justify-center py-12">
                                                <p className="text-base sm:text-lg text-gray-700 dark:text-gray-300">
                                                    {t('user.emptyContent')}
                                                </p>
                                            </div>
                                        ) : (
                                            <div className="grid-popular">
                                                {vodList.map((vod, index) => {
                                                    const formattedTime = vod.startedAt ? formatDateTime(vod.startedAt) : ''
                                                    const stream: LiveStream = {
                                                        id: vod.id ?? String(index),
                                                        streamerName: profile.displayName,
                                                        title: vod.title,
                                                        category: vod.category,
                                                        viewerCount: vod.views,
                                                        thumbnail: vod.thumb,
                                                        avatar: profile.avatar,
                                                        startTime: formattedTime,
                                                        tags: vod.tags,
                                                    }
                                                    return <LiveCard key={stream.id} stream={stream} t={t} badgeLabel={t('explore.vod')} />
                                                })}
                                            </div>
                                        )}
                                    </div>
                                )}

                                {profileTab === 'board' && (
                                    <div className="pt-4">
                                        {viewingPostId && selectedPost ? (
                                            <>
                                                <div className="mb-4">
                                                    <Link
                                                        href={`/user/${encodeURIComponent(profilePathSegment)}/posts`}
                                                        className="inline-flex items-center gap-2 rounded-xl border border-gray-200 dark:border-white/20 bg-white dark:bg-black/20 px-3 py-2 text-sm font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-white/10 hover:border-gray-300 dark:hover:border-white/30 transition-colors"
                                                        aria-label={t('user.board.backToBoard')}
                                                    >
                                                        <FiArrowLeft className="w-4 h-4 flex-shrink-0" aria-hidden="true" />
                                                        <span>{t('user.board.backToBoard')}</span>
                                                    </Link>
                                                </div>
                                                <article className="border-t border-gray-200 dark:border-white/10 pt-3 first:border-t-0 first:pt-0">
                                                    {selectedPost.pinned && (
                                                        <div className="flex items-center gap-1.5 mb-2">
                                                            <FaThumbtack className="w-3.5 h-3.5 text-gray-500 dark:text-gray-400 flex-shrink-0" aria-hidden="true" />
                                                            <span className="text-xs text-gray-500 dark:text-gray-400">
                                                                {t('user.board.pinnedLabel')}
                                                            </span>
                                                        </div>
                                                    )}
                                                    <div className="flex items-center gap-3">
                                                        <div className="relative w-10 h-10 rounded-full overflow-hidden flex-shrink-0 border border-gray-200 dark:border-white/10">
                                                            {hasValidImageSrc(selectedPost.authorAvatar) ? (
                                                                <Image
                                                                    src={selectedPost.authorAvatar}
                                                                    alt=""
                                                                    fill
                                                                    className="object-cover"
                                                                    unoptimized
                                                                />
                                                            ) : (
                                                                <div className="flex h-full w-full items-center justify-center bg-gray-100 dark:bg-white/10">
                                                                    <FiUser className="w-4 h-4 text-gray-400" />
                                                                </div>
                                                            )}
                                                        </div>
                                                        <div className="min-w-0 flex-1">
                                                            <p className="text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
                                                                {selectedPost.authorName}
                                                            </p>
                                                            <p className="text-xs text-gray-500 dark:text-gray-400">
                                                                {selectedPost.date}
                                                            </p>
                                                        </div>
                                                    </div>
                                                    <div className="mt-3">
                                                        <p className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap break-words">
                                                            {selectedPost.content}
                                                        </p>
                                                    </div>
                                                    {selectedPost.thumb && (
                                                        <div className="mt-3 inline-block max-w-full">
                                                            <button
                                                                type="button"
                                                                onClick={() => setImageLightboxUrl(selectedPost.thumb)}
                                                                className="block text-left cursor-zoom-in focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-500 rounded-xl"
                                                            >
                                                                <Image
                                                                    src={selectedPost.thumb}
                                                                    alt=""
                                                                    width={640}
                                                                    height={360}
                                                                    className="max-h-[360px] max-w-xl w-auto h-auto rounded-xl bg-gray-100 dark:bg-neutral-900"
                                                                    unoptimized
                                                                />
                                                            </button>
                                                        </div>
                                                    )}
                                                    <div className="flex items-center gap-4 mt-3 pt-2">
                                                        <span className="inline-flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400" aria-label={t('user.board.likesCount')}>
                                                            <svg viewBox="0 0 24 24" className="w-5 h-5" fill="currentColor" aria-hidden="true">
                                                                <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
                                                            </svg>
                                                            <span>{selectedPost.views}</span>
                                                        </span>
                                                        <span className="inline-flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400" aria-label={t('user.board.commentsCount')}>
                                                            <svg viewBox="0 0 24 24" className="w-5 h-5" fill="currentColor" aria-hidden="true">
                                                                <path d="M5 4h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-5.59l-2.7 2.7A1 1 0 0 1 9 17.99V15H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z" />
                                                            </svg>
                                                            <span>{postCommentCount}</span>
                                                        </span>
                                                        <button
                                                            type="button"
                                                            className="inline-flex items-center justify-center w-9 h-9 rounded-full text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors"
                                                            aria-label={t('explore.share')}
                                                        >
                                                            <svg viewBox="0 0 24 24" className="w-5 h-5" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                                                                <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" />
                                                                <polyline points="16 6 12 2 8 6" />
                                                                <line x1="12" y1="2" x2="12" y2="15" />
                                                            </svg>
                                                        </button>
                                                    </div>
                                                </article>
                                                <hr className="my-8 border-gray-200 dark:border-white/10" />
                                                <section className="mt-6" aria-label={t('catch.comments')}>
                                                    <h2 className="text-base font-semibold text-gray-900 dark:text-white mb-4">
                                                        {t('catch.comments')} {postCommentCount}
                                                    </h2>
                                                    <div className="flex-shrink-0 mb-6 pb-4 border-b border-gray-200 dark:border-white/10">
                                                        <CommentInput
                                                            onSubmit={currentUserId ? handleCreateComment : undefined}
                                                            placeholder={t('user.board.commentPlaceholder')}
                                                            userAvatar={initialCurrentUserAvatar}
                                                            isLoggedIn={!!currentUserId}
                                                        />
                                                    </div>
                                                    {postCommentsLoading ? (
                                                        <CommentsListSkeleton />
                                                    ) : postComments.length > 0 ? (
                                                        <div className="space-y-4">
                                                            {postComments.map((comment) => (
                                                                <CommentItem
                                                                    key={comment.id}
                                                                    comment={comment}
                                                                    onReply={currentUserId ? handleReply : undefined}
                                                                    onDelete={handleDeleteComment}
                                                                    userAvatar={initialCurrentUserAvatar}
                                                                    isLoggedIn={!!currentUserId}
                                                                    currentUserId={currentUserId ?? undefined}
                                                                    videoOwnerId={ownerUserId}
                                                                />
                                                            ))}
                                                        </div>
                                                    ) : (
                                                        <p className="py-8 text-center text-sm text-gray-500 dark:text-gray-400">
                                                            {t('catch.commentsEmpty')}
                                                        </p>
                                                    )}
                                                </section>
                                            </>
                                        ) : !hasBoard ? (
                                            <div className="flex items-center justify-center py-12">
                                                <p className="text-base sm:text-lg text-gray-700 dark:text-gray-300">
                                                    {t('user.emptyContent')}
                                                </p>
                                            </div>
                                        ) : (
                                            <ul className="list-none p-0 m-0">
                                                {boardPosts.map((boardPost) => (
                                                    <li
                                                        key={boardPost.id}
                                                        className="border-t border-gray-200 dark:border-white/10 py-3 first:border-t-0 first:pt-0"
                                                    >
                                                        {boardPost.pinned && (
                                                            <div className="flex items-center gap-1.5 mb-2">
                                                                <FaThumbtack className="w-3.5 h-3.5 text-gray-500 dark:text-gray-400 flex-shrink-0" aria-hidden="true" />
                                                                <span className="text-xs text-gray-500 dark:text-gray-400">
                                                                    {t('user.board.pinnedLabel')}
                                                                </span>
                                                            </div>
                                                        )}
                                                        <div className="flex items-center gap-3">
                                                            <div className="relative w-10 h-10 rounded-full overflow-hidden flex-shrink-0 border border-gray-200 dark:border-white/10">
                                                                {hasValidImageSrc(boardPost.authorAvatar) ? (
                                                                    <Image
                                                                        src={boardPost.authorAvatar}
                                                                        alt=""
                                                                        fill
                                                                        className="object-cover"
                                                                        unoptimized
                                                                    />
                                                                ) : (
                                                                    <div className="flex h-full w-full items-center justify-center bg-gray-100 dark:bg-white/10">
                                                                        <FiUser className="w-4 h-4 text-gray-400" />
                                                                    </div>
                                                                )}
                                                            </div>
                                                            <div className="min-w-0 flex-1">
                                                                <p className="text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
                                                                    {boardPost.authorName}
                                                                </p>
                                                                <p className="text-xs text-gray-500 dark:text-gray-400">
                                                                    {boardPost.date}
                                                                </p>
                                                            </div>
                                                        </div>
                                                        {initialSelectedPostId ? (
                                                            <button
                                                                type="button"
                                                                onClick={() => setViewingPostId(boardPost.id)}
                                                                className="block w-full text-left mt-3 rounded-xl cursor-pointer"
                                                            >
                                                                <p className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap break-words">
                                                                    {boardPost.content}
                                                                </p>
                                                                {boardPost.thumb && (
                                                                    <div className="mt-3 inline-block max-w-full">
                                                                        <Image
                                                                            src={boardPost.thumb}
                                                                            alt=""
                                                                            width={640}
                                                                            height={360}
                                                                            className="max-h-[360px] max-w-xl w-auto h-auto rounded-xl bg-gray-100 dark:bg-neutral-900"
                                                                            unoptimized
                                                                        />
                                                                    </div>
                                                                )}
                                                            </button>
                                                        ) : (
                                                            <Link
                                                                href={`/user/${encodeURIComponent(profilePathSegment)}/posts/${encodeURIComponent(boardPost.id)}`}
                                                                className="block w-full text-left mt-3 rounded-xl"
                                                            >
                                                                <p className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap break-words">
                                                                    {boardPost.content}
                                                                </p>
                                                                {boardPost.thumb && (
                                                                    <div className="mt-3 inline-block max-w-full">
                                                                        <Image
                                                                            src={boardPost.thumb}
                                                                            alt=""
                                                                            width={640}
                                                                            height={360}
                                                                            className="max-h-[360px] max-w-xl w-auto h-auto rounded-xl bg-gray-100 dark:bg-neutral-900"
                                                                            unoptimized
                                                                        />
                                                                    </div>
                                                                )}
                                                            </Link>
                                                        )}
                                                        <div className="flex items-center gap-4 mt-3 pt-2">
                                                                <span className="inline-flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400" aria-label={t('user.board.likesCount')}>
                                                                    <svg viewBox="0 0 24 24" className="w-5 h-5" fill="currentColor" aria-hidden="true">
                                                                        <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
                                                                    </svg>
                                                                    <span>{boardPost.views}</span>
                                                                </span>
                                                                {initialSelectedPostId ? (
                                                                    <button
                                                                        type="button"
                                                                        onClick={() => setViewingPostId(boardPost.id)}
                                                                        className="inline-flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 transition-colors"
                                                                        aria-label={t('user.board.commentsCount')}
                                                                    >
                                                                        <svg viewBox="0 0 24 24" className="w-5 h-5" fill="currentColor" aria-hidden="true">
                                                                            <path d="M5 4h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-5.59l-2.7 2.7A1 1 0 0 1 9 17.99V15H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z" />
                                                                        </svg>
                                                                        <span>{boardPost.comments}</span>
                                                                    </button>
                                                                ) : (
                                                                    <Link
                                                                        href={`/user/${encodeURIComponent(profilePathSegment)}/posts/${encodeURIComponent(boardPost.id)}`}
                                                                        className="inline-flex items-center gap-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 transition-colors"
                                                                        aria-label={t('user.board.commentsCount')}
                                                                    >
                                                                        <svg viewBox="0 0 24 24" className="w-5 h-5" fill="currentColor" aria-hidden="true">
                                                                            <path d="M5 4h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-5.59l-2.7 2.7A1 1 0 0 1 9 17.99V15H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z" />
                                                                        </svg>
                                                                        <span>{boardPost.comments}</span>
                                                                    </Link>
                                                                )}
                                                                <button
                                                                    type="button"
                                                                    className="inline-flex items-center justify-center w-9 h-9 rounded-full text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors"
                                                                    aria-label={t('explore.share')}
                                                                >
                                                                    <svg viewBox="0 0 24 24" className="w-5 h-5" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                                                                        <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" />
                                                                        <polyline points="16 6 12 2 8 6" />
                                                                        <line x1="12" y1="2" x2="12" y2="15" />
                                                                    </svg>
                                                                </button>
                                                            </div>
                                                    </li>
                                                ))}
                                            </ul>
                                        )}
                                    </div>
                                )}
                            </div>
                        </section>
                    )
                })()
            )}

            {imageLightboxUrl && (
                <div
                    className="fixed inset-0 z-[320] flex items-center justify-center bg-black/80 p-4"
                    onClick={() => setImageLightboxUrl(null)}
                    role="dialog"
                    aria-modal="true"
                    aria-label={t('common.close')}
                >
                    <button
                        type="button"
                        className="absolute top-4 right-4 z-10 w-10 h-10 rounded-full bg-black/50 hover:bg-black/70 text-white inline-flex items-center justify-center transition-colors"
                        onClick={() => setImageLightboxUrl(null)}
                        aria-label={t('common.close')}
                    >
                        <FaXmark className="w-5 h-5" />
                    </button>
                    <Image
                        src={imageLightboxUrl}
                        alt=""
                        width={1200}
                        height={900}
                        className="max-w-full max-h-[90vh] w-auto h-auto object-contain rounded-lg"
                        onClick={(e) => e.stopPropagation()}
                        draggable={false}
                        unoptimized
                    />
                </div>
            )}

            {live && live.isLive && !livePreviewHidden && !livePreviewSourceError && !isBlocked && (
                <div
                    ref={livePreviewRef}
                    className={`group fixed z-[150] w-[300px] rounded-[24px] border border-gray-200 dark:border-white/10 bg-white/90 dark:bg-[#0c0d0e]/90 backdrop-blur p-3 shadow-[0_18px_45px_rgba(0,0,0,0.25)] pointer-events-auto touch-none select-none ${livePreviewDragging
                        ? 'cursor-grabbing transition-none'
                        : 'transition-[left,top] duration-[420ms] ease-[cubic-bezier(0.22,1,0.36,1)]'
                        }`}
                    style={livePreviewStyle}
                    onPointerDown={handleLivePreviewPointerDown}
                    onPointerMove={handleLivePreviewPointerMove}
                    onPointerUp={endLivePreviewDrag}
                    onPointerCancel={endLivePreviewDrag}
                    onClickCapture={handleLivePreviewClickCapture}
                    onDragStart={(e) => e.preventDefault()}
                >
                    <div className="relative">
                        <div
                            className={`block transition-[opacity,transform] duration-200 ease-out ${livePreviewClosing ? 'opacity-0 scale-[0.98] translate-y-1 pointer-events-none' : 'opacity-100 scale-100 translate-y-0'
                                }`}
                        >
                            <div className="relative w-full aspect-video overflow-hidden rounded-2xl border border-gray-200/60 dark:border-white/10 bg-black">
                                {live.src ? (
                                    <LivePreviewPlayer
                                        src={live.src}
                                        poster={live.thumbnail}
                                        className="absolute inset-0 pointer-events-none"
                                        onSourceError={handleLivePreviewSourceError}
                                    />
                                ) : hasValidImageSrc(live.thumbnail) ? (
                                    <Image
                                        src={live.thumbnail}
                                        alt="live"
                                        fill
                                        className="pointer-events-none"
                                        unoptimized
                                    />
                                ) : (
                                    <div className="absolute inset-0 bg-gray-800" />
                                )}

                                <div className="absolute inset-0 z-[2] bg-black/35 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" />

                                <div className="absolute top-2 left-2 z-[10]">
                                    <span className="inline-flex items-center gap-1.5 rounded-full bg-black/70 px-2 h-6 text-xs text-white">
                                        <span className="w-1.5 h-1.5 rounded-full bg-red-500" aria-hidden="true" />
                                        <span>{live.viewers.toLocaleString()}</span>
                                    </span>
                                </div>
                            </div>

                                <div className="mt-2 flex items-center gap-2">
                                    <div className="flex-1 min-w-0 text-sm font-semibold text-gray-900 dark:text-white line-clamp-2">
                                        {live.title}
                                    </div>

                                    <div className="ml-auto flex items-center gap-1">
                                        <button
                                        type="button"
                                        className="w-9 h-9 rounded-full inline-flex items-center justify-center bg-black/10 dark:bg-white/10 text-gray-700 dark:text-gray-100 hover:bg-[rgba(145,150,161,0.1)] transition-colors"
                                        aria-label={t('user.livePreview.enter')}
                                        data-live-preview-nodrag="1"
                                        onClick={(e) => {
                                            e.preventDefault()
                                            e.stopPropagation()
                                            router.push(`/room/${live.roomId}`)
                                        }}
                                    >
                                        <FaExternalLinkAlt className="w-4 h-4" aria-hidden="true" />
                                        </button>

                                    <button
                                        type="button"
                                        className="w-9 h-9 rounded-full inline-flex items-center justify-center bg-black/10 dark:bg-white/10 text-gray-700 dark:text-gray-100 hover:bg-[rgba(145,150,161,0.1)] transition-colors"
                                        aria-label={t('room.close')}
                                        onClick={(e) => {
                                            e.preventDefault()
                                            e.stopPropagation()
                                            closeLivePreview()
                                        }}
                                        data-live-preview-nodrag="1"
                                    >
                                        <FaXmark className="w-4 h-4" aria-hidden="true" />
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            )}
            {showCreatePostFab ? (
                <button
                    type="button"
                    onClick={() => {
                        setCreatePostError(null)
                        setCreatePostOpen(true)
                    }}
                    className="fixed bottom-6 right-6 z-[160] inline-flex h-14 w-14 items-center justify-center rounded-full bg-neutral-900 text-white shadow-lg shadow-black/25 transition-transform hover:scale-105 active:scale-95 dark:bg-white dark:text-neutral-900 dark:shadow-black/50"
                    aria-label={t('user.board.createPost')}
                    title={t('user.board.createPost')}
                >
                    <FiEdit className="h-6 w-6" strokeWidth={2} aria-hidden />
                </button>
            ) : null}
            <UserCreateBoardPostModal
                open={createPostOpen}
                onClose={() => {
                    if (!createPostSubmitting) setCreatePostOpen(false)
                }}
                title={t('user.board.createPostTitle')}
                authorName={profile.displayName}
                authorAvatar={profile.avatar || null}
                contentPlaceholder={t('user.board.createPostPlaceholder')}
                addToPostLabel={t('user.board.createPostAddToPost')}
                addImageLabel={t('user.board.createPostAddImage')}
                removeImageLabel={t('user.board.createPostRemoveImage')}
                imageTooLargeLabel={t('user.board.createPostImageTooLarge')}
                imageInvalidLabel={t('user.board.createPostImageInvalid')}
                submitLabel={t('user.board.createPostSubmit')}
                cancelLabel={t('common.cancel')}
                submitting={createPostSubmitting}
                error={createPostError}
                onSubmit={handleCreateBoardPost}
            />
            <UserAvatarFrameCollectionModal
                open={avatarFrameCollectionOpen}
                onClose={() => setAvatarFrameCollectionOpen(false)}
                frames={avatarFrameCollection}
                loading={avatarFrameCollectionLoading}
                error={avatarFrameCollectionError}
                avatarSrc={profile.avatar}
                displayName={profile.displayName}
                title={t('user.avatarFrames.modalTitle')}
                emptyText={t('user.avatarFrames.empty')}
                closeLabel={t('room.viewerCard.close')}
                countLabel={(count) => t('user.avatarFrames.count', { count })}
                equippedLabel={t('user.avatarFrames.equipped')}
                loadingText={t('user.avatarFrames.loading')}
                useLabel={t('user.avatarFrames.use')}
                unequipLabel={t('user.avatarFrames.unequip')}
                canManage={isOwnProfile}
                actionLoading={avatarFrameActionLoading}
                onUse={handleUseAvatarFrame}
                onUnequip={handleUnequipAvatarFrame}
            />
        </main>
        <Footer />
        </div>
    )
}


