'use client';

import React, { useMemo, useState, useRef, useCallback } from 'react';
import {
    Check,
    CheckCheck,
    Clock,
    AlertCircle,
    ImageIcon,
    Video,
    FileText,
    Mic,
    Reply,
    MoreHorizontal,
    ChevronDown,
    Forward,
    Star,
    Trash2,
    Link,
    Copy,
    Phone,
    List,
    ChevronRight,
    BarChart2,
    X,
    Download,
} from 'lucide-react';
import { createPortal } from 'react-dom';
import { motion, AnimatePresence } from 'framer-motion';
import { format } from 'date-fns';
import { Message, RichPayload, NativeBtn } from '../types/inboxTypes';
import { normalizeJid, formatPhone, getMediaUrl, parseSafeDate } from '../utils/inboxUtils';
import LinkPreview, { extractFirstUrl, renderTextWithLinks } from './LinkPreview';
import Avatar from './ui/Avatar';

// ── AudioBubble ───────────────────────────────────────────────────────────────

interface AudioBubbleProps {
    msg: Message
    fullMediaUrl: string | null
    isOut: boolean
    TimestampRow: React.ReactNode
}

const WAVEFORM_BARS = 30

const AudioBubble: React.FC<AudioBubbleProps> = ({ msg, fullMediaUrl, isOut, TimestampRow }) => {
    const audioRef = useRef<HTMLAudioElement>(null)
    const [playing, setPlaying] = useState(false)
    const [currentTime, setCurrentTime] = useState(0)
    const [duration, setDuration] = useState(0)
    const [speed, setSpeed] = useState<1 | 1.5 | 2>(1)
    const [played, setPlayed] = useState(false)

    const toggle = useCallback(() => {
        const el = audioRef.current
        if (!el) return
        if (playing) {
            el.pause()
            setPlaying(false)
        } else {
            el.play().catch(() => {})
            setPlaying(true)
            setPlayed(true)
        }
    }, [playing])

    const cycleSpeed = useCallback(() => {
        const el = audioRef.current
        const next: 1 | 1.5 | 2 = speed === 1 ? 1.5 : speed === 1.5 ? 2 : 1
        setSpeed(next)
        if (el) el.playbackRate = next
    }, [speed])

    const formatTime = (s: number) => {
        if (!isFinite(s) || s <= 0) return '0:00'
        const m = Math.floor(s / 60)
        const sec = Math.floor(s % 60)
        return `${m}:${sec.toString().padStart(2, '0')}`
    }

    const progress = duration > 0 ? currentTime / duration : 0

    // Incoming unread PTT = green; played or outgoing = blue
    const isPtt = msg.type === 'ptt'
    const accent = isPtt && !isOut && !played ? '#00a884' : '#53bdeb'

    // Deterministic waveform heights seeded from message_id
    const waveHeights = useMemo(() => {
        const seed = msg.message_id.split('').reduce((a, c) => (a + c.charCodeAt(0)) % 97, 0)
        return Array.from({ length: WAVEFORM_BARS }, (_, i) => {
            const v = Math.abs(Math.sin((i + seed) * 0.85)) * 0.55 + Math.abs(Math.sin((i * 2.3 + seed) * 0.4)) * 0.45
            return Math.max(0.15, Math.min(1, v))
        })
    }, [msg.message_id])

    return (
        <div>
            <audio
                ref={audioRef}
                src={fullMediaUrl || undefined}
                onTimeUpdate={() => setCurrentTime(audioRef.current?.currentTime ?? 0)}
                onDurationChange={() => setDuration(audioRef.current?.duration ?? 0)}
                onEnded={() => { setPlaying(false); setCurrentTime(0) }}
                preload="metadata"
            />
            <div className="flex items-center gap-2.5 bg-[#f0f2f5] px-3 py-2.5 rounded-xl border border-black/5 w-[260px]">
                {/* Play/pause */}
                <button
                    onClick={toggle}
                    className="w-10 h-10 rounded-full flex items-center justify-center shrink-0 shadow-sm transition-transform active:scale-95"
                    style={{ backgroundColor: accent }}
                >
                    {playing ? (
                        <svg className="w-4 h-4 fill-white" viewBox="0 0 24 24">
                            <rect x="5" y="3" width="4" height="18" rx="1" />
                            <rect x="15" y="3" width="4" height="18" rx="1" />
                        </svg>
                    ) : (
                        <svg className="w-4 h-4 fill-white" viewBox="0 0 24 24">
                            <polygon points="6,3 20,12 6,21" />
                        </svg>
                    )}
                </button>

                {/* Speed — antes do waveform, alinhado ao centro vertical */}
                <button
                    onClick={cycleSpeed}
                    className="text-[11px] font-bold text-[#667781] hover:text-[#111b21] transition-colors leading-none shrink-0 w-7 text-center"
                >
                    {speed === 1 ? '1×' : speed === 1.5 ? '1.5×' : '2×'}
                </button>

                {/* Waveform + tempo */}
                <div className="flex-1 flex flex-col gap-1 min-w-0">
                    <div className="flex items-end gap-[2px] h-7">
                        {waveHeights.map((h, i) => (
                            <div
                                key={i}
                                className="flex-1 rounded-full transition-colors duration-100"
                                style={{
                                    height: `${h * 100}%`,
                                    backgroundColor: i / WAVEFORM_BARS <= progress ? accent : '#cdd4da',
                                }}
                            />
                        ))}
                    </div>
                    <span className="text-[11px] text-[#667781] tabular-nums leading-none">
                        {currentTime > 0 ? formatTime(currentTime) : formatTime(duration)}
                    </span>
                </div>
            </div>
            {TimestampRow}
        </div>
    )
}

// ── DocumentBubble ────────────────────────────────────────────────────────────

interface DocumentBubbleProps {
    msg: Message
    fullMediaUrl: string | null
    TimestampRow: React.ReactNode
    onRedownload?: () => void
    isRedownloading?: boolean
}

const DOC_TYPES: Record<string, { bg: string; label: string }> = {
    pdf:  { bg: '#e53e3e', label: 'PDF' },
    doc:  { bg: '#2b6cb0', label: 'W'   },
    docx: { bg: '#2b6cb0', label: 'W'   },
    xls:  { bg: '#276749', label: 'X'   },
    xlsx: { bg: '#276749', label: 'X'   },
    ppt:  { bg: '#c05621', label: 'P'   },
    pptx: { bg: '#c05621', label: 'P'   },
    txt:  { bg: '#718096', label: 'TXT' },
    csv:  { bg: '#276749', label: 'CSV' },
}

const DocumentBubble: React.FC<DocumentBubbleProps> = ({ msg, fullMediaUrl, TimestampRow, onRedownload, isRedownloading }) => {
    const [previewOpen, setPreviewOpen] = useState(false)

    // Derive extension from media_type or media_url
    const ext = (() => {
        const fromMime = msg.media_type?.split('/').pop()?.replace(/[^a-z0-9]/gi, '') ?? ''
        const fromUrl  = fullMediaUrl?.split('?')[0].split('.').pop()?.toLowerCase() ?? ''
        return (fromMime || fromUrl || 'file').toLowerCase().slice(0, 5)
    })()

    const docType = DOC_TYPES[ext] ?? { bg: '#00a884', label: ext.toUpperCase().slice(0, 3) || 'FILE' }

    // Filename: prefer msg.text; fallback to last segment of URL
    const filename = msg.text?.trim() ||
        fullMediaUrl?.split('?')[0].split('/').pop()?.replace(/^\d+-/, '') ||
        'Documento'

    const sizeStr = msg.media_size && msg.media_size > 0
        ? msg.media_size >= 1024 * 1024
            ? `${(msg.media_size / 1024 / 1024).toFixed(1)} MB`
            : `${Math.ceil(msg.media_size / 1024)} KB`
        : null

    const isPdf = ext === 'pdf'

    const handleClick = () => {
        if (!fullMediaUrl) {
            onRedownload?.()
            return
        }
        if (isPdf) {
            setPreviewOpen(true)
        } else {
            window.open(fullMediaUrl, '_blank')
        }
    }

    return (
        <>
            <div>
                <div
                    onClick={handleClick}
                    className="flex items-center gap-3 bg-[#f0f2f5] p-3 rounded-xl border border-black/5 cursor-pointer hover:bg-[#e8eaed] transition-all active:scale-[0.98] min-w-[220px] max-w-[280px]"
                >
                    {/* Type icon */}
                    <div
                        className="w-10 h-10 rounded-lg flex items-center justify-center shrink-0 shadow-sm"
                        style={{ backgroundColor: docType.bg }}
                    >
                        {isRedownloading
                            ? <div className="w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin" />
                            : <span className="text-white text-[10px] font-extrabold tracking-tight leading-none">{docType.label}</span>
                        }
                    </div>
                    {/* Filename + meta */}
                    <div className="flex flex-col min-w-0 flex-1">
                        <span className="text-[13.5px] font-normal truncate text-[#111b21] leading-snug">
                            {filename}
                        </span>
                        <span className="text-[11px] text-[#667781] mt-[2px]">
                            {isRedownloading ? 'Baixando...' : `${ext.toUpperCase()}${sizeStr ? ` · ${sizeStr}` : ''}`}
                        </span>
                    </div>
                    <Download className="w-4 h-4 text-[#8696a0] shrink-0" />
                </div>
                {TimestampRow}
            </div>

            {/* PDF inline preview modal — rendered via portal to escape framer-motion stacking context */}
            {previewOpen && fullMediaUrl && typeof document !== 'undefined' && createPortal(
                <div
                    className="fixed inset-0 z-[9999] flex flex-col bg-black/80 backdrop-blur-sm"
                    onClick={(e) => { if (e.target === e.currentTarget) setPreviewOpen(false) }}
                >
                    <div className="flex items-center justify-between px-4 py-2 bg-[#111b21] shrink-0">
                        <span className="text-white text-[13px] font-medium truncate max-w-[70%]">{filename}</span>
                        <div className="flex items-center gap-3">
                            <a
                                href={fullMediaUrl}
                                download={filename}
                                className="text-[#8696a0] hover:text-white transition-colors"
                                onClick={(e) => e.stopPropagation()}
                            >
                                <Download className="w-5 h-5" />
                            </a>
                            <button
                                onClick={() => setPreviewOpen(false)}
                                className="text-[#8696a0] hover:text-white transition-colors"
                            >
                                <X className="w-5 h-5" />
                            </button>
                        </div>
                    </div>
                    <iframe
                        src={fullMediaUrl}
                        className="flex-1 w-full border-0"
                        title={filename}
                    />
                </div>,
                document.body
            )}
        </>
    )
}

// Message interface removed and moved to types.ts

interface MessageBubbleProps {
    msg: Message;
    isGroupChat: boolean;
    senderLabel: string;
    showTail?: boolean;
    quotedSenderLabel?: string;
    quotedPreviewText?: string;
    reactionPickerFor: string | null;
    onReply: (msg: Message) => void;
    onToggleReactionPicker: (msgId: string) => void;
    onReact: (msg: Message, emoji: string) => void;
    onForward?: (msg: Message) => void;
    onDelete?: (msg: Message) => void;
    onStar?: (msg: Message) => void;
    onEdit?: (msg: Message) => void;
    onOpenMedia?: (msg: Message) => void;
    onRedownloadMedia?: (msg: Message) => Promise<void>;
    quickReactions: string[];
    selectedChat?: any;
}

const MessageBubble: React.FC<MessageBubbleProps> = ({
    msg,
    isGroupChat,
    senderLabel,
    quotedSenderLabel,
    quotedPreviewText,
    reactionPickerFor,
    onReply,
    onToggleReactionPicker,
    onReact,
    onForward,
    onDelete,
    onStar,
    onEdit,
    onOpenMedia,
    onRedownloadMedia,
    quickReactions,
    selectedChat,
    showTail = false,
}) => {
    const [isMenuOpen, setIsMenuOpen] = React.useState(false);
    const [listOpen, setListOpen] = useState(false);
    const [isRedownloading, setIsRedownloading] = useState(false);
    const [mediaUnavailable, setMediaUnavailable] = useState(false);

    const handleRedownload = useCallback(async () => {
        if (!onRedownloadMedia || isRedownloading || mediaUnavailable) return
        setIsRedownloading(true)
        try {
            await onRedownloadMedia(msg)
        } catch (err: any) {
            const status = err?.response?.status ?? err?.status
            if (status === 400 || status === 404) setMediaUnavailable(true)
        } finally {
            setIsRedownloading(false)
        }
    }, [onRedownloadMedia, msg, isRedownloading, mediaUnavailable])
    const isOut = msg.direction === 'out';
    const showActionsLeft = isOut;
    const showActionsRight = !isOut;

    // variant: 'dark' = texto escuro (balão claro), 'white' = overlay sobre imagem
    const renderMessageStatus = (status: string, variant: 'dark' | 'white' = 'dark') => {
        const c = variant === 'white'
            ? { pending: 'text-white/50', sent: 'text-white/70', check2: 'text-white/70', read: 'text-[#53bdeb]', fail: 'text-red-300' }
            : { pending: 'text-[#8696a0]/60', sent: 'text-[#8696a0]', check2: 'text-[#8696a0]', read: 'text-[#53bdeb]', fail: 'text-[#ef4444]' }
        switch (status) {
            case 'pending':
                // Mensagem enfileirada — ainda não chegou ao servidor
                return <Clock className={`w-3 h-3 ${c.pending}`} />
            case 'sent':
                // Chegou ao servidor — não sabemos se foi entregue
                return <Check className={`w-3.5 h-3.5 ${c.sent}`} />
            case 'delivered':
                // Entregue no dispositivo do destinatário
                return <CheckCheck className={`w-3.5 h-3.5 ${c.check2}`} />
            case 'read':
                // Lido pelo destinatário
                return <CheckCheck className={`w-3.5 h-3.5 ${c.read}`} />
            case 'failed':
                return <span title="Falha no envio"><AlertCircle className={`w-3.5 h-3.5 ${c.fail}`} /></span>
            default:
                return null
        }
    };

    // ── Timestamp helpers ─────────────────────────────────────────────────────

    const timeStr = format(parseSafeDate(msg.timestamp), 'HH:mm');

    // Espaçador invisível — empurra o texto da última linha para criar espaço
    // para o timestamp sem sobrepor o conteúdo (técnica usada pelo WhatsApp oficial)
    // outgoing: tempo (~38px) + gap + check (~14px) = ~62px
    // incoming: tempo somente (~42px)
    const spacerW = isOut ? 62 : 42;
    const TimespacerEl = (
        <span
            className="inline-block pointer-events-none select-none opacity-0 align-bottom"
            style={{ width: spacerW, height: 14 }}
            aria-hidden
        />
    );

    // Timestamp padrão (sobre fundo claro)
    const TimestampEl = (
        <span className="inline-flex items-center gap-[3px] text-[11px] text-[#667781] font-normal leading-none select-none flex-shrink-0">
            {timeStr}
            {isOut && renderMessageStatus(msg.status)}
        </span>
    );

    // Timestamp para overlay em fundo escuro (imagem/vídeo sem legenda)
    const TimestampWhiteEl = (
        <span className="inline-flex items-center gap-[3px] text-[11px] text-white/90 font-normal leading-none select-none flex-shrink-0 drop-shadow">
            {timeStr}
            {isOut && renderMessageStatus(msg.status, 'white')}
        </span>
    );

    // Linha de timestamp abaixo do conteúdo (áudio, documento, sticker, etc.)
    const TimestampRow = (
        <div className="flex items-center justify-end gap-[3px] mt-1 -mb-0.5 pr-0.5">
            {TimestampEl}
        </div>
    );

    // ── Rich message renderers ────────────────────────────────────────────────

    const renderRichButtons = (p: RichPayload) => {
        const btns = p.nativeButtons ?? []
        const btnIcon = (b: NativeBtn) => {
            if (b.type === 'url')  return <Link   className="w-3.5 h-3.5 shrink-0" />
            if (b.type === 'copy') return <Copy   className="w-3.5 h-3.5 shrink-0" />
            if (b.type === 'call') return <Phone  className="w-3.5 h-3.5 shrink-0" />
            return null
        }
        return (
            <div>
                {(p.text || p.footer) && (
                    <div className="px-1 pt-1 pb-1">
                        {p.text && (
                            <p className="text-[14.2px] break-words whitespace-pre-wrap leading-[1.6] text-[#111b21]">
                                {renderTextWithLinks(p.text)}
                            </p>
                        )}
                        {p.footer && <p className="text-[12px] text-[#667781] mt-0.5">{p.footer}</p>}
                    </div>
                )}
                <div className="border-t border-black/10 mt-1">
                    {btns.map((b, i) => (
                        <div
                            key={i}
                            className={`flex items-center justify-center gap-1.5 py-2 px-3 text-[13px] font-medium text-[#00a884] ${i > 0 ? 'border-t border-black/10' : ''}`}
                        >
                            {btnIcon(b)}
                            <span>{b.text}</span>
                        </div>
                    ))}
                </div>
                {TimestampRow}
            </div>
        )
    }

    const renderRichList = (p: RichPayload) => {
        const open = listOpen
        const setOpen = setListOpen
        const list = p.nativeList!
        return (
            <div>
                {(p.text || p.footer) && (
                    <div className="px-1 pt-1 pb-1">
                        {p.text && (
                            <p className="text-[14.2px] break-words whitespace-pre-wrap leading-[1.6] text-[#111b21]">
                                {renderTextWithLinks(p.text)}
                            </p>
                        )}
                        {p.footer && <p className="text-[12px] text-[#667781] mt-0.5">{p.footer}</p>}
                    </div>
                )}
                <div className="border-t border-black/10 mt-1">
                    <button
                        onClick={() => setOpen(!open)}
                        className="w-full flex items-center justify-center gap-1.5 py-2 px-3 text-[13px] font-medium text-[#00a884]"
                    >
                        <List className="w-3.5 h-3.5 shrink-0" />
                        <span>{list.buttonText}</span>
                        <ChevronRight className={`w-3.5 h-3.5 shrink-0 transition-transform ${open ? 'rotate-90' : ''}`} />
                    </button>
                    {open && (
                        <div className="border-t border-black/10 bg-black/[0.02] rounded-b-lg">
                            {list.sections.map((s, si) => (
                                <div key={si}>
                                    {s.title && <div className="px-3 py-1.5 text-[11px] font-bold text-[#667781] uppercase tracking-wide">{s.title}</div>}
                                    {s.rows.map((r, ri) => (
                                        <div key={ri} className="px-3 py-2 border-t border-black/5">
                                            <div className="text-[13px] font-medium text-[#111b21]">{r.title}</div>
                                            {r.description && <div className="text-[12px] text-[#667781] mt-0.5">{r.description}</div>}
                                        </div>
                                    ))}
                                </div>
                            ))}
                        </div>
                    )}
                </div>
                {TimestampRow}
            </div>
        )
    }

    const renderRichCarousel = (p: RichPayload) => {
        const cards = p.nativeCarousel?.cards ?? []
        return (
            <div className="max-w-[320px]">
                {p.text && (
                    <div className="px-1 pt-1 pb-1">
                        <p className="text-[14.2px] break-words whitespace-pre-wrap leading-[1.6] text-[#111b21]">
                            {renderTextWithLinks(p.text)}
                        </p>
                    </div>
                )}
                <div className="flex gap-2 overflow-x-auto pb-1 snap-x snap-mandatory px-1 scrollbar-hide">
                    {cards.map((card, ci) => (
                        <div key={ci} className="snap-start shrink-0 w-[200px] bg-white border border-black/10 rounded-xl overflow-hidden shadow-sm">
                            {card.image?.url && (
                                <img
                                    src={card.image.url}
                                    alt={card.title ?? ''}
                                    className="w-full h-28 object-cover"
                                />
                            )}
                            <div className="p-2">
                                {card.title  && <div className="text-[13px] font-semibold text-[#111b21] truncate">{card.title}</div>}
                                {card.body   && <div className="text-[12px] text-[#667781] mt-0.5 line-clamp-2">{card.body}</div>}
                                {card.footer && <div className="text-[11px] text-[#8696a0] mt-0.5">{card.footer}</div>}
                                {(card.buttons ?? []).length > 0 && (
                                    <div className="mt-2 border-t border-black/10 pt-1.5 flex flex-col gap-1">
                                        {card.buttons.map((b, bi) => (
                                            <div key={bi} className="text-center text-[12px] font-medium text-[#00a884] py-0.5">{b.text}</div>
                                        ))}
                                    </div>
                                )}
                            </div>
                        </div>
                    ))}
                </div>
                {TimestampRow}
            </div>
        )
    }

    const renderRichPoll = (p: RichPayload) => {
        const poll = p.poll!
        return (
            <div className="min-w-[220px]">
                <div className="px-1 pt-1 pb-1">
                    <div className="flex items-center gap-1.5 text-[12px] text-[#667781] font-medium mb-1.5">
                        <BarChart2 className="w-3.5 h-3.5" />
                        <span>ENQUETE</span>
                    </div>
                    <p className="text-[14.2px] font-semibold text-[#111b21] mb-2">{poll.name}</p>
                    <div className="flex flex-col gap-1.5">
                        {poll.values.map((v, i) => (
                            <div key={i} className="flex items-center gap-2 py-1.5 px-2 border border-black/10 rounded-lg text-[13px] text-[#111b21] hover:bg-black/5 cursor-pointer transition-colors">
                                <div className="w-4 h-4 rounded-full border-2 border-[#8696a0] shrink-0" />
                                {v}
                            </div>
                        ))}
                    </div>
                    {poll.selectableCount && poll.selectableCount > 1 && (
                        <div className="text-[11px] text-[#8696a0] mt-1.5">Selecione até {poll.selectableCount} opções</div>
                    )}
                </div>
                {TimestampRow}
            </div>
        )
    }

    const renderMessageContent = () => {
        const fullMediaUrl = getMediaUrl(msg.media_url);

        // ── Rich message types ──────────────────────────────────────────────
        const rp = msg.rich_payload

        // Mensagem outgoing com payload rico salvo
        if (rp) {
            if (msg.type === 'buttons') return renderRichButtons(rp)
            if (msg.type === 'list')     return renderRichList(rp)
            if (msg.type === 'carousel') return renderRichCarousel(rp)
            if (msg.type === 'poll' && rp.poll) return renderRichPoll(rp)
            // INTERACTIVE (url/copy/call) também usa renderRichButtons
            if (msg.type === 'interactive' && rp.nativeButtons) return renderRichButtons(rp)
        }

        // Resposta de clique de botão / seleção de lista recebida (incoming)
        if (msg.type === 'interactive' && !rp && msg.text) {
            return (
                <div>
                    <div className="flex items-center gap-1.5 text-[12px] text-[#667781] mb-1">
                        <ChevronRight className="w-3.5 h-3.5 text-[#00a884]" />
                        <span className="font-medium text-[#00a884]">Selecionou:</span>
                    </div>
                    <p className="text-[14.2px] break-words whitespace-pre-wrap leading-[1.6] text-[#111b21]">
                        {msg.text}
                        {TimespacerEl}
                    </p>
                    <div className="absolute bottom-0.5 right-1">{TimestampEl}</div>
                </div>
            )
        }

        // Mensagem interativa incoming (botões/lista enviados por outro BA)
        if (msg.type === 'buttons' && !rp && msg.text) {
            return (
                <div>
                    <p className="text-[14.2px] break-words whitespace-pre-wrap leading-[1.6] text-[#111b21]">
                        {renderTextWithLinks(msg.text)}
                        {TimespacerEl}
                    </p>
                    <div className="flex items-center gap-1 text-[11px] text-[#8696a0] mt-1">
                        <span>📋</span><span>Mensagem com botões</span>
                    </div>
                    <div className="absolute bottom-0.5 right-1">{TimestampEl}</div>
                </div>
            )
        }

        switch (msg.type) {
            case 'image': {
                const hasCaption = Boolean(msg.text?.trim());
                return (
                    <div className="rounded-lg overflow-hidden w-[268px]">
                        <div
                            className="relative group/media w-[268px] h-[200px] bg-black/5 cursor-pointer overflow-hidden"
                            onClick={() => fullMediaUrl ? (onOpenMedia ? onOpenMedia(msg) : window.open(fullMediaUrl, '_blank')) : handleRedownload()}
                        >
                            {fullMediaUrl ? (
                                <img
                                    src={fullMediaUrl}
                                    alt="Media"
                                    className="w-full h-full object-cover transition-transform group-hover/media:scale-[1.03] block"
                                />
                            ) : (
                                <div className="flex flex-col items-center justify-center w-full h-full gap-2">
                                    {isRedownloading
                                        ? <div className="w-8 h-8 border-2 border-slate-400 border-t-transparent rounded-full animate-spin" />
                                        : <><ImageIcon className="w-8 h-8 text-slate-400" /><span className="text-[11px] text-slate-400">Toque para baixar</span></>
                                    }
                                </div>
                            )}
                            {!hasCaption && (
                                <div className="absolute bottom-1.5 right-2 bg-black/40 backdrop-blur-[2px] rounded-full px-1.5 py-[3px]">
                                    {TimestampWhiteEl}
                                </div>
                            )}
                        </div>
                        {hasCaption && (
                            <div className="relative px-1 pt-1.5 pb-0.5">
                                <p className="text-[14.2px] break-words whitespace-pre-wrap leading-[1.6] text-[#111b21]">
                                    {msg.text}
                                    {TimespacerEl}
                                </p>
                                <div className="absolute bottom-0.5 right-1">{TimestampEl}</div>
                            </div>
                        )}
                    </div>
                );
            }
            case 'video': {
                const hasCaption = Boolean(msg.text?.trim());
                return (
                    <div className="rounded-lg overflow-hidden w-[268px]">
                        <div
                            className="relative w-[268px] h-[200px] bg-black cursor-pointer group/vid overflow-hidden"
                            onClick={() => fullMediaUrl ? (onOpenMedia ? onOpenMedia(msg) : window.open(fullMediaUrl, '_blank')) : handleRedownload()}
                        >
                            {fullMediaUrl ? (
                            <div className="absolute inset-0 flex items-center justify-center bg-black/20 hover:bg-black/30 transition-colors">
                                <div className="w-12 h-12 bg-white/20 backdrop-blur-md rounded-full flex items-center justify-center text-white shadow-xl border border-white/30 group-hover/vid:scale-110 transition-transform">
                                    <Video className="w-6 h-6 fill-current" />
                                </div>
                            </div>
                            ) : (
                            <div className="absolute inset-0 flex flex-col items-center justify-center bg-black/40 gap-2">
                                {isRedownloading
                                    ? <div className="w-8 h-8 border-2 border-white/60 border-t-transparent rounded-full animate-spin" />
                                    : <><Video className="w-8 h-8 text-white/60" /><span className="text-[11px] text-white/60">Toque para baixar</span></>
                                }
                            </div>
                            )}
                            <div className="absolute bottom-0 inset-x-0 h-10 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" />
                            {!hasCaption && (
                                <div className="absolute bottom-1.5 right-2">
                                    {TimestampWhiteEl}
                                </div>
                            )}
                        </div>
                        {hasCaption && (
                            <div className="relative px-1 pt-1.5 pb-0.5">
                                <p className="text-[14.2px] break-words whitespace-pre-wrap leading-[1.6] text-[#111b21]">
                                    {msg.text}
                                    {TimespacerEl}
                                </p>
                                <div className="absolute bottom-0.5 right-1">{TimestampEl}</div>
                            </div>
                        )}
                    </div>
                );
            }
            case 'audio':
            case 'ptt':
                if (!fullMediaUrl) {
                    return (
                        <div>
                            <div
                                onClick={mediaUnavailable ? undefined : handleRedownload}
                                className={`flex items-center gap-2.5 bg-[#f0f2f5] px-3 py-2.5 rounded-xl border border-black/5 w-[260px] transition-colors ${mediaUnavailable ? 'cursor-default opacity-60' : 'cursor-pointer hover:bg-[#e8eaed]'}`}
                            >
                                {isRedownloading
                                    ? <div className="w-8 h-8 border-2 border-slate-400 border-t-transparent rounded-full animate-spin shrink-0" />
                                    : <div className="w-10 h-10 rounded-full bg-[#8696a0] flex items-center justify-center shrink-0"><Mic className="w-4 h-4 text-white" /></div>
                                }
                                <span className="text-[12px] text-[#667781]">
                                    {isRedownloading ? 'Baixando...' : mediaUnavailable ? 'Áudio não disponível' : 'Toque para baixar áudio'}
                                </span>
                            </div>
                            {TimestampRow}
                        </div>
                    )
                }
                return <AudioBubble msg={msg} fullMediaUrl={fullMediaUrl} isOut={isOut} TimestampRow={TimestampRow} />;
            case 'document':
                return <DocumentBubble msg={msg} fullMediaUrl={fullMediaUrl} TimestampRow={TimestampRow} onRedownload={!fullMediaUrl ? handleRedownload : undefined} isRedownloading={isRedownloading} />;
            case 'sticker':
                return (
                    <div>
                        {fullMediaUrl
                            ? <img src={fullMediaUrl} alt="Sticker" className="max-w-[180px] max-h-[180px]" />
                            : (
                                <div
                                    onClick={handleRedownload}
                                    className="flex items-center gap-2 text-[13px] text-[#667781] italic cursor-pointer hover:text-[#111b21] transition-colors"
                                >
                                    {isRedownloading
                                        ? <div className="w-4 h-4 border-2 border-slate-400 border-t-transparent rounded-full animate-spin" />
                                        : <Star className="w-4 h-4" />
                                    }
                                    {isRedownloading ? 'Baixando...' : 'Toque para baixar figurinha'}
                                </div>
                            )
                        }
                        {TimestampRow}
                    </div>
                );
            case 'location':
                return (
                    <div>
                        <div className="flex items-center gap-2 text-[13px] text-[#667781] italic">
                            <span className="text-lg">📍</span> Localização compartilhada
                        </div>
                        {TimestampRow}
                    </div>
                );
            case 'contact':
                return (
                    <div>
                        <div className="flex items-center gap-2 text-[13px] text-[#667781] italic">
                            <span className="text-lg">👤</span> {msg.text || 'Contato compartilhado'}
                        </div>
                        {TimestampRow}
                    </div>
                );
            case 'reaction':
                return null;
            case 'unsupported':
                return (
                    <div>
                        <div className="flex items-center gap-2 text-[12px] text-[#8696a0] italic">
                            <AlertCircle className="w-3.5 h-3.5" /> Mensagem não suportada
                        </div>
                        {TimestampRow}
                    </div>
                );
            default: {
                // text, extendedtext, etc.
                if (!msg.text) {
                    return (
                        <div>
                            <div className="flex items-center gap-2 text-[12px] text-[#8696a0] italic">
                                <AlertCircle className="w-3.5 h-3.5" /> Mensagem não disponível
                            </div>
                            {TimestampRow}
                        </div>
                    );
                }
                return (
                    <p className="text-[14.2px] break-words whitespace-pre-wrap leading-[1.6] text-[#111b21]">
                        {renderTextWithLinks(msg.text)}
                        <span style={{ float: 'right', marginLeft: 6, position: 'relative', bottom: -3 }}>
                            {TimestampEl}
                        </span>
                    </p>
                );
            }
        }
    };

    const bubbleClasses = `px-2 py-1.5 rounded-lg shadow-[0_1px_0.5px_rgba(11,20,26,0.13)] relative group overflow-visible transition-all ${isOut
        ? `bg-[#d9fdd3] ${showTail ? 'rounded-tr-none' : ''}`
        : `bg-white ${showTail ? 'rounded-tl-none' : ''}`
        }`;

    const tailStyles = showTail ? (
        <div 
            className="absolute top-0 w-2.5 h-3.5 pointer-events-none"
            style={{
                [isOut ? 'right' : 'left']: '-8px',
                backgroundColor: isOut ? '#d9fdd3' : '#ffffff',
                clipPath: isOut ? 'polygon(0 0, 100% 0, 0 100%)' : 'polygon(100% 0, 0 0, 100% 100%)',
                zIndex: 1
            }}
        />
    ) : null;

    return (
        <motion.div
            id={`msg-${msg.message_id}`}
            initial={{ opacity: 0, scale: 0.95, y: 10 }}
            animate={{ opacity: 1, scale: 1, y: 0 }}
            className={`flex w-full mb-3 group/row ${isOut ? 'justify-end pr-4' : 'justify-start'}`}
        >
            {showActionsLeft && (
                <div className="opacity-0 group-hover/row:opacity-100 transition-opacity flex flex-col items-center justify-center mr-2 gap-2">
                    <button onClick={() => onReply(msg)} className="p-1.5 hover:bg-white/5 rounded-full text-slate-500 transition-all hover:scale-110" title="Responder">
                        <Reply className="w-4 h-4" />
                    </button>
                    <button onClick={() => onToggleReactionPicker(msg.message_id)} className="p-1.5 hover:bg-white/5 rounded-full text-slate-500 transition-all hover:scale-110" title="Reagir">
                        <span className="text-xs">🙂</span>
                    </button>
                </div>
            )}
            {!isOut && isGroupChat && senderLabel && (
                <div className="flex-shrink-0 mr-2 mt-1 self-start">
                    <Avatar
                        chat={{
                            remote_jid: msg.sender_jid || null,
                            displayName: senderLabel,
                            phone: null,
                            instance_name: (selectedChat as any)?.instance_name
                        }}
                        size={28}
                    />
                </div>
            )}

            <div className="flex flex-col max-w-[75%] relative">
                <div className={bubbleClasses}>
                    {tailStyles}
                    {/* Authentic WhatsApp Message Menu Button */}
                    <button
                        onClick={() => setIsMenuOpen(!isMenuOpen)}
                        className={`absolute top-1 right-1 p-1 text-slate-500 opacity-0 group-hover:opacity-100 hover:text-slate-300 transition-opacity z-30`}
                    >
                        <ChevronDown className="w-5 h-5" />
                    </button>

                    {isGroupChat && senderLabel && !isOut && (
                        <div className="mb-1.5 text-[11px] font-black tracking-wider text-brand-400 uppercase">
                            {senderLabel}
                        </div>
                    )}

                    {/* Quoted Message */}
                    {(msg.quoted_message_id || msg.quoted_id) && (
                        <div className={`mb-2 p-2 rounded-lg border-l-[4px] border-[#00a884] text-[13px] cursor-pointer ${isOut ? 'bg-black/5' : 'bg-[#f0f2f5]'} hover:bg-black/10 transition-colors`}
                            onClick={() => {
                                const targetId = msg.quoted_message_id || msg.quoted_id;
                                const el = targetId ? document.getElementById(`msg-${targetId}`) : null;
                                if (el) {
                                    el.scrollIntoView({ behavior: 'smooth', block: 'center' });
                                    el.classList.add('bg-[#00a884]/20');
                                    setTimeout(() => el.classList.remove('bg-[#00a884]/20'), 1500);
                                }
                            }}
                        >
                            <div className="font-bold text-[#00a884] mb-0.5 truncate">
                                {quotedSenderLabel}
                            </div>
                            <div className="text-[#667781] truncate">
                                {quotedPreviewText}
                            </div>
                        </div>
                    )}

                    {renderMessageContent()}

                    {/* Context Menu Dropdown */}
                    <AnimatePresence>
                        {isMenuOpen && (
                            <>
                                <div className="fixed inset-0 z-40" onClick={() => setIsMenuOpen(false)} />
                                <motion.div
                                    initial={{ opacity: 0, scale: 0.95, y: -10 }}
                                    animate={{ opacity: 1, scale: 1, y: 0 }}
                                    exit={{ opacity: 0, scale: 0.95, y: -10 }}
                                    className={`absolute top-8 ${isOut ? 'right-2' : 'left-2'} w-48 bg-white rounded-lg shadow-2xl border border-gray-100 py-1.5 z-[100] origin-top-right`}
                                >
                                    {[
                                        { label: 'Responder', icon: <Reply className="w-4 h-4" />, onClick: () => { onReply(msg); setIsMenuOpen(false); } },
                                        ...(isOut && msg.type === 'text' && onEdit ? [{ label: 'Editar', icon: <span className="w-4 h-4 font-bold text-xs">✎</span>, onClick: () => { onEdit(msg); setIsMenuOpen(false); } }] : []),
                                        { label: 'Encaminhar', icon: <Forward className="w-4 h-4" />, onClick: () => { onForward?.(msg); setIsMenuOpen(false); } },
                                        { label: 'Favoritar', icon: <Star className="w-4 h-4" />, onClick: () => { onStar?.(msg); setIsMenuOpen(false); } },
                                        { label: 'Apagar', icon: <Trash2 className="w-4 h-4" />, onClick: () => { onDelete?.(msg); setIsMenuOpen(false); }, danger: true },
                                    ].map((item, i) => (
                                        <button
                                            key={i}
                                            onClick={item.onClick}
                                            className={`w-full flex items-center gap-3 px-4 py-2.5 text-sm font-bold transition-colors ${item.danger ? 'text-red-400 hover:bg-red-500/10' : 'text-slate-300 hover:bg-white/5'}`}
                                        >
                                            {item.icon}
                                            {item.label}
                                        </button>
                                    ))}
                                </motion.div>
                            </>
                        )}
                    </AnimatePresence>

                    {/* Reaction Picker Popover */}
                    <AnimatePresence>
                        {reactionPickerFor === msg.message_id && (
                            <>
                                <div className="fixed inset-0 z-40" onClick={() => onToggleReactionPicker('')} />
                                <motion.div
                                    initial={{ opacity: 0, y: 10, scale: 0.9 }}
                                    animate={{ opacity: 1, y: 0, scale: 1 }}
                                    exit={{ opacity: 0, y: 10, scale: 0.9 }}
                                >
                                    <div className={`absolute top-[calc(100%+8px)] ${isOut ? 'right-0 origin-top-right' : 'left-0 origin-top'} z-[100] flex animate-in fade-in zoom-in duration-200`}>
                                        <div className="flex items-center gap-1.5 p-2 bg-[#111b21] rounded-full shadow-2xl border border-white/10 backdrop-blur-xl">
                                            {quickReactions.map((emoji) => (
                                                <button
                                                    key={emoji}
                                                    onClick={(e) => {
                                                        e.stopPropagation();
                                                        onReact(msg, emoji);
                                                        onToggleReactionPicker('');
                                                    }}
                                                    className="w-10 h-10 flex items-center justify-center hover:bg-white/5 rounded-full transition-all hover:scale-125 active:scale-95 text-2xl"
                                                >
                                                    {emoji}
                                                </button>
                                            ))}
                                        </div>
                                    </div>
                                </motion.div>
                            </>
                        )}
                    </AnimatePresence>
                </div>

                {/* Visible Reactions Badge */}
                {msg.reactions && Object.keys(msg.reactions).length > 0 && (
                    <motion.div
                        initial={{ scale: 0.5, opacity: 0 }}
                        animate={{ scale: 1, opacity: 1 }}
                        className={`mt-1 flex ${isOut ? 'justify-end mr-2' : 'justify-start ml-2'}`}
                    >
                        <div className="flex items-center bg-[#111b21] rounded-full px-2.5 py-1 shadow-2xl border border-white/5 gap-1.5 z-10 hover:scale-105 transition-transform cursor-pointer ring-1 ring-white/10 backdrop-blur-xl">
                            {Object.entries(msg.reactions).slice(0, 3).map(([sender, emoji], idx) => (
                                <span key={idx} title={sender} className="text-[13px]">{emoji}</span>
                            ))}
                            {Object.keys(msg.reactions).length > 3 && (
                                <span className="text-[10px] text-slate-500 font-black">+{Object.keys(msg.reactions).length - 3}</span>
                            )}
                        </div>
                    </motion.div>
                )}
            </div>

            {showActionsRight && (
                <div className="opacity-0 group-hover/row:opacity-100 transition-opacity flex flex-col items-center justify-center ml-2 gap-2">
                    <button onClick={() => onReply(msg)} className="p-1.5 hover:bg-white/5 rounded-full text-slate-500 transition-all hover:scale-110" title="Responder">
                        <Reply className="w-4 h-4" />
                    </button>
                    <button onClick={() => onToggleReactionPicker(msg.message_id)} className="p-1.5 hover:bg-white/5 rounded-full text-slate-500 transition-all hover:scale-110" title="Reagir">
                        <span className="text-xs">🙃</span>
                    </button>
                </div>
            )}
        </motion.div>
    );
};

export default MessageBubble;
