'use client'

import { createPortal } from 'react-dom'
import { useEffect, useLayoutEffect, useState, useCallback } from 'react'
import Image from 'next/image'
import { FiChevronLeft, FiChevronRight, FiClock, FiSmile, FiStar, FiX } from 'react-icons/fi'
import {
    CHAT_EMOJI_PANEL_CELL_PX,
    CHAT_EMOJI_PANEL_PX,
} from '@/app/room/_components/chat/chatEmojis'

export type EmojiItem = { id: string; alt: string; code: string; src: string }

export default function EmojiPanel({
    panelRef,
    anchorRef,
    boundsRef,
    avoidRef,
    variant,
    t,
    emojiTab,
    setEmojiTab,
    items,
    emojiClosing,
    emojiEntering,
    onClose,
    onEmojiClick,
}: {
    panelRef: React.RefObject<HTMLDivElement>
    anchorRef: React.RefObject<HTMLElement>
    boundsRef?: React.RefObject<HTMLElement>
    avoidRef?: React.RefObject<HTMLElement>
    variant: 'desktop' | 'mobile'
    t: (key: string) => string
    emojiTab: 'recent' | 'subscription' | 'default'
    setEmojiTab: (v: 'recent' | 'subscription' | 'default') => void
    items: EmojiItem[]
    emojiClosing: boolean
    emojiEntering: boolean
    onClose: () => void
    onEmojiClick?: (emojiCode: string) => void
}) {
    const [mounted, setMounted] = useState(false)
    const [pos, setPos] = useState<{ top: number; left: number; width: number }>({ top: 0, left: 0, width: 360 })
    const [recentItems, setRecentItems] = useState<EmojiItem[]>([])

    const loadRecentEmojis = useCallback(() => {
        if (typeof window === 'undefined') return
        try {
            const stored = localStorage.getItem('recent_emojis')
            if (!stored) {
                setRecentItems([])
                return
            }
            const codes: string[] = JSON.parse(stored)
            const recent: EmojiItem[] = []
            for (const code of codes) {
                const item = items.find((it) => it.code === code)
                if (item) {
                    recent.push(item)
                }
            }
            setRecentItems(recent)
        } catch (error) {
            console.error('Failed to get recent emojis:', error)
            setRecentItems([])
        }
    }, [items])

    useEffect(() => {
        loadRecentEmojis()
    }, [loadRecentEmojis, emojiTab])

    useEffect(() => {
        if (typeof window === 'undefined') return
        const handleStorageChange = (e: StorageEvent) => {
            if (e.key === 'recent_emojis') {
                loadRecentEmojis()
            }
        }
        window.addEventListener('storage', handleStorageChange)
        return () => {
            window.removeEventListener('storage', handleStorageChange)
        }
    }, [loadRecentEmojis])

    const handleEmojiClick = useCallback((emojiCode: string) => {
        if (onEmojiClick) {
            onEmojiClick(emojiCode)
        }
        if (typeof window !== 'undefined') {
            try {
                const stored = localStorage.getItem('recent_emojis')
                let codes: string[] = stored ? JSON.parse(stored) : []
                codes = codes.filter((code) => code !== emojiCode)
                codes.unshift(emojiCode)
                codes = codes.slice(0, 20)
                localStorage.setItem('recent_emojis', JSON.stringify(codes))
                loadRecentEmojis()
            } catch (error) {
                console.error('Failed to save recent emoji:', error)
            }
        }
    }, [onEmojiClick, loadRecentEmojis])

    useEffect(() => setMounted(true), [])

    useLayoutEffect(() => {
        if (!mounted) return
        const PANEL_H = 310
        const GAP = 8
        const AVOID_EXTRA = 5
        const MARGIN = 12
        const compute = () => {
            const anchor = anchorRef.current
            if (!anchor) return
            const r = anchor.getBoundingClientRect()
            const vw = window.innerWidth
            const vh = window.innerHeight
            const boundsRect = boundsRef?.current?.getBoundingClientRect?.()
            const leftBound = boundsRect ? boundsRect.left : 0
            const rightBound = boundsRect ? boundsRect.right : vw
            const boundsWidth = boundsRect ? boundsRect.width : vw
            const isPopout = boundsRect && boundsWidth < 500
            let width: number
            let left: number
            if (isPopout) {
                width = Math.max(0, Math.floor(boundsWidth - MARGIN * 2))
                left = Math.round(leftBound + MARGIN)
            } else {
                const maxW = Math.max(0, Math.floor(rightBound - leftBound - MARGIN * 2))
                const desiredW = variant === 'desktop' ? 360 : Math.max(280, vw - 32)
                width = Math.round(maxW > 0 ? Math.min(desiredW, maxW) : desiredW)
                const leftMin = Math.round((boundsRect ? leftBound : 0) + MARGIN)
                const leftMax = Math.round((boundsRect ? rightBound : vw) - width - MARGIN)
                const unclampedLeft = Math.round(r.right - width)
                left = Math.min(Math.max(unclampedLeft, leftMin), leftMax)
            }
            const avoidRect = avoidRef?.current?.getBoundingClientRect?.()
            const top = avoidRect
                ? avoidRect.top - PANEL_H - GAP - AVOID_EXTRA
                : (() => {
                    const preferTop = r.top - PANEL_H - GAP
                    const canTop = preferTop >= MARGIN
                    return canTop ? preferTop : Math.min(vh - PANEL_H - MARGIN, r.bottom + GAP)
                })()
            setPos({ top: Math.round(top), left: Math.round(left), width: Math.round(width) })
        }
        compute()
        window.addEventListener('resize', compute)
        window.addEventListener('scroll', compute, true)
        return () => {
            window.removeEventListener('resize', compute)
            window.removeEventListener('scroll', compute, true)
        }
    }, [mounted, variant, anchorRef, boundsRef, avoidRef])

    if (!mounted) return null

    return createPortal(
        <div
            ref={panelRef}
            style={{ top: `${pos.top}px`, left: `${pos.left}px`, width: `${pos.width}px` }}
            className={`fixed z-[180] rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-[#0c0d0e] shadow-lg overflow-hidden transform-gpu transition-[opacity,transform] duration-200 ease-[cubic-bezier(0.56,0.12,0.12,0.98)] ${emojiClosing || emojiEntering ? 'opacity-0 translate-y-2 pointer-events-none' : 'opacity-100 translate-y-0'
                }`}
        >
            <div className="flex items-center px-4 py-2.5">
                <h3 className="text-base font-semibold text-gray-900 dark:text-white">{t('room.emoji.title')}</h3>
                <button
                    type="button"
                    onClick={onClose}
                    className="ml-auto w-7 h-7 rounded-full inline-flex items-center justify-center hover:bg-[rgba(145,150,161,0.1)] active:bg-[rgba(23,25,28,0.3)] transition-colors"
                    aria-label={t('room.close')}
                >
                    <FiX className="w-4.5 h-4.5 text-[#757b8a] dark:text-gray-300" />
                </button>
            </div>

            <div className="border-b border-gray-200/80 dark:border-gray-800 px-3">
                <div className="flex items-end gap-2">
                    <button
                        type="button"
                        aria-hidden="true"
                        tabIndex={-1}
                        className="w-10 h-8 mb-[7px] rounded-lg inline-flex items-center justify-center text-[#acb0b9] opacity-60 cursor-default select-none"
                    >
                        <FiChevronLeft className="w-4 h-4" />
                    </button>

                    <div className="relative flex-1 overflow-hidden h-[37px]">
                        <div className="absolute inset-y-0 left-0 flex items-end gap-2">
                            {(
                                [
                                    { key: 'recent', icon: <FiClock className="w-5 h-5" />, label: t('room.emoji.tabs.recent') },
                                    { key: 'subscription', icon: <FiStar className="w-5 h-5" />, label: t('room.emoji.tabs.subscription') },
                                    { key: 'default', icon: <FiSmile className="w-5 h-5" />, label: t('room.emoji.tabs.default') },
                                ] as const
                            ).map((tab) => (
                                <div
                                    key={tab.key}
                                    className={`relative inline-flex items-center mb-[7px] before:content-[''] before:absolute before:left-0 before:bottom-[-7px] before:bg-blue-600 dark:before:bg-blue-400 before:w-0 before:h-0.5 before:rounded before:transition-[width] before:duration-200 before:ease-[cubic-bezier(0,1,0.66,1.1)] ${emojiTab === tab.key ? 'before:w-full' : ''
                                        }`}
                                >
                                    <button
                                        type="button"
                                        onClick={() => setEmojiTab(tab.key)}
                                        title={tab.label}
                                        className="w-10 h-8 rounded-lg inline-flex items-center justify-center hover:bg-[rgba(145,150,161,0.1)] transition-colors text-[#525661] dark:text-gray-200"
                                    >
                                        {tab.icon}
                                    </button>
                                </div>
                            ))}
                        </div>
                    </div>

                    <button
                        type="button"
                        aria-hidden="true"
                        tabIndex={-1}
                        className="w-10 h-8 mb-[7px] rounded-lg inline-flex items-center justify-center text-[#acb0b9] opacity-60 cursor-default select-none"
                    >
                        <FiChevronRight className="w-4 h-4" />
                    </button>
                </div>
            </div>

            <div className="flex-1 h-[calc(310px-44px-38px)] overflow-y-auto overflow-x-hidden hide-scrollbar">
                {emojiTab === 'recent' ? (
                    recentItems.length === 0 ? (
                        <div className="h-full flex items-center justify-center px-4 pb-2">
                            <p className="text-sm text-[#757b8a] dark:text-gray-400 leading-5 text-center">{t('room.emoji.recentEmpty')}</p>
                        </div>
                    ) : (
                        <div className="p-3 flex flex-wrap items-start gap-1.5">
                            {recentItems.map((it) => (
                                <button
                                    key={it.id}
                                    type="button"
                                    onClick={() => handleEmojiClick(it.code)}
                                    className="rounded-lg inline-flex items-center justify-center hover:bg-[rgba(117,123,138,0.1)] transition-colors"
                                    style={{ width: CHAT_EMOJI_PANEL_CELL_PX, height: CHAT_EMOJI_PANEL_CELL_PX }}
                                    title={it.code}
                                    aria-label={it.alt}
                                >
                                    <Image
                                        src={it.src}
                                        alt={it.alt}
                                        width={CHAT_EMOJI_PANEL_PX}
                                        height={CHAT_EMOJI_PANEL_PX}
                                        className="object-contain"
                                        style={{ width: CHAT_EMOJI_PANEL_PX, height: CHAT_EMOJI_PANEL_PX }}
                                        unoptimized
                                    />
                                </button>
                            ))}
                        </div>
                    )
                ) : (
                    <div className="p-1 flex flex-wrap items-start gap-1.5">
                        {items.map((it) => (
                            <button
                                key={it.id}
                                type="button"
                                onClick={() => {
                                    if (onEmojiClick) {
                                        onEmojiClick(it.code)
                                    }
                                }}
                                className="rounded-lg inline-flex items-center justify-center hover:bg-[rgba(117,123,138,0.1)] transition-colors"
                                style={{ width: CHAT_EMOJI_PANEL_CELL_PX, height: CHAT_EMOJI_PANEL_CELL_PX }}
                                title={it.code}
                                aria-label={it.alt}
                            >
                                <Image
                                    src={it.src}
                                    alt={it.alt}
                                    width={CHAT_EMOJI_PANEL_PX}
                                    height={CHAT_EMOJI_PANEL_PX}
                                    className="object-contain"
                                    style={{ width: CHAT_EMOJI_PANEL_PX, height: CHAT_EMOJI_PANEL_PX }}
                                    unoptimized
                                />
                            </button>
                        ))}
                    </div>
                )}
            </div>
        </div>
        ,
        document.body
    )
}

