'use client'

import { useState, useRef, useEffect } from 'react'
import { FiMoreVertical } from 'react-icons/fi'
import type { ChatMessage, ParticipantItem } from '../types'
import { filterVisibleChatMessages } from '@/lib/chat/filterVisibleChatMessages'
import { getObsMessageRoleModifier, getUserRoleBadge, getUserNameColor } from './UserRoleUtils'
import { renderMessageText } from './RenderMessageText'
import GiftChatMessage from './GiftChatMessage'

interface MessageListProps {
    messages: ChatMessage[]
    mode: 'desktop' | 'mobile'
    streamerId: string
    currentUserId?: string | null
    mentionMessageRefs: React.MutableRefObject<Map<string, HTMLDivElement>>
    isMessageMentioningMe: (message: ChatMessage) => boolean
    openChatViewerCard: (mode: 'desktop' | 'mobile', e: React.MouseEvent<HTMLButtonElement>, message: ChatMessage) => void
    openMentionViewerCard: (mode: 'desktop' | 'mobile', e: React.MouseEvent<HTMLButtonElement>, user: ParticipantItem) => void
    onPinMessage?: (messageId: string) => void
    onUnpinMessage?: () => void
    onDeleteMessage?: (messageId: string) => void
    isModerator?: boolean
    highlightMentions?: boolean
    hideSystemMessages?: boolean
    showGiftMessages?: boolean
    emojiItems?: Array<{ id: string; alt: string; code: string; src: string }>
    /** OBS 疊層：加強文字對比、隱藏互動選單 */
    obsOverlay?: boolean
    /** OBS 疊層主題（URL ?theme=light|dark） */
    obsEmbedTheme?: 'dark' | 'light'
    getUserAvatar?: (userId: string | null | undefined) => string | null | undefined
    modUserIds?: ReadonlySet<string>
    superAdminUserIds?: ReadonlySet<string>
    t: (key: string, params?: Record<string, string>) => string
}

export default function MessageList({
    messages,
    mode,
    streamerId,
    currentUserId,
    mentionMessageRefs,
    isMessageMentioningMe,
    openChatViewerCard,
    openMentionViewerCard,
    onPinMessage,
    onUnpinMessage,
    onDeleteMessage,
    isModerator = false,
    highlightMentions = true,
    hideSystemMessages = false,
    showGiftMessages = true,
    emojiItems,
    obsOverlay = false,
    getUserAvatar,
    modUserIds,
    superAdminUserIds,
    t,
}: MessageListProps) {
    const obsTextClass = obsOverlay
        ? 'obs-chat-message__body'
        : 'text-gray-900 dark:text-gray-100'

    const getMessageBodyWrapperClass = (message: ChatMessage) => {
        if (message.gift) {
            return obsOverlay ? 'relative [text-shadow:none]' : 'relative isolate'
        }
        return `relative ${obsTextClass}`
    }

    const obsSystemClass = obsOverlay ? 'obs-chat-system' : 'text-gray-600 dark:text-gray-400'
    const filteredMessages = filterVisibleChatMessages(messages, {
        hideSystemMessages,
        showGiftMessages,
        currentUserId,
        isModerator,
    })
    const displayedMessages = filteredMessages.slice(-70)
    const [hoveredMessageId, setHoveredMessageId] = useState<string | null>(null)
    const [menuOpenMessageId, setMenuOpenMessageId] = useState<string | null>(null)
    const [viewingDeletedMessages, setViewingDeletedMessages] = useState<Set<string>>(new Set())
    const menuRefs = useRef<Map<string, HTMLDivElement>>(new Map())

    useEffect(() => {
        const handleClickOutside = (event: MouseEvent) => {
            const target = event.target as HTMLElement
            if (!target) return
            let clickedInsideMenu = false
            let clickedInsideButton = false
            menuRefs.current.forEach((menuEl) => {
                if (menuEl && menuEl.contains(target)) {
                    clickedInsideMenu = true
                }
            })
            if (target.closest('[data-menu-trigger]')) {
                clickedInsideButton = true
            }
            if (target.closest('[data-menu-container]')) {
                clickedInsideButton = true
            }
            if (!clickedInsideMenu && !clickedInsideButton) {
                setMenuOpenMessageId(null)
                setHoveredMessageId((prev) => {
                    if (prev && menuOpenMessageId === prev) {
                        return null
                    }
                    return prev
                })
            }
        }
        document.addEventListener('mousedown', handleClickOutside)
        return () => {
            document.removeEventListener('mousedown', handleClickOutside)
        }
    }, [menuOpenMessageId])

    const handlePinClick = (messageId: string) => {
        if (onPinMessage) {
            onPinMessage(messageId)
        }
        setMenuOpenMessageId(null)
    }

    const handleUnpinClick = () => {
        if (onUnpinMessage) {
            onUnpinMessage()
        }
        setMenuOpenMessageId(null)
    }

    const handleDeleteClick = (messageId: string) => {
        if (onDeleteMessage) {
            onDeleteMessage(messageId)
        }
        setMenuOpenMessageId(null)
    }

    const renderAuthorLabel = (m: ChatMessage) => {
        const label = m.isSystem ? (m.author || t('room.systemMessage.author')) : m.author
        if (obsOverlay) {
            return <span className="obs-chat-message__author">{label}</span>
        }
        return (
            <button
                type="button"
                onClick={(e) => openChatViewerCard(mode, e, m)}
                className={`font-semibold  cursor-pointer ${getUserNameColor(m, streamerId, modUserIds, superAdminUserIds)}`}
            >
                {label}
            </button>
        )
    }

    const renderAuthorWithBadge = (m: ChatMessage) => {
        const roleBadge = getUserRoleBadge(m, streamerId, modUserIds, superAdminUserIds)
        return (
            <span
                className={`inline-flex items-center whitespace-nowrap shrink-0 mr-1.5${obsOverlay ? ' obs-chat-role-badge-inline' : ''}`}
            >
                {roleBadge}
                {renderAuthorLabel(m)}
            </span>
        )
    }

    const renderMessageBody = (m: ChatMessage, messageTextClassName?: string) => (
        <span
            className={`inline-flex flex-wrap items-center gap-x-1.5 gap-y-0.5 leading-[1.4] ${messageTextClassName ?? ''}`}
            style={{ wordBreak: 'break-all' }}
        >
            {renderAuthorWithBadge(m)}
            {renderMessageText(m, openMentionViewerCard, mode, t, emojiItems, currentUserId, obsOverlay, streamerId)}
        </span>
    )

    return (
        <>
            {displayedMessages.map((m) =>
                m.isSystem ? (
                    <div
                        key={m.id}
                        className={obsSystemClass}
                        style={{ wordBreak: 'break-all' }}
                    >
                        {renderMessageText(m, openMentionViewerCard, mode, t, emojiItems, currentUserId, obsOverlay, streamerId)}
                    </div>
                ) : m.isDeleted && (m.deletedBy?.userId === m.userId || !isModerator) ? null : (
                    <div
                        key={m.id}
                        ref={(el) => {
                            if (el && isMessageMentioningMe(m) && m.userId !== currentUserId) {
                                mentionMessageRefs.current.set(m.id, el)
                            } else {
                                mentionMessageRefs.current.delete(m.id)
                            }
                        }}
                        data-message-id={m.id}
                        className={
                            obsOverlay
                                ? `obs-chat-message ${getObsMessageRoleModifier(m, streamerId, modUserIds, superAdminUserIds)}`
                                : 'relative py-1 transition-colors group'
                        }
                        onMouseEnter={() => {
                            if (menuOpenMessageId && menuOpenMessageId !== m.id) {
                                return
                            }
                            setHoveredMessageId(m.id)
                        }}
                        onMouseLeave={(e) => {
                            if (menuOpenMessageId === m.id) {
                                return
                            }
                            const relatedTarget = e.relatedTarget
                            if (relatedTarget && relatedTarget instanceof HTMLElement) {
                                if (relatedTarget.closest('[data-menu-container]') || relatedTarget.closest('[data-menu-trigger]')) {
                                    return
                                }
                            }
                            setHoveredMessageId(null)
                        }}
                    >
                        {!obsOverlay && highlightMentions && isMessageMentioningMe(m) && (
                            <div className="absolute inset-y-0 left-0 right-0 bg-yellow-100 dark:bg-yellow-900/20 -mx-4" />
                        )}
                        <div className={getMessageBodyWrapperClass(m)}>
                            {m.isDeleted && isModerator && m.deletedBy?.userId !== m.userId ? (
                                <div>
                                    <div className="flex items-center gap-2 text-gray-500 dark:text-gray-400 italic mb-1">
                                        <span>{t('room.message.deleted')}</span>
                                        {m.deletedBy && m.deletedBy.userId === currentUserId && (
                                            <button
                                                type="button"
                                                onClick={() => {
                                                    setViewingDeletedMessages((prev) => {
                                                        const next = new Set(prev)
                                                        if (next.has(m.id)) {
                                                            next.delete(m.id)
                                                        } else {
                                                            next.add(m.id)
                                                        }
                                                        return next
                                                    })
                                                }}
                                                className="text-sm text-blue-600 dark:text-blue-400 hover:underline"
                                            >
                                                {viewingDeletedMessages.has(m.id) ? t('room.message.hideOriginal') : t('room.message.viewOriginal')}
                                            </button>
                                        )}
                                    </div>
                                    {viewingDeletedMessages.has(m.id) && (
                                        <div className={`min-w-0 opacity-50 ${m.gift ? '' : 'line-through'}`}>
                                            {m.gift ? (
                                                <GiftChatMessage
                                                    message={m}
                                                    streamerId={streamerId}
                                                    getUserAvatar={getUserAvatar}
                                                    openChatViewerCard={openChatViewerCard}
                                                    openMentionViewerCard={openMentionViewerCard}
                                                    mode={mode}
                                                    modUserIds={modUserIds}
                                                    superAdminUserIds={superAdminUserIds}
                                                    t={t}
                                                />
                                            ) : (
                                                renderMessageBody(m)
                                            )}
                                        </div>
                                    )}
                                </div>
                            ) : m.gift ? (
                                <GiftChatMessage
                                    message={m}
                                    streamerId={streamerId}
                                    getUserAvatar={getUserAvatar}
                                    openChatViewerCard={openChatViewerCard}
                                    openMentionViewerCard={openMentionViewerCard}
                                    mode={mode}
                                    modUserIds={modUserIds}
                                    superAdminUserIds={superAdminUserIds}
                                    t={t}
                                />
                            ) : (
                                <div className="min-w-0">{renderMessageBody(m)}</div>
                            )}
                        </div>
                        {!obsOverlay && !m.gift && !m.isDeleted && (hoveredMessageId === m.id || menuOpenMessageId === m.id) && (isModerator || m.userId === currentUserId) && (
                            <div
                                className="absolute right-0 top-1/2 -translate-y-1/2 z-10 hover:bg-gray-100 dark:hover:bg-[#1a1c21] rounded-xl p-0.5"
                                data-menu-container
                                onMouseEnter={() => {
                                    setHoveredMessageId(m.id)
                                }}
                                onMouseLeave={(e) => {
                                    if (menuOpenMessageId === m.id) {
                                        return
                                    }
                                    const relatedTarget = e.relatedTarget
                                    if (relatedTarget && relatedTarget instanceof HTMLElement && relatedTarget.closest(`[data-message-id="${m.id}"]`)) {
                                        return
                                    }
                                    setHoveredMessageId(null)
                                }}
                            >
                                <button
                                    type="button"
                                    data-menu-trigger
                                    onClick={(e) => {
                                        e.stopPropagation()
                                        const newMenuState = menuOpenMessageId === m.id ? null : m.id
                                        setMenuOpenMessageId(newMenuState)
                                        if (newMenuState === m.id) {
                                            setHoveredMessageId(m.id)
                                        }
                                    }}
                                    className="p-1 rounded transition-colors opacity-0 group-hover:opacity-100 relative z-10"
                                    style={{ opacity: menuOpenMessageId === m.id ? 1 : undefined }}
                                    aria-label={t('room.message.moreOptions')}
                                >
                                    <FiMoreVertical className="w-4 h-4 text-gray-500 dark:text-gray-400" />
                                </button>
                                {menuOpenMessageId === m.id && (
                                    <div
                                        ref={(el) => {
                                            if (el) {
                                                menuRefs.current.set(m.id, el)
                                            } else {
                                                menuRefs.current.delete(m.id)
                                            }
                                        }}
                                        className="absolute right-0 top-full mt-1 bg-white dark:bg-[#0c0d0e] border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg z-50 min-w-[120px] overflow-hidden"
                                        onMouseDown={(e) => {
                                            e.stopPropagation()
                                        }}
                                    >
                                        {isModerator && (
                                            <>
                                                {m.isPinned ? (
                                                    <button
                                                        type="button"
                                                        onClick={(e) => {
                                                            e.stopPropagation()
                                                            handleUnpinClick()
                                                        }}
                                                        onMouseDown={(e) => {
                                                            e.stopPropagation()
                                                        }}
                                                        className="block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-[#1a1c21] transition-colors cursor-pointer"
                                                    >
                                                        {t('room.message.unpin')}
                                                    </button>
                                                ) : (
                                                    <button
                                                        type="button"
                                                        onClick={(e) => {
                                                            e.stopPropagation()
                                                            handlePinClick(m.id)
                                                        }}
                                                        onMouseDown={(e) => {
                                                            e.stopPropagation()
                                                        }}
                                                        className="block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-[#1a1c21] transition-colors cursor-pointer"
                                                    >
                                                        {t('room.message.pin')}
                                                    </button>
                                                )}
                                                <div className="border-t border-gray-200 dark:border-gray-700"></div>
                                            </>
                                        )}
                                        <button
                                            type="button"
                                            onClick={(e) => {
                                                e.stopPropagation()
                                                handleDeleteClick(m.id)
                                            }}
                                            onMouseDown={(e) => {
                                                e.stopPropagation()
                                            }}
                                            className="block w-full text-left px-4 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-[#1a1c21] transition-colors cursor-pointer"
                                        >
                                            {t('room.message.delete')}
                                        </button>
                                    </div>
                                )}
                            </div>
                        )}
                    </div>
                )
            )}
        </>
    )
}

