'use client'

import Image from 'next/image'
import Link from 'next/link'
import AvatarWithFrame, { AVATAR_FRAME_RING_PX_SM } from '@/components/AvatarWithFrame'
import { resolveAvatarFrameAssetUrl } from '@/lib/avatarFrames/resolveUrl'
import type { AvatarFramePayload } from '@/lib/avatarFrames/types'
import { useCallback, useEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import { FaUser } from 'react-icons/fa6'
import {
    FiChevronLeft,
    FiChevronRight,
    FiX,
    FiShield,
    FiClock,
    FiMessageSquare,
    FiFileText,
    FiGift,
    FiMessageCircle,
    FiSlash,
    FiCheckCircle,
    FiUserMinus,
    FiUserPlus,
} from 'react-icons/fi'
import { useToast } from '@/contexts/ToastContext'
import type { ParticipantItem, ViewerCardState, UserAdminInfo } from '../types'
import { isGuestParticipant } from './UserRoleUtils'
import UserFamilyCard from '@/components/groups/UserFamilyCard'
import { resolveMediaUrl } from '@/lib/media/resolveMediaUrl'
import { hasValidImageSrc } from '@/lib/media/mediaGuards'
import { formatViews } from '@/utils/format'

const VIEWER_EXIT_MS = 320

const plainActionBtnClass =
    'inline-flex min-h-[48px] w-full flex-row items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white px-3 py-2.5 text-sm font-medium leading-tight text-gray-700 outline-none transition hover:bg-gray-50 focus-visible:ring-2 focus-visible:ring-gray-400/40 active:scale-[0.98] disabled:opacity-60 dark:border-neutral-700 dark:bg-[#14161a] dark:text-gray-100 dark:hover:bg-[#1a1c21]'

export default function ViewerCard({
    cardRef,
    viewerCard,
    viewerCardDepth,
    t,
    onClose,
    onBackToRoot,
    onGift,
    onWhisper,
    isModerator,
    isStreamer,
    isSuperAdmin,
    onBan,
    onUnban,
    isBanned,
    currentUserId,
    userAdminInfo,
    onAddMod,
    onRemoveMod,
    streamerId,
}: {
    cardRef: React.RefObject<HTMLDivElement>
    viewerCard: ViewerCardState
    viewerCardDepth: 'root' | 'gift' | 'admin'
    t: (key: string, options?: Record<string, unknown>) => string
    onClose: () => void
    onBackToRoot: () => void
    onGift: (user: ParticipantItem) => void
    onWhisper?: (user: ParticipantItem) => void
    isModerator?: boolean
    isStreamer?: boolean
    isSuperAdmin?: boolean
    onBan?: (user: ParticipantItem) => void
    onUnban?: (user: ParticipantItem) => void
    isBanned?: boolean
    currentUserId?: string | null
    userAdminInfo?: UserAdminInfo | null
    onAddMod?: (user: ParticipantItem) => void
    onRemoveMod?: (user: ParticipantItem) => void
    streamerId?: string
}) {
    const [profileExtra, setProfileExtra] = useState<{
        displayName: string
        avatar: string | null
        handle: string
        profilePath: string
        avatarFrame: AvatarFramePayload | null
        followersCount: number
    } | null>(null)
    const [families, setFamilies] = useState<
        Array<{
            id: string
            name: string
            avatar: string | null
            role: string
            membersCount: number
        }> | null
    >(null)
    const [isClosing, setIsClosing] = useState(false)
    const [isFollowing, setIsFollowing] = useState<boolean | null>(null)
    const [followSubmitting, setFollowSubmitting] = useState(false)
    const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
    const { showToast } = useToast()

    const clearCloseTimer = useCallback(() => {
        if (closeTimerRef.current !== null) {
            clearTimeout(closeTimerRef.current)
            closeTimerRef.current = null
        }
    }, [])

    const requestClose = useCallback(() => {
        if (isClosing) return
        if (typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
            onClose()
            return
        }
        setIsClosing(true)
        clearCloseTimer()
        closeTimerRef.current = setTimeout(() => {
            closeTimerRef.current = null
            onClose()
        }, VIEWER_EXIT_MS)
    }, [isClosing, onClose, clearCloseTimer])

    useEffect(() => {
        setIsClosing(false)
        clearCloseTimer()
        setIsFollowing(null)
        setFollowSubmitting(false)
    }, [viewerCard.user.id, viewerCard.mode, clearCloseTimer])

    useEffect(() => () => clearCloseTimer(), [clearCloseTimer])

    useEffect(() => {
        if (!viewerCard || viewerCardDepth !== 'root') {
            setProfileExtra(null)
            setFamilies(null)
            return
        }
        const u = viewerCard.user
        const uid = u.id
        if (!uid || uid.startsWith('guest_')) {
            setProfileExtra({
                displayName: u.name,
                avatar: u.avatarUrl ?? null,
                handle: uid.replace(/^guest_/, '') || 'guest',
                profilePath: '',
                avatarFrame: null,
                followersCount: 0,
            })
            setFamilies([])
            return
        }
        setFamilies(null)
        let cancelled = false
        const apiKey = String(u.displayId || '').trim() || String(u.profileApiKey || '').trim() || uid
        fetch(`/api/users/${encodeURIComponent(apiKey)}?lite=1`)
            .then((r) => r.json())
            .then((payload: unknown) => {
                if (cancelled) return
                const infoData = payload as {
                    ok?: boolean
                    data?: {
                        user?: {
                            displayName?: string
                            avatar?: string | null
                            displayId?: string | null
                            profilePathSegment?: string
                            id?: string
                            followersCount?: number
                        }
                        avatarFrame?: AvatarFramePayload | null
                        groups?: Array<{
                            id: string
                            name: string
                            avatar?: string | null
                            role?: string
                            membersCount?: number
                        }>
                    }
                }
                const row = infoData?.data?.user
                if (infoData?.ok && row) {
                    const displayIdTrim = String(row.displayId ?? '').trim()
                    const pathSeg = displayIdTrim || String(row.id || uid)
                    const frameRaw = infoData?.data?.avatarFrame
                    const avatarFrame =
                        frameRaw && frameRaw.image
                            ? {
                                  id: String(frameRaw.id ?? ''),
                                  image: resolveAvatarFrameAssetUrl(String(frameRaw.image)),
                                  type:
                                      String(frameRaw.type ?? 'IMG').toUpperCase() === 'LOTTIE'
                                          ? ('LOTTIE' as const)
                                          : ('IMG' as const),
                              }
                            : null
                    setProfileExtra({
                        displayName: String(row.displayName || u.name),
                        avatar: row.avatar != null && row.avatar !== '' ? String(row.avatar) : (u.avatarUrl ?? null),
                        handle: pathSeg,
                        profilePath: pathSeg,
                        avatarFrame,
                        followersCount: Number(row.followersCount) || 0,
                    })
                } else {
                    setProfileExtra({
                        displayName: u.name,
                        avatar: u.avatarUrl ?? null,
                        handle: uid,
                        profilePath: uid,
                        avatarFrame: null,
                        followersCount: 0,
                    })
                }
                const gList = infoData?.data?.groups
                setFamilies(
                    Array.isArray(gList)
                        ? gList.map((g) => {
                              const resolved = resolveMediaUrl(g.avatar)
                              return {
                                  id: g.id,
                                  name: g.name,
                                  avatar: resolved || null,
                                  role: String(g.role ?? 'member').trim() || 'member',
                                  membersCount: Number(g.membersCount) || 0,
                              }
                          })
                        : []
                )
            })
            .catch(() => {
                if (!cancelled) {
                    setProfileExtra({
                        displayName: u.name,
                        avatar: u.avatarUrl ?? null,
                        handle: uid,
                        profilePath: uid,
                        avatarFrame: null,
                        followersCount: 0,
                    })
                    setFamilies([])
                }
            })
        return () => {
            cancelled = true
        }
    }, [viewerCard, viewerCardDepth])

    useEffect(() => {
        if (viewerCardDepth !== 'root') {
            setIsFollowing(null)
            return
        }
        const u = viewerCard.user
        const uid = u.id
        if (!uid || uid.startsWith('guest_') || !currentUserId || uid === currentUserId) {
            setIsFollowing(null)
            return
        }
        let cancelled = false
        const apiKey = String(u.displayId || '').trim() || String(u.profileApiKey || '').trim() || uid
        fetch(`/api/users/${encodeURIComponent(apiKey)}/follow`)
            .then((r) => r.json())
            .then((payload: unknown) => {
                if (cancelled) return
                const data = payload as { ok?: boolean; data?: { isFollowing?: boolean } }
                setIsFollowing(Boolean(data?.ok && data?.data?.isFollowing))
            })
            .catch(() => {
                if (!cancelled) setIsFollowing(false)
            })
        return () => {
            cancelled = true
        }
    }, [viewerCard.user, viewerCardDepth, currentUserId])

    const pe = profileExtra
    const cardUser = viewerCard.user
    const isGuestUser = isGuestParticipant(cardUser)
    /** API 回傳前：僅用已知 display_id / profileApiKey；勿用 user_id 佔位以免先閃 UUID 再換成 display_id */
    const optimisticHandle =
        String(cardUser.displayId || '').trim() || String(cardUser.profileApiKey || '').trim()
    const rootDisplayName = pe?.displayName ?? cardUser.name
    const rootHandle = pe?.handle ?? (optimisticHandle || cardUser.id)
    const rootAvatarUrl = pe?.avatar ?? cardUser.avatarUrl
    const rootAvatarFrame = pe?.avatarFrame ?? null
    const profileHref =
        pe?.profilePath && !cardUser.id.startsWith('guest_') ? `/user/${encodeURIComponent(pe.profilePath)}` : null
    const uidForHandle = cardUser.id
    const showHandleSkeleton =
        viewerCardDepth === 'root' &&
        Boolean(uidForHandle) &&
        !uidForHandle.startsWith('guest_') &&
        pe === null &&
        !optimisticHandle.trim()
    const isSelf = Boolean(currentUserId && cardUser.id === currentUserId)
    const showFollowButton =
        viewerCardDepth === 'root' && !isGuestUser && !isSelf && Boolean(currentUserId)
    const followApiKey =
        String(cardUser.displayId || '').trim() ||
        String(cardUser.profileApiKey || '').trim() ||
        cardUser.id

    const handleFollowClick = async () => {
        if (!currentUserId) {
            showToast(t('room.loginRequired'), 'error')
            return
        }
        if (followSubmitting || isFollowing === null) return
        setFollowSubmitting(true)
        try {
            const res = await fetch(`/api/users/${encodeURIComponent(followApiKey)}/follow`, { method: 'POST' })
            const json = await res.json().catch(() => null)
            const data = json?.data
            if (json?.ok && data) {
                const nextFollowing = Boolean(data.isFollowing)
                const nextFollowers = Number(data.followersCount)
                setIsFollowing(nextFollowing)
                if (Number.isFinite(nextFollowers)) {
                    setProfileExtra((prev) =>
                        prev
                            ? { ...prev, followersCount: nextFollowers }
                            : prev
                    )
                }
                return
            }
            setIsFollowing((prev) => {
                if (prev === null) return prev
                const next = !prev
                setProfileExtra((pePrev) =>
                    pePrev
                        ? {
                              ...pePrev,
                              followersCount: Math.max(0, pePrev.followersCount + (next ? 1 : -1)),
                          }
                        : pePrev
                )
                return next
            })
        } catch {
            // ignore
        } finally {
            setFollowSubmitting(false)
        }
    }

    const showGiftButton = !isSelf && !isStreamer
    const showWhisperButton = Boolean(onWhisper)
    const showPrimaryActionsRow = Boolean(
        currentUserId && !isGuestUser && (showFollowButton || showGiftButton || showWhisperButton)
    )

    const canBanUser = (() => {
        if (isGuestUser || viewerCard.user.id === currentUserId) return false
        if (isSuperAdmin) return true
        const targetIsStreamer =
            viewerCard.user.userType === 'streamer' || (streamerId && viewerCard.user.id === streamerId)
        const targetIsSuperAdmin = viewerCard.user.userType === 'superAdmin' || userAdminInfo?.isSuperAdmin
        if (isStreamer) {
            if (targetIsSuperAdmin) return false
            return true
        }
        if (isModerator && !isStreamer) {
            if (targetIsStreamer) return false
            if (viewerCard.user.userType === 'manager') return false
            if (targetIsSuperAdmin) return false
            return true
        }
        return false
    })()

    const showBanRow = !isGuestUser && canBanUser && Boolean(onBan || onUnban)
    const targetIsSuperAdminMod = viewerCard.user.userType === 'superAdmin' || userAdminInfo?.isSuperAdmin
    const showModRow =
        !isGuestUser &&
        Boolean(isStreamer || isSuperAdmin) &&
        viewerCard.user.id !== currentUserId &&
        viewerCard.user.userType !== 'streamer' &&
        !targetIsSuperAdminMod &&
        Boolean(onAddMod || onRemoveMod)

    const showActionsSection = !isGuestUser && (showPrimaryActionsRow || showBanRow || showModRow)

    const headerLeft =
        viewerCardDepth === 'admin' && userAdminInfo ? (
            <button
                type="button"
                onClick={onBackToRoot}
                className="inline-flex min-w-0 items-center gap-1.5 text-sm font-semibold text-gray-900 dark:text-white hover:opacity-80 transition-opacity"
            >
                <FiChevronLeft className="w-4 h-4 flex-shrink-0" />
                <span className="truncate">{t('room.viewerCard.adminView')}</span>
            </button>
        ) : viewerCardDepth === 'gift' ? (
            <button
                type="button"
                onClick={onBackToRoot}
                className="inline-flex min-w-0 items-center gap-1.5 text-sm font-semibold text-gray-900 dark:text-white hover:opacity-80 transition-opacity"
            >
                <FiChevronLeft className="w-4 h-4 flex-shrink-0" />
                <span className="truncate">{t('room.viewerCard.gift')}</span>
            </button>
        ) : (
            <span className="truncate text-sm font-semibold text-gray-900 dark:text-white">{t('room.viewerCard.seeMore')}</span>
        )

    const modal = (
        <div
            ref={cardRef}
            className={`fixed inset-0 z-[500] flex items-center justify-center p-3 sm:p-4${isClosing ? ' pointer-events-none' : ''}`}
        >
            <div
                className={`absolute inset-0 bg-black/45 dark:bg-black/60 ${isClosing ? 'gp-viewer-exit-backdrop' : 'gp-viewer-enter-backdrop'}`}
                aria-hidden="true"
            />
            <div
                key={`${viewerCard.user.id}-${viewerCard.mode}`}
                role="dialog"
                aria-modal="true"
                aria-label={t('room.viewerCard.seeMore')}
                className={`relative z-10 flex max-h-[min(90vh,720px)] w-full min-w-0 max-w-[400px] flex-col overflow-hidden rounded-2xl border border-gray-200 bg-white shadow-xl dark:border-gray-800 dark:bg-[#0c0d0e] ${isClosing ? 'gp-viewer-exit-panel' : 'gp-viewer-enter-panel'}`}
            >
                <div className="flex h-11 shrink-0 items-center justify-between gap-2 border-b border-gray-100 bg-white px-3 dark:border-neutral-800 dark:bg-[#0c0d0e]">
                    <div className="min-w-0 flex-1">{headerLeft}</div>
                    <button
                        type="button"
                        onClick={requestClose}
                        className="inline-flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full text-[#525661] transition-colors hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-[#1a1c21]"
                        aria-label={t('room.viewerCard.close')}
                    >
                        <FiX className="h-[18px] w-[18px]" />
                    </button>
                </div>

                {viewerCardDepth === 'admin' && userAdminInfo ? (
                    <div className="max-h-[600px] overflow-y-auto pb-2">
                        <div className="px-3 pb-2 pt-3">
                            <div className="mb-3 flex items-start gap-2">
                                <span className="h-10 w-10 flex-shrink-0 overflow-hidden rounded-full border border-gray-200 bg-gray-200 dark:border-gray-800 dark:bg-neutral-900">
                                    {userAdminInfo.avatarUrl ? (
                                        <Image
                                            src={userAdminInfo.avatarUrl}
                                            alt=""
                                            width={40}
                                            height={40}
                                            className="h-full w-full object-cover"
                                            unoptimized
                                        />
                                    ) : (
                                        <span className="flex h-full w-full items-center justify-center text-gray-400">
                                            <FaUser className="h-5 w-5" />
                                        </span>
                                    )}
                                </span>
                                <div className="min-w-0 flex-1">
                                    <div className="break-words text-base font-semibold leading-6 text-gray-900 dark:text-white">
                                        {userAdminInfo.userName}
                                    </div>
                                    <div className="mt-0.5 break-words text-sm text-gray-500 dark:text-gray-400">{userAdminInfo.userId}</div>
                                    <div className="mt-1 flex items-center gap-1 text-xs text-gray-400 dark:text-gray-500">
                                        <FiClock className="h-3 w-3" />
                                        <span>
                                            {t('room.viewerCard.createdAt')}: {new Date(userAdminInfo.createdAt).toLocaleDateString()}
                                        </span>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div className="mx-3 h-px bg-gray-100 dark:bg-neutral-900" />

                        <div className="px-3 pb-2 pt-2">
                            <div className="mb-2 flex items-center gap-2">
                                <FiMessageSquare className="h-4 w-4 text-gray-500 dark:text-gray-400" />
                                <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">
                                    {t('room.viewerCard.chatHistory')} ({userAdminInfo.chatMessages.length})
                                </span>
                            </div>
                            <div className="max-h-[150px] space-y-1 overflow-y-auto">
                                {userAdminInfo.chatMessages.length > 0 ? (
                                    userAdminInfo.chatMessages.map((msg) => (
                                        <div key={msg.id} className="rounded bg-gray-50 p-2 text-xs text-gray-600 dark:bg-[#1a1c21] dark:text-gray-400">
                                            <div className="mb-1 text-gray-400 dark:text-gray-500">{new Date(msg.createdAt).toLocaleString()}</div>
                                            <div className="break-words">{msg.text}</div>
                                        </div>
                                    ))
                                ) : (
                                    <div className="text-xs text-gray-400 dark:text-gray-500">{t('room.viewerCard.noChatHistory')}</div>
                                )}
                            </div>
                        </div>

                        <div className="mx-3 h-px bg-gray-100 dark:bg-neutral-900" />

                        <div className="px-3 pb-2 pt-2">
                            <div className="mb-2 flex items-center gap-2">
                                <FiShield className="h-4 w-4 text-gray-500 dark:text-gray-400" />
                                <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">
                                    {t('room.viewerCard.banHistory')} ({userAdminInfo.banHistory.length})
                                </span>
                            </div>
                            <div className="max-h-[150px] space-y-1 overflow-y-auto">
                                {userAdminInfo.banHistory.length > 0 ? (
                                    userAdminInfo.banHistory.map(
                                        (ban: {
                                            id: string
                                            reason?: string
                                            durationMs?: number | null
                                            bannedAt: string
                                            bannedBy: string
                                            expiresAt?: number | null
                                            isPermanent: boolean
                                        }) => (
                                            <div key={ban.id} className="rounded bg-gray-50 p-2 text-xs text-gray-600 dark:bg-[#1a1c21] dark:text-gray-400">
                                                <div className="mb-1 flex items-center justify-between">
                                                    <span className="text-gray-400 dark:text-gray-500">{new Date(ban.bannedAt).toLocaleString()}</span>
                                                    <span
                                                        className={`rounded px-2 py-0.5 text-xs ${ban.isPermanent
                                                            ? 'bg-red-100 text-red-700 dark:bg-red-900/20 dark:text-red-300'
                                                            : 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/20 dark:text-yellow-300'
                                                            }`}
                                                    >
                                                        {ban.isPermanent ? t('room.ban.modal.durations.permanent') : t('room.viewerCard.temporaryBan')}
                                                    </span>
                                                </div>
                                                {ban.reason && <div className="mt-1 text-gray-500 dark:text-gray-400">{ban.reason}</div>}
                                                <div className="mt-1 text-xs text-gray-400 dark:text-gray-500">
                                                    {t('room.viewerCard.bannedBy')}: {ban.bannedBy}
                                                </div>
                                            </div>
                                        )
                                    )
                                ) : (
                                    <div className="text-xs text-gray-400 dark:text-gray-500">{t('room.viewerCard.noBanHistory')}</div>
                                )}
                            </div>
                        </div>

                        <div className="mx-3 h-px bg-gray-100 dark:bg-neutral-900" />

                        <div className="px-3 pb-2 pt-2">
                            <div className="mb-2 flex items-center gap-2">
                                <FiFileText className="h-4 w-4 text-gray-500 dark:text-gray-400" />
                                <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">
                                    {t('room.viewerCard.adminNotes')} ({userAdminInfo.adminNotes.length})
                                </span>
                            </div>
                            <div className="max-h-[150px] space-y-1 overflow-y-auto">
                                {userAdminInfo.adminNotes.length > 0 ? (
                                    userAdminInfo.adminNotes.map((note: { id: string; note: string; createdAt: string; createdBy: string }) => (
                                        <div key={note.id} className="rounded bg-gray-50 p-2 text-xs text-gray-600 dark:bg-[#1a1c21] dark:text-gray-400">
                                            <div className="mb-1 text-gray-400 dark:text-gray-500">
                                                {new Date(note.createdAt).toLocaleString()} - {note.createdBy}
                                            </div>
                                            <div className="break-words">{note.note}</div>
                                        </div>
                                    ))
                                ) : (
                                    <div className="text-xs text-gray-400 dark:text-gray-500">{t('room.viewerCard.noAdminNotes')}</div>
                                )}
                            </div>
                        </div>
                    </div>
                ) : viewerCardDepth === 'root' ? (
                    <div className="min-h-0 flex-1 overflow-y-auto pb-2">
                        <div className="px-4 pt-1">
                            <div className="flex items-center gap-3">
                                <div
                                    className="flex shrink-0 items-center justify-center"
                                    style={{
                                        width: AVATAR_FRAME_RING_PX_SM,
                                        height: AVATAR_FRAME_RING_PX_SM,
                                        minWidth: AVATAR_FRAME_RING_PX_SM,
                                        minHeight: AVATAR_FRAME_RING_PX_SM,
                                    }}
                                >
                                    <AvatarWithFrame
                                        size="sm"
                                        avatarSrc={rootAvatarUrl}
                                        alt={rootDisplayName}
                                        frame={rootAvatarFrame}
                                        href={profileHref ?? undefined}
                                        placeholderIconClassName="h-8 w-8"
                                    />
                                </div>
                                <div className="min-w-0 flex-1 self-center">
                                    <p className="text-lg font-bold leading-snug text-gray-900 dark:text-white break-words">{rootDisplayName}</p>
                                    <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
                                        {showHandleSkeleton ? (
                                            <span className="inline-block h-4 w-24 animate-pulse rounded bg-gray-200 dark:bg-neutral-800" />
                                        ) : (
                                            <span className="break-all">@{rootHandle}</span>
                                        )}
                                    </p>
                                    {!isGuestUser && pe !== null ? (
                                        <p className="mt-1 text-sm text-gray-500 dark:text-gray-400 tabular-nums">
                                            {t('room.viewerCard.followers', {
                                                value: formatViews(pe.followersCount),
                                            })}
                                        </p>
                                    ) : null}
                                </div>
                            </div>
                        </div>
                        {families !== null && families.length > 0 ? (
                            <div className="mt-1 px-4 pb-1">
                                <p className="mb-2 text-xs font-semibold text-gray-500 dark:text-white/60">
                                    {t('user.families.title')}
                                </p>
                                <ul className="flex flex-col gap-2">
                                    {families.map((g) => (
                                        <li key={g.id}>
                                            <UserFamilyCard
                                                group={g}
                                                leaderLabel={t('user.families.leader')}
                                                deputyLabel={t('user.families.deputy')}
                                                membersLabel={(count) =>
                                                    t('user.families.members', { count })
                                                }
                                            />
                                        </li>
                                    ))}
                                </ul>
                            </div>
                        ) : null}

                        {showActionsSection ? (
                        <div className="border-t border-gray-100 px-4 pt-3 mt-2 dark:border-neutral-800">
                            {showPrimaryActionsRow ? (
                                <div className="flex flex-col gap-2.5">
                                    {showFollowButton ? (
                                        <button
                                            type="button"
                                            onClick={() => void handleFollowClick()}
                                            disabled={followSubmitting || isFollowing === null}
                                            className={plainActionBtnClass}
                                        >
                                            <FiUserPlus className="h-5 w-5 shrink-0 opacity-95" aria-hidden />
                                            <span className="truncate">
                                                {isFollowing ? t('room.unfollow') : t('room.follow')}
                                            </span>
                                        </button>
                                    ) : null}
                                    {showGiftButton ? (
                                        <button
                                            type="button"
                                            onClick={() => onGift(viewerCard.user)}
                                            className={plainActionBtnClass}
                                        >
                                            <FiGift className="h-5 w-5 shrink-0 opacity-95" aria-hidden />
                                            <span className="truncate">{t('room.viewerCard.gift')}</span>
                                        </button>
                                    ) : null}
                                    {showWhisperButton ? (
                                        <button
                                            type="button"
                                            onClick={() => onWhisper!(viewerCard.user)}
                                            className="inline-flex min-h-[48px] w-full flex-row items-center justify-center gap-2 rounded-xl bg-gradient-to-br from-violet-600 to-indigo-600 px-3 py-2.5 text-sm font-semibold leading-tight text-white shadow-md shadow-violet-500/25 outline-none ring-violet-500/30 transition hover:brightness-110 hover:shadow-lg hover:shadow-violet-500/30 focus-visible:ring-2 active:scale-[0.98] dark:shadow-indigo-950/40"
                                        >
                                            <FiMessageCircle className="h-5 w-5 shrink-0 opacity-95" aria-hidden />
                                            <span>{t('room.viewerCard.whisper')}</span>
                                        </button>
                                    ) : null}
                                </div>
                            ) : null}
                            {showBanRow || showModRow ? (
                                (() => {
                                const modActionClass =
                                    'group relative flex w-full min-h-[52px] items-center gap-3 overflow-hidden rounded-xl border px-3 py-2.5 text-left outline-none transition focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-white focus-visible:ring-gray-400/40 active:scale-[0.99] dark:focus-visible:ring-offset-[#0c0d0e] dark:focus-visible:ring-gray-500/40'

                                return (
                                    <div
                                        className={
                                            currentUserId
                                                ? 'mt-3 space-y-2'
                                                : 'mt-3 space-y-2 border-t border-gray-100 pt-3 dark:border-neutral-800'
                                        }
                                    >
                                        {showBanRow ? (
                                            isBanned && onUnban ? (
                                                <button
                                                    type="button"
                                                    onClick={() => onUnban(viewerCard.user)}
                                                    className={`${modActionClass} border-emerald-200 bg-emerald-50/95 text-emerald-950 shadow-sm hover:bg-emerald-100/95 dark:border-emerald-400/45 dark:bg-emerald-500/15 dark:text-emerald-50 dark:shadow-md dark:shadow-black/30 dark:hover:bg-emerald-500/25`}
                                                >
                                                    <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-emerald-100 text-emerald-700 ring-1 ring-emerald-200/80 dark:bg-emerald-500/30 dark:text-emerald-200 dark:ring-emerald-400/40">
                                                        <FiCheckCircle className="h-5 w-5" strokeWidth={2} aria-hidden />
                                                    </span>
                                                    <span className="min-w-0 flex-1">
                                                        <span className="block text-sm font-semibold leading-tight text-emerald-950 dark:text-emerald-50">
                                                            {t('room.viewerCard.unban')}
                                                        </span>
                                                        <span className="mt-0.5 block text-[11px] font-medium leading-snug text-emerald-800/90 dark:text-emerald-300/90">
                                                            {t('room.viewerCard.unbanHint')}
                                                        </span>
                                                    </span>
                                                    <FiChevronRight
                                                        className="h-4 w-4 shrink-0 text-emerald-600/60 opacity-0 transition group-hover:translate-x-0.5 group-hover:opacity-100 dark:text-emerald-300/80"
                                                        aria-hidden
                                                    />
                                                </button>
                                            ) : (
                                                onBan && (
                                                    <button
                                                        type="button"
                                                        onClick={() => onBan(viewerCard.user)}
                                                        className={`${modActionClass} border-rose-200 bg-rose-50/95 text-rose-950 shadow-sm hover:bg-rose-100/95 dark:border-rose-400/45 dark:bg-rose-500/15 dark:text-rose-50 dark:shadow-md dark:shadow-black/30 dark:hover:bg-rose-500/25`}
                                                    >
                                                        <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-rose-100 text-rose-700 ring-1 ring-rose-200/80 dark:bg-rose-500/30 dark:text-rose-200 dark:ring-rose-400/40">
                                                            <FiSlash className="h-5 w-5" strokeWidth={2.25} aria-hidden />
                                                        </span>
                                                        <span className="min-w-0 flex-1">
                                                            <span className="block text-sm font-semibold leading-tight text-rose-950 dark:text-rose-50">
                                                                {t('room.viewerCard.ban')}
                                                            </span>
                                                            <span className="mt-0.5 block text-[11px] font-medium leading-snug text-rose-800/90 dark:text-rose-300/90">
                                                                {t('room.viewerCard.banHint')}
                                                            </span>
                                                        </span>
                                                        <FiChevronRight
                                                            className="h-4 w-4 shrink-0 text-rose-600/60 opacity-0 transition group-hover:translate-x-0.5 group-hover:opacity-100 dark:text-rose-300/80"
                                                            aria-hidden
                                                        />
                                                    </button>
                                                )
                                            )
                                        ) : null}
                                        {showModRow ? (
                                            (() => {
                                                const isMod =
                                                    userAdminInfo !== null && userAdminInfo !== undefined
                                                        ? userAdminInfo.isMod
                                                        : viewerCard.user.userType === 'manager'

                                                return isMod && onRemoveMod ? (
                                                    <button
                                                        type="button"
                                                        onClick={() => onRemoveMod(viewerCard.user)}
                                                        className={`${modActionClass} border-amber-200 bg-amber-50/95 text-amber-950 shadow-sm hover:bg-amber-100/95 dark:border-amber-400/45 dark:bg-amber-500/15 dark:text-amber-50 dark:shadow-md dark:shadow-black/30 dark:hover:bg-amber-500/25`}
                                                    >
                                                        <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-amber-100 text-amber-800 ring-1 ring-amber-200/80 dark:bg-amber-500/30 dark:text-amber-200 dark:ring-amber-400/40">
                                                            <FiUserMinus className="h-5 w-5" strokeWidth={2} aria-hidden />
                                                        </span>
                                                        <span className="min-w-0 flex-1">
                                                            <span className="block text-sm font-semibold leading-tight text-amber-950 dark:text-amber-50">
                                                                {t('room.viewerCard.removeMod')}
                                                            </span>
                                                            <span className="mt-0.5 block text-[11px] font-medium leading-snug text-amber-900/85 dark:text-amber-300/90">
                                                                {t('room.viewerCard.removeModHint')}
                                                            </span>
                                                        </span>
                                                        <FiChevronRight
                                                            className="h-4 w-4 shrink-0 text-amber-700/55 opacity-0 transition group-hover:translate-x-0.5 group-hover:opacity-100 dark:text-amber-300/80"
                                                            aria-hidden
                                                        />
                                                    </button>
                                                ) : (
                                                    onAddMod && (
                                                        <button
                                                            type="button"
                                                            onClick={() => onAddMod(viewerCard.user)}
                                                            className={`${modActionClass} border-sky-200 bg-sky-50/95 text-slate-900 shadow-sm hover:bg-sky-100/95 dark:border-sky-400/45 dark:bg-sky-500/15 dark:text-sky-50 dark:shadow-md dark:shadow-black/30 dark:hover:bg-sky-500/25`}
                                                        >
                                                            <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-sky-100 text-sky-800 ring-1 ring-sky-200/80 dark:bg-sky-500/30 dark:text-sky-200 dark:ring-sky-400/40">
                                                                <FiShield className="h-5 w-5" strokeWidth={2} aria-hidden />
                                                            </span>
                                                            <span className="min-w-0 flex-1">
                                                                <span className="block text-sm font-semibold leading-tight text-slate-900 dark:text-sky-50">
                                                                    {t('room.viewerCard.addMod')}
                                                                </span>
                                                                <span className="mt-0.5 block text-[11px] font-medium leading-snug text-slate-600 dark:text-sky-300/90">
                                                                    {t('room.viewerCard.addModHint')}
                                                                </span>
                                                            </span>
                                                            <FiChevronRight
                                                                className="h-4 w-4 shrink-0 text-sky-700/55 opacity-0 transition group-hover:translate-x-0.5 group-hover:opacity-100 dark:text-sky-300/80"
                                                                aria-hidden
                                                            />
                                                        </button>
                                                    )
                                                )
                                            })()
                                        ) : null}
                                    </div>
                                )
                            })()
                            ) : null}
                        </div>
                        ) : null}
                    </div>
                ) : (
                    <div className="pb-2">
                        <ul className="pt-1">
                            <li>
                                <button
                                    type="button"
                                    className="flex h-9 w-full items-center px-3 text-sm text-[#525661] transition-colors hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-[#1a1c21]"
                                >
                                    {t('room.viewerCard.subscription')}
                                </button>
                            </li>
                            <li>
                                <button
                                    type="button"
                                    className="flex h-9 w-full items-center px-3 text-sm text-[#525661] transition-colors hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-[#1a1c21]"
                                >
                                    {t('room.viewerCard.quickview')}
                                </button>
                            </li>
                        </ul>
                    </div>
                )}
            </div>
        </div>
    )

    if (typeof document === 'undefined') return null
    return createPortal(modal, document.body)
}
