'use client'

import Image from 'next/image'
import { FaCrown, FaWrench } from 'react-icons/fa'
import { FaS } from 'react-icons/fa6'
import { CHAT_EMOJI_MESSAGE_PX, findChatEmojiByCode } from '@/app/room/_components/chat/chatEmojis'
import type { ChatMessage, MentionInfo, ParticipantItem, EmojiInfo } from '../types'
import { getUserRoleBadge, getUserNameColor } from './UserRoleUtils'

/**
 * 格式化禁言時長
 * @param durationMs 時長（毫秒），null 表示永久
 * @param isPermanent 是否永久禁言
 * @param t 翻譯函數
 * @returns 格式化後的時長字符串
 */
function formatBanDuration(
    durationMs: number | null | undefined,
    isPermanent: boolean | undefined,
    t: (key: string, params?: Record<string, string>) => string
): string {
    if (isPermanent || durationMs === null || durationMs === undefined) {
        return t('room.systemMessage.banDuration.permanent')
    }

    const minutes = Math.floor(durationMs / (1000 * 60))
    const hours = Math.floor(minutes / 60)
    const days = Math.floor(hours / 24)

    if (days > 0) {
        return t('room.systemMessage.banDuration.days', { count: String(days) })
    } else if (hours > 0) {
        return t('room.systemMessage.banDuration.hours', { count: String(hours) })
    } else if (minutes > 0) {
        return t('room.systemMessage.banDuration.minutes', { count: String(minutes) })
    } else {
        const seconds = Math.floor(durationMs / 1000)
        return t('room.systemMessage.banDuration.seconds', { count: String(seconds) })
    }
}

type OpenChatViewerCard = (
    mode: 'desktop' | 'mobile',
    event: React.MouseEvent<HTMLButtonElement>,
    user: ParticipantItem
) => void

function getRoleIconAndName(
    adminUserType?: 'streamer' | 'manager' | 'superAdmin',
    t?: (key: string) => string
): { roleIcon: React.ReactNode; roleName: string } {
    const isStreamer = adminUserType === 'streamer'
    const isMod = adminUserType === 'manager'
    const isSuperAdmin = adminUserType === 'superAdmin'
    const roleIcon = isStreamer ? (
        <span className="inline-flex items-center justify-center w-4 h-4 rounded-sm bg-orange-500 border border-orange-600 dark:border-orange-400 flex-shrink-0 mx-1">
            <FaCrown className="w-2.5 h-2.5 text-white" />
        </span>
    ) : isMod ? (
        <span className="inline-flex items-center justify-center w-4 h-4 rounded-sm bg-blue-500 border border-blue-600 dark:border-blue-400 flex-shrink-0 mx-1">
            <FaWrench className="w-2.5 h-2.5 text-white" />
        </span>
    ) : isSuperAdmin ? (
        <span className="inline-flex items-center justify-center w-4 h-4 rounded-sm bg-purple-500 border border-purple-600 dark:border-purple-400 flex-shrink-0 mx-1">
            <FaS className="w-2.5 h-2.5 text-white" />
        </span>
    ) : null
    const roleName = t && isStreamer ? t('room.systemMessage.roleStreamer') : t && isMod ? t('room.systemMessage.roleMod') : t && isSuperAdmin ? t('room.systemMessage.roleSuperAdmin') : ''
    return { roleIcon, roleName }
}

function getBanTargetRoleIcon(
    targetType: 'streamer' | 'manager' | 'superAdmin' | 'viewer' | undefined,
    t: (key: string) => string
): React.ReactNode {
    if (targetType === 'streamer' || targetType === 'manager' || targetType === 'superAdmin') {
        return getRoleIconAndName(targetType, t).roleIcon
    }
    return null
}

/** 與 UserRoleUtils.getUserNameColor 一致，供系統訊息內可點名稱使用 */
type SystemMessageNameRole = 'streamer' | 'manager' | 'superAdmin' | 'viewer'

function adminTypeToNameRole(
    adminUserType: 'streamer' | 'manager' | 'superAdmin' | undefined
): SystemMessageNameRole {
    if (adminUserType === 'streamer' || adminUserType === 'manager' || adminUserType === 'superAdmin') {
        return adminUserType
    }
    return 'viewer'
}

function systemMessageNameButtonClass(role: SystemMessageNameRole, obsEmbed?: boolean): string {
    if (obsEmbed) {
        return `obs-chat-name obs-chat-name--${role === 'superAdmin' ? 'superadmin' : role}`
    }
    const base = ' cursor-pointer font-medium '
    switch (role) {
        case 'streamer':
            return base + 'text-orange-600 dark:text-orange-400 hover:text-orange-700 dark:hover:text-orange-300'
        case 'manager':
            return base + 'text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300'
        case 'superAdmin':
            return base + 'text-purple-600 dark:text-purple-400 hover:text-purple-700 dark:hover:text-purple-300'
        default:
            return base + 'text-gray-800 dark:text-gray-200 hover:text-gray-900 dark:hover:text-gray-100'
    }
}

const OBS_INLINE_TEXT_CLASS = 'obs-chat-inline-text'
const OBS_LINK_CLASS = 'obs-chat-link'
const OBS_MENTION_CLASS = 'obs-chat-mention'

/** renderMessageText 執行期間是否為 OBS 疊層（供子函式套用可覆寫的 class） */
let renderMessageTextObsEmbed = false

/** 僅管理端可見：操作者 已禁言／已解除禁言 被操作者（含時長） */
function renderBanChangeModeratorVisible(
    isAdd: boolean,
    adminName: string,
    adminId: string,
    adminUserType: 'streamer' | 'manager' | 'superAdmin' | undefined,
    targetName: string,
    targetId: string,
    targetUserType: 'streamer' | 'manager' | 'superAdmin' | 'viewer' | undefined,
    durationText: string,
    openChatViewerCard: OpenChatViewerCard,
    mode: 'desktop' | 'mobile',
    t: (key: string, params?: Record<string, string>) => string
) {
    const { roleIcon: adminIcon } = getRoleIconAndName(adminUserType, t)
    const targetIcon = getBanTargetRoleIcon(targetUserType, t)
    if (isAdd) {
        const beforeDur = t('room.systemMessage.banModeratorBeforeDuration')
        const afterDur = t('room.systemMessage.banModeratorAfterDuration')
        return (
            <span className="inline-flex flex-wrap items-center gap-x-0.5 gap-y-1" style={{ wordBreak: 'break-all' }}>
                {adminIcon}
                {createUserButton(adminName, adminId, openChatViewerCard, mode, 'ban-mod-admin', adminTypeToNameRole(adminUserType))}
                <span>{t('room.systemMessage.banModeratorAddMid')}</span>
                {targetIcon}
                {createUserButton(
                    targetName,
                    targetId,
                    openChatViewerCard,
                    mode,
                    'ban-mod-target',
                    targetUserType === 'streamer' || targetUserType === 'manager' || targetUserType === 'superAdmin'
                        ? targetUserType
                        : 'viewer'
                )}
                {beforeDur ? <span>{beforeDur}</span> : null}
                <span>{durationText}</span>
                {afterDur ? <span>{afterDur}</span> : null}
            </span>
        )
    }
    const rmMid = t('room.systemMessage.banModeratorRemoveMid')
    const rmEnd = t('room.systemMessage.banModeratorRemoveEnd')
    return (
        <span className="inline-flex flex-wrap items-center gap-x-0.5 gap-y-1" style={{ wordBreak: 'break-all' }}>
            {adminIcon}
            {createUserButton(adminName, adminId, openChatViewerCard, mode, 'ban-mod-admin', adminTypeToNameRole(adminUserType))}
            <span>{rmMid}</span>
            {targetIcon}
            {createUserButton(
                targetName,
                targetId,
                openChatViewerCard,
                mode,
                'ban-mod-target',
                targetUserType === 'streamer' || targetUserType === 'manager' || targetUserType === 'superAdmin'
                    ? targetUserType
                    : 'viewer'
            )}
            {rmEnd ? <span>{rmEnd}</span> : null}
        </span>
    )
}

/** 被禁言／被解除禁言本人 */
function renderBanChangeForTargetUser(
    isAdd: boolean,
    adminName: string,
    adminId: string,
    adminUserType: 'streamer' | 'manager' | 'superAdmin' | undefined,
    durationText: string,
    openChatViewerCard: OpenChatViewerCard,
    mode: 'desktop' | 'mobile',
    t: (key: string, params?: Record<string, string>) => string
) {
    const { roleIcon: adminIcon } = getRoleIconAndName(adminUserType, t)
    if (isAdd) {
        const afterDur = t('room.systemMessage.banTargetBanAfterDuration')
        return (
            <span className="inline-flex flex-wrap items-center gap-x-0.5 gap-y-1" style={{ wordBreak: 'break-all' }}>
                <span>{t('room.systemMessage.banTargetYouBanPrefix')}</span>
                {adminIcon}
                {createUserButton(adminName, adminId, openChatViewerCard, mode, 'ban-you-admin', adminTypeToNameRole(adminUserType))}
                <span>{t('room.systemMessage.banTargetBanVerb')}</span>
                <span>{durationText}</span>
                {afterDur ? <span>{afterDur}</span> : null}
            </span>
        )
    }
    return (
        <span className="inline-flex flex-wrap items-center gap-x-0.5 gap-y-1" style={{ wordBreak: 'break-all' }}>
            <span>{t('room.systemMessage.banTargetYouUnbanPrefix')}</span>
            {adminIcon}
            {createUserButton(adminName, adminId, openChatViewerCard, mode, 'ban-you-admin', adminTypeToNameRole(adminUserType))}
            <span>{t('room.systemMessage.banTargetUnbanSuffix')}</span>
        </span>
    )
}

function createUserButton(
    userName: string,
    userId: string,
    openChatViewerCard: OpenChatViewerCard,
    mode: 'desktop' | 'mobile',
    key: string,
    nameRole: SystemMessageNameRole = 'viewer'
): React.ReactNode {
    const nameClass = systemMessageNameButtonClass(nameRole, renderMessageTextObsEmbed)
    if (renderMessageTextObsEmbed) {
        return (
            <span key={key} className={nameClass}>
                {userName}
            </span>
        )
    }
    const user: ParticipantItem = {
        role: 'viewer',
        name: userName,
        id: userId,
        avatarUrl: undefined,
    }
    return (
        <button
            key={key}
            type="button"
            onClick={(e) => openChatViewerCard(mode, e, user)}
            className={nameClass}
        >
            {userName}
        </button>
    )
}

function renderModeratorSystemMessage(
    messageText: string,
    userName: string,
    userId: string,
    adminName: string,
    adminId: string,
    adminUserType: 'streamer' | 'manager' | 'superAdmin' | undefined,
    roleIcon: React.ReactNode,
    roleName: string,
    openChatViewerCard: OpenChatViewerCard,
    mode: 'desktop' | 'mobile'
): React.ReactNode {
    const parts: React.ReactNode[] = []
    const userNamePlaceholder = `[${userName}]`
    const adminNamePlaceholder = `[${adminName}]`
    const userNameIndex = messageText.indexOf(userNamePlaceholder)
    const adminNameIndex = messageText.indexOf(adminNamePlaceholder)

    if (userNameIndex !== -1) {
        const beforeUserText = messageText.substring(0, userNameIndex)
        parts.push(...renderTextWithUrls(beforeUserText, ''))
        parts.push(createUserButton(userName, userId, openChatViewerCard, mode, 'user', 'viewer'))
        const afterUser = messageText.substring(userNameIndex + userNamePlaceholder.length)
        const beforeAdmin = afterUser.substring(0, afterUser.indexOf(adminNamePlaceholder))
        const beforeAdminWithoutRoleName = beforeAdmin.replace(roleName, '').trim()
        const beforeAdminUrls = renderTextWithUrls(beforeAdminWithoutRoleName, '')
        parts.push(
            <span key="before-admin" style={{ wordBreak: 'break-all' }}>
                {beforeAdminUrls}
                {roleIcon}
            </span>
        )
        parts.push(createUserButton(adminName, adminId, openChatViewerCard, mode, 'admin', adminTypeToNameRole(adminUserType)))
        const afterAdminText = messageText.substring(adminNameIndex + adminNamePlaceholder.length)
        parts.push(...renderTextWithUrls(afterAdminText, ''))
    } else {
        parts.push(...renderTextWithUrls(messageText, ''))
    }
    return <span className="inline-flex items-center flex-wrap gap-1" style={{ wordBreak: 'break-all' }}>{parts}</span>
}

function renderUserSystemMessage(
    messageText: string,
    adminName: string,
    adminId: string,
    adminUserType: 'streamer' | 'manager' | 'superAdmin' | undefined,
    roleIcon: React.ReactNode,
    roleName: string,
    openChatViewerCard: OpenChatViewerCard,
    mode: 'desktop' | 'mobile'
): React.ReactNode {
    const parts: React.ReactNode[] = []
    const adminNamePlaceholder = `[${adminName}]`
    const adminNameIndex = messageText.indexOf(adminNamePlaceholder)

    if (adminNameIndex !== -1) {
        const beforeAdmin = messageText.substring(0, adminNameIndex)
        const beforeAdminWithoutRoleName = beforeAdmin.replace(roleName, '').trim()
        const beforeAdminUrls = renderTextWithUrls(beforeAdminWithoutRoleName, '')
        parts.push(
            <span key="before-admin" style={{ wordBreak: 'break-all' }}>
                {beforeAdminUrls}
                {roleIcon}
            </span>
        )
        parts.push(createUserButton(adminName, adminId, openChatViewerCard, mode, 'admin', adminTypeToNameRole(adminUserType)))
        const afterAdminText = messageText.substring(adminNameIndex + adminNamePlaceholder.length)
        parts.push(...renderTextWithUrls(afterAdminText, ''))
    } else {
        parts.push(...renderTextWithUrls(messageText, ''))
    }
    return <span className="inline-flex items-center flex-wrap gap-1" style={{ wordBreak: 'break-all' }}>{parts}</span>
}

/** 僅管理端可見：「[身分圖示][操作者] 已指定／已移除 [Mod 圖示][對象] …」 */
function renderModChangeModeratorVisible(
    isAdd: boolean,
    adminName: string,
    adminId: string,
    adminUserType: 'streamer' | 'manager' | 'superAdmin' | undefined,
    targetName: string,
    targetId: string,
    openChatViewerCard: OpenChatViewerCard,
    mode: 'desktop' | 'mobile',
    t: (key: string, params?: Record<string, string>) => string
) {
    const { roleIcon: adminIcon } = getRoleIconAndName(adminUserType, t)
    const { roleIcon: modRoleIcon } = getRoleIconAndName('manager', t)
    const mid = isAdd ? t('room.systemMessage.modModeratorMidAdd') : t('room.systemMessage.modModeratorMidRemove')
    const end = isAdd ? t('room.systemMessage.modModeratorEndAdd') : t('room.systemMessage.modModeratorEndRemove')
    return (
        <span className="inline-flex flex-wrap items-center gap-x-0.5 gap-y-1" style={{ wordBreak: 'break-all' }}>
            {adminIcon}
            {createUserButton(adminName, adminId, openChatViewerCard, mode, 'mod-admin', adminTypeToNameRole(adminUserType))}
            <span>{mid}</span>
            {modRoleIcon}
            {createUserButton(targetName, targetId, openChatViewerCard, mode, 'mod-target', 'manager')}
            <span>{end}</span>
        </span>
    )
}

/** 被操作本人：「[身分圖示][操作者] 已指定您為 Mod」等 */
function renderModChangeForTargetUser(
    isAdd: boolean,
    adminName: string,
    adminId: string,
    adminUserType: 'streamer' | 'manager' | 'superAdmin' | undefined,
    openChatViewerCard: OpenChatViewerCard,
    mode: 'desktop' | 'mobile',
    t: (key: string, params?: Record<string, string>) => string
) {
    const { roleIcon: adminIcon } = getRoleIconAndName(adminUserType, t)
    const suffix = isAdd ? t('room.systemMessage.modTargetYouAdd') : t('room.systemMessage.modTargetYouRemove')
    return (
        <span className="inline-flex flex-wrap items-center gap-x-0.5 gap-y-1" style={{ wordBreak: 'break-all' }}>
            {adminIcon}
            {createUserButton(adminName, adminId, openChatViewerCard, mode, 'mod-admin-target', adminTypeToNameRole(adminUserType))}
            <span>{suffix}</span>
        </span>
    )
}

function renderSystemMessage(
    message: ChatMessage,
    openChatViewerCard: OpenChatViewerCard | undefined,
    mode: 'desktop' | 'mobile',
    t: (key: string, params?: Record<string, string>) => string,
    currentUserId?: string | null
): React.ReactNode | null {
    const systemData = message.systemMessageData
    if (!systemData) return null
    const { roleIcon, roleName } = getRoleIconAndName(message.adminUserType, t)
    // Mod 相關消息（isModeratorOnly：主播／Mod／超管；否則為被操作者本人）
    if (message.systemMessageType === 'modAdded' || message.systemMessageType === 'modRemoved') {
        const isAdd = message.systemMessageType === 'modAdded'
        const adminName = systemData.adminName
        const adminId = message.adminUserId
        const adminType = message.adminUserType
        const targetName = systemData.userName
        const targetId = isAdd ? message.moddedUserId : message.unmoddedUserId

        if (message.isModeratorOnly) {
            if (!adminName || !targetName || !targetId) return null
            if (!adminId) {
                return t(
                    isAdd ? 'room.systemMessage.modModeratorPlainAdd' : 'room.systemMessage.modModeratorPlainRemove',
                    { adminName: adminName ?? '', targetName }
                )
            }
            if (openChatViewerCard) {
                return renderModChangeModeratorVisible(
                    isAdd,
                    adminName,
                    adminId,
                    adminType,
                    targetName,
                    targetId,
                    openChatViewerCard,
                    mode,
                    t
                )
            }
            return t(
                isAdd ? 'room.systemMessage.modModeratorPlainAdd' : 'room.systemMessage.modModeratorPlainRemove',
                { adminName, targetName }
            )
        }

        if (adminName && adminId) {
            if (openChatViewerCard) {
                return renderModChangeForTargetUser(isAdd, adminName, adminId, adminType, openChatViewerCard, mode, t)
            }
            return t(isAdd ? 'room.systemMessage.modTargetPlainAdd' : 'room.systemMessage.modTargetPlainRemove', {
                adminName,
            })
        }
        return null
    }

    // Ban 相關消息（管理端：雙身分圖示＋可點名；本人：您被…）
    if (message.systemMessageType === 'banAdded' || message.systemMessageType === 'banRemoved') {
        const isAdd = message.systemMessageType === 'banAdded'
        const isModeratorOnly = message.isModeratorOnly
        const targetId = isAdd ? message.bannedUserId : message.unbannedUserId
        const targetName = systemData.userName
        const targetUserType = systemData.targetUserType
        const adminName = systemData.adminName
        const adminId = message.adminUserId
        const adminType = message.adminUserType

        let durationText = ''
        if (isAdd) {
            const durationMs = systemData.durationMs
            const isPermanent = systemData.isPermanent
            durationText = formatBanDuration(durationMs, isPermanent, t)
        }

        const viewerIsBanTarget = Boolean(currentUserId && targetId && currentUserId === targetId)

        if (isModeratorOnly && !viewerIsBanTarget) {
            if (!adminName || !adminId || !targetName || !targetId) return null
            if (openChatViewerCard) {
                return renderBanChangeModeratorVisible(
                    isAdd,
                    adminName,
                    adminId,
                    adminType,
                    targetName,
                    targetId,
                    targetUserType,
                    durationText,
                    openChatViewerCard,
                    mode,
                    t
                )
            }
            return isAdd
                ? t('room.systemMessage.banModeratorPlainAdd', {
                      adminName,
                      targetName,
                      duration: durationText,
                  })
                : t('room.systemMessage.banModeratorPlainRemove', { adminName, targetName })
        }

        if (adminName && adminId) {
            if (openChatViewerCard) {
                return renderBanChangeForTargetUser(
                    isAdd,
                    adminName,
                    adminId,
                    adminType,
                    durationText,
                    openChatViewerCard,
                    mode,
                    t
                )
            }
            return isAdd
                ? t('room.systemMessage.banTargetPlainAdd', { adminName, duration: durationText })
                : t('room.systemMessage.banTargetPlainRemove', { adminName })
        }
        return null
    }
    if (message.systemMessageType === 'chatDisabled' || message.systemMessageType === 'chatEnabled') {
        const translationKey = message.systemMessageType === 'chatDisabled'
            ? 'room.systemMessage.chatDisabled'
            : 'room.systemMessage.chatEnabled'

        if (systemData.adminName && message.adminUserId) {
            if (openChatViewerCard) {
                const messageText = t(translationKey, {
                    roleName: roleName,
                    adminName: systemData.adminName,
                })
                return renderUserSystemMessage(
                    messageText,
                    systemData.adminName,
                    message.adminUserId,
                    message.adminUserType,
                    roleIcon,
                    roleName,
                    openChatViewerCard,
                    mode
                )
            } else {
                const messageText = t(translationKey, {
                    roleName: roleName,
                    adminName: systemData.adminName || '',
                })
                return messageText
            }
        }
    }
    return null
}


function renderTextWithUrls(text: string, className: string, obsEmbed = renderMessageTextObsEmbed): React.ReactNode[] {
    const textClass = obsEmbed ? OBS_INLINE_TEXT_CLASS : className
    const linkClass = obsEmbed
        ? OBS_LINK_CLASS
        : 'text-blue-600 dark:text-blue-400  break-all'
    const URL_REGEX = /(https?:\/\/[^\s]+|www\.[^\s]+)/gi
    const parts: React.ReactNode[] = []
    let lastIndex = 0
    let match: RegExpExecArray | null
    URL_REGEX.lastIndex = 0
    while ((match = URL_REGEX.exec(text)) !== null) {
        if (match.index > lastIndex) {
            parts.push(
                <span key={`text-${lastIndex}`} className={textClass} style={{ wordBreak: 'break-all' }}>
                    {text.substring(lastIndex, match.index)}
                </span>
            )
        }
        let url = match[0]
        let href = url
        if (!url.startsWith('http://') && !url.startsWith('https://')) {
            href = `https://${url}`
        }
        parts.push(
            <a
                key={`url-${match.index}`}
                href={href}
                target="_blank"
                rel="nofollow noopener noreferrer"
                className={linkClass}
                onClick={(e) => e.stopPropagation()}
            >
                {url}
            </a>
        )
        lastIndex = match.index + match[0].length
    }
    if (lastIndex < text.length) {
        parts.push(
            <span key={`text-${lastIndex}`} className={textClass} style={{ wordBreak: 'break-all' }}>
                {text.substring(lastIndex)}
            </span>
        )
    }
    return parts.length > 0 ? parts : [<span key="text-0" className={textClass} style={{ wordBreak: 'break-all' }}>{text}</span>]
}

function resolveGiftRecipientUserType(
    recipientUserId: string,
    streamerId?: string
): ChatMessage['userType'] | undefined {
    if (streamerId && recipientUserId === streamerId) return 'streamer'
    return undefined
}

function renderGiftMessage(
    message: ChatMessage,
    t: (key: string, params?: Record<string, string>) => string,
    streamerId?: string,
    openMentionViewerCard?: OpenChatViewerCard,
    mode: 'desktop' | 'mobile' = 'desktop'
) {
    const gift = message.gift
    if (!gift) return null

    const recipientName =
        gift.recipientName?.trim() || gift.recipientDisplayId?.trim() || gift.recipientUserId
    const recipientItem: ParticipantItem = {
        role: '',
        id: gift.recipientUserId,
        name: recipientName,
        userType: resolveGiftRecipientUserType(gift.recipientUserId, streamerId),
        profileApiKey: gift.recipientDisplayId,
    }
    const recipientBadge = getUserRoleBadge(recipientItem, streamerId)

    return (
        <span className="inline-flex items-center flex-wrap gap-x-1 gap-y-0.5 shrink-0 text-gray-900 dark:text-gray-100">
            <span>{t('room.giftMessage.to')}</span>
            <span className="inline-flex items-center whitespace-nowrap shrink-0">
                {recipientBadge}
                {openMentionViewerCard ? (
                    <button
                        type="button"
                        onClick={(e) => openMentionViewerCard(mode, e, recipientItem)}
                        className={`font-semibold cursor-pointer ${getUserNameColor(recipientItem, streamerId)}`}
                    >
                        {recipientName}
                    </button>
                ) : (
                    <span className={`font-semibold ${getUserNameColor(recipientItem, streamerId)}`}>
                        {recipientName}
                    </span>
                )}
            </span>
            <span>{t('room.giftMessage.sent')}</span>
            {gift.image ? (
                <Image
                    src={gift.image}
                    alt=""
                    width={24}
                    height={24}
                    className="inline-block h-6 w-auto object-contain"
                    unoptimized
                />
            ) : null}
        </span>
    )
}

export function renderMessageText(
    message: ChatMessage,
    openChatViewerCard?: OpenChatViewerCard,
    mode: 'desktop' | 'mobile' = 'desktop',
    t?: (key: string, params?: Record<string, string>) => string,
    emojiItems?: Array<{ id: string; alt: string; code: string; src: string }>,
    currentUserId?: string | null,
    obsEmbed = false,
    streamerId?: string
) {
    const prevObsEmbed = renderMessageTextObsEmbed
    renderMessageTextObsEmbed = obsEmbed
    try {
    if (message.gift && t) {
        const giftLine = renderGiftMessage(message, t, streamerId, openChatViewerCard, mode)
        if (giftLine) return giftLine
    }

    if (message.isSystem && message.systemMessageType && t) {
        if (message.systemMessageType === 'userEntered') {
            const name =
                message.author?.trim() ||
                (typeof message.systemMessageData?.userName === 'string'
                    ? message.systemMessageData.userName.trim()
                    : '') ||
                t('common.guest')
            return (
                <span
                    className={obsEmbed ? OBS_INLINE_TEXT_CLASS : 'text-gray-600 dark:text-gray-400'}
                    style={{ wordBreak: 'break-all' }}
                >
                    {t('room.systemMessage.userEntered', { name })}
                </span>
            )
        }
        if (message.moddedUserId || message.unmoddedUserId || message.bannedUserId || message.unbannedUserId ||
            message.systemMessageType === 'chatDisabled' || message.systemMessageType === 'chatEnabled') {
            const result = renderSystemMessage(message, openChatViewerCard, mode, t, currentUserId)
            if (result != null) return result
        }
    }
    if (message.isSystem && message.text && t && !message.systemMessageType) {
        const isEnterNotice =
            message.text.includes('已進入直播間') ||
            message.text.includes('已进入直播间') ||
            message.text.includes('entered the stream') ||
            message.text.includes('配信ルームに入りました') ||
            message.text.includes('방송에 입장')
        if (isEnterNotice) {
            const rawName = (message.author || message.text.split(/\s+/)[0] || '').trim()
            const name = rawName === 'common.guest' ? t('common.guest') : rawName || t('common.guest')
            return (
                <span
                    className={obsEmbed ? OBS_INLINE_TEXT_CLASS : 'text-gray-600 dark:text-gray-400'}
                    style={{ wordBreak: 'break-all' }}
                >
                    {t('room.systemMessage.userEntered', { name })}
                </span>
            )
        }
    }
    const allItems: Array<{ type: 'mention' | 'emoji'; startIndex: number; endIndex: number; data: any }> = []
    if (message.mentions && message.mentions.length > 0) {
        message.mentions.forEach((mention) => {
            allItems.push({ type: 'mention', startIndex: mention.startIndex, endIndex: mention.endIndex, data: mention })
        })
    }
    if (message.emojis && message.emojis.length > 0) {
        message.emojis.forEach((emoji) => {
            allItems.push({ type: 'emoji', startIndex: emoji.startIndex, endIndex: emoji.endIndex, data: emoji })
        })
    }
    if ((!message.emojis || message.emojis.length === 0) && message.text && emojiItems && emojiItems.length > 0) {
        const emojiCodePattern = /\/([^/]+)\//g
        const matches = [...message.text.matchAll(emojiCodePattern)]
        if (matches.length > 0) {
            for (let i = matches.length - 1; i >= 0; i--) {
                const match = matches[i]
                const emojiCode = match[0]
                const emojiItem = emojiItems.find((item) => item.code === emojiCode)
                if (emojiItem && match.index !== undefined) {
                    allItems.push({
                        type: 'emoji',
                        startIndex: match.index,
                        endIndex: match.index + emojiCode.length,
                        data: { code: emojiCode, src: emojiItem.src, startIndex: match.index, endIndex: match.index + emojiCode.length },
                    })
                }
            }
        }
    }
    if (allItems.length === 0) {
        const plainClass = obsEmbed ? OBS_INLINE_TEXT_CLASS : 'text-gray-500 dark:text-gray-400'
        return <span style={{ wordBreak: 'break-all' }}>{renderTextWithUrls(message.text, plainClass)}</span>
    }
    const parts: React.ReactNode[] = []
    let lastIndex = 0
    const sortedItems = allItems.sort((a, b) => a.startIndex - b.startIndex)

    sortedItems.forEach((item) => {
        if (item.startIndex > lastIndex) {
            const textSegment = message.text.substring(lastIndex, item.startIndex)
            const segmentClass = obsEmbed ? OBS_INLINE_TEXT_CLASS : 'text-gray-500 dark:text-gray-400'
            parts.push(...renderTextWithUrls(textSegment, segmentClass))
        }

        if (item.type === 'mention') {
            const mention = item.data as MentionInfo
            const isEveryone = mention.userId === '@everyone'
            if (isEveryone || !openChatViewerCard || obsEmbed) {
                parts.push(
                    <span
                        key={`mention-${mention.startIndex}`}
                        className={
                            obsEmbed
                                ? OBS_MENTION_CLASS
                                : `inline-flex items-center px-2 py-0.5 rounded-md text-sm font-medium mx-0.5 ${isEveryone
                                      ? 'bg-yellow-100 dark:bg-yellow-900/30 text-yellow-700 dark:text-yellow-300'
                                      : 'bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300'
                                  }`
                        }
                    >
                        @{mention.userName}
                    </span>
                )
            } else {
                const user: ParticipantItem = {
                    role: 'viewer',
                    name: mention.userName,
                    id: mention.userId,
                    avatarUrl: undefined,
                }
                parts.push(
                    <button
                        key={`mention-${mention.startIndex}`}
                        type="button"
                        onClick={(e) => openChatViewerCard(mode, e, user)}
                        className="inline-flex items-center px-2 py-0.5 rounded-md bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 text-sm font-medium mx-0.5 hover:bg-blue-200 dark:hover:bg-blue-900/50 cursor-pointer transition-colors"
                    >
                        @{mention.userName}
                    </button>
                )
            }
        } else if (item.type === 'emoji') {
            const emoji = item.data as EmojiInfo
            const resolvedSrc =
                emojiItems?.find((i) => i.code === emoji.code)?.src ??
                findChatEmojiByCode(emoji.code)?.src ??
                emoji.src
            parts.push(
                <Image
                    key={`emoji-${emoji.startIndex}`}
                    src={resolvedSrc}
                    alt={emoji.code}
                    width={CHAT_EMOJI_MESSAGE_PX}
                    height={CHAT_EMOJI_MESSAGE_PX}
                    className="inline-block align-middle pointer-events-none object-contain"
                    style={{
                        width: CHAT_EMOJI_MESSAGE_PX,
                        height: CHAT_EMOJI_MESSAGE_PX,
                        verticalAlign: 'middle',
                        display: 'inline-block',
                    }}
                    unoptimized
                />
            )
        }

        lastIndex = item.endIndex
    })

    if (lastIndex < message.text.length) {
        const textSegment = message.text.substring(lastIndex)
        const tailClass = obsEmbed ? OBS_INLINE_TEXT_CLASS : 'text-gray-500 dark:text-gray-400'
        parts.push(...renderTextWithUrls(textSegment, tailClass))
    }
    return <>{parts}</>
    } finally {
        renderMessageTextObsEmbed = prevObsEmbed
    }
}


