import React, { useState } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
import {
    EmojieIcon,
    EditIcon,
    ReplyIcon,
    MoreIcon,
    DeleteIcon,
    PinIcon,
} from '../assets/icons';
import { getEmojiUrl, AllEmojis } from '../assets/emojis';
import Tooltip from './Tooltip';
import Avatar from './Avatar';

const fireIcon = getEmojiUrl('nature', 'fire');
const heartIcon = getEmojiUrl('symbols', 'heart');
const thumbsupIcon = getEmojiUrl('people', 'thumbsup');

const ICON_COLOR_DEFAULT = 'color-mix(in oklab, hsl(240 4.294% 68.039% / 1) 100%, #000 0%)';
const USER_COLORS = ['#5865F2', '#EBA7CD', '#57F287', '#FEE75C', '#EB459E', '#ED4245'];

export const getUserColor = (name) => {
    let hash = 0;
    for (let i = 0; i < name.length; i++) { hash = name.charCodeAt(i) + ((hash << 5) - hash); }
    return USER_COLORS[Math.abs(hash) % USER_COLORS.length];
};

export const extractUrls = (text) => {
    const urlRegex = /(https?:\/\/[^\s]+)/g;
    return text.match(urlRegex) || [];
};

export const formatMentions = (text) => {
    if (!text) return '';
    return text.replace(/@(\w+)/g, '[@$1](mention://$1)');
};

export const formatEmojis = (text) => {
    if (!text) return '';
    return text.replace(/:([a-zA-Z0-9_]+):/g, (match, name) => {
        const emoji = AllEmojis.find(e => e.name === name);
        return emoji ? `![${match}](${emoji.src})` : match;
    });
};

export const parseAttachment = (content) => {
    if (!content || !content.startsWith('{')) return null;
    try {
        const parsed = JSON.parse(content);
        return parsed.type === 'attachment' ? parsed : null;
    } catch (e) {
        return null;
    }
};

export const parseSystemMessage = (content) => {
    if (!content || !content.startsWith('{')) return null;
    try {
        const parsed = JSON.parse(content);
        return parsed.type === 'system' ? parsed : null;
    } catch (e) {
        return null;
    }
};

const VIDEO_EXT_RE = /\.(mp4|webm|ogg|mov)(\?[^\s]*)?$/i;
const isVideoUrl = (url) => VIDEO_EXT_RE.test(url);

const getReactionIcon = (name) => {
    switch (name) {
        case 'thumbsup': return thumbsupIcon;
        case 'heart': return heartIcon;
        case 'fire': return fireIcon;
        default: return heartIcon;
    }
};

const ColoredIcon = ({ src, color, size = '24px', style = {} }) => (
    <div style={{ width: size, height: size, overflow: 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center', ...style }}>
        <img src={src} alt="" style={color ? { width: size, height: size, transform: 'translateX(-1000px)', filter: `drop-shadow(1000px 0 0 ${color})` } : { width: size, height: size, objectFit: 'contain' }} />
    </div>
);

const isNewDay = (current, previous) => {
    if (!previous) return true;
    return current.getDate() !== previous.getDate()
        || current.getMonth() !== previous.getMonth()
        || current.getFullYear() !== previous.getFullYear();
};

const markdownComponents = {
    a: ({ node, ...props }) => {
        if (props.href && props.href.startsWith('mention://')) return <span style={{ background: 'color-mix(in oklab,hsl(234.935 calc(1*85.556%) 64.706% /0.23921568627450981) 100%,hsl(0 0% 0% /0.23921568627450981) 0%)', borderRadius: '3px', color: 'color-mix(in oklab, hsl(228.14 calc(1*100%) 83.137% /1) 100%, #000 0%)', fontWeight: 500, padding: '0 2px', cursor: 'default' }} title={props.children}>{props.children}</span>;
        return <a {...props} onClick={(e) => { e.preventDefault(); window.cryptoAPI.openExternal(props.href); }} style={{ color: '#00b0f4', cursor: 'pointer', textDecoration: 'none' }} onMouseOver={(e) => e.target.style.textDecoration = 'underline'} onMouseOut={(e) => e.target.style.textDecoration = 'none'} />;
    },
    code({ node, inline, className, children, ...props }) {
        const match = /language-(\w+)/.exec(className || '');
        return !inline && match ? <SyntaxHighlighter style={oneDark} language={match[1]} PreTag="div" {...props}>{String(children).replace(/\n$/, '')}</SyntaxHighlighter> : <code className={className} {...props}>{children}</code>;
    },
    p: ({ node, ...props }) => <p style={{ margin: '0 0 6px 0' }} {...props} />,
    h1: ({ node, ...props }) => <h1 style={{ fontSize: '1.5rem', fontWeight: 700, margin: '12px 0 6px 0', lineHeight: 1.1 }} {...props} />,
    h2: ({ node, ...props }) => <h2 style={{ fontSize: '1.25rem', fontWeight: 700, margin: '10px 0 6px 0', lineHeight: 1.1 }} {...props} />,
    h3: ({ node, ...props }) => <h3 style={{ fontSize: '1.1rem', fontWeight: 700, margin: '8px 0 6px 0', lineHeight: 1.1 }} {...props} />,
    ul: ({ node, ...props }) => <ul style={{ margin: '0 0 6px 0', paddingLeft: '20px' }} {...props} />,
    ol: ({ node, ...props }) => <ol style={{ margin: '0 0 6px 0', paddingLeft: '20px' }} {...props} />,
    li: ({ node, ...props }) => <li style={{ margin: '0' }} {...props} />,
    hr: ({ node, ...props }) => <hr style={{ border: 'none', borderTop: '1px solid #4f545c', margin: '12px 0' }} {...props} />,
    img: ({ node, alt, src, ...props }) => {
        if (alt && alt.startsWith(':') && alt.endsWith(':')) {
            return <img src={src} alt={alt} style={{ width: '22px', height: '22px', verticalAlign: 'bottom', margin: '0 1px', display: 'inline' }} />;
        }
        return <img alt={alt} src={src} {...props} />;
    },
};

const IconButton = ({ onClick, emoji }) => (
    <div onClick={(e) => { e.stopPropagation(); onClick(e); }} className="icon-button" style={{ cursor: 'pointer', padding: '6px', fontSize: '16px', lineHeight: 1, color: 'var(--header-secondary)', transition: 'background-color 0.1s' }}>
        {emoji}
    </div>
);

const MessageToolbar = ({ onAddReaction, onEdit, onReply, onMore, isOwner }) => (
    <div className="message-toolbar">
        <Tooltip text="Thumbs Up" position="top">
            <IconButton onClick={() => onAddReaction('thumbsup')} emoji={<ColoredIcon src={thumbsupIcon} size="20px" />} />
        </Tooltip>
        <Tooltip text="Heart" position="top">
            <IconButton onClick={() => onAddReaction('heart')} emoji={<ColoredIcon src={heartIcon} size="20px" />} />
        </Tooltip>
        <Tooltip text="Fire" position="top">
            <IconButton onClick={() => onAddReaction('fire')} emoji={<ColoredIcon src={fireIcon} size="20px" />} />
        </Tooltip>
        <div style={{ width: '1px', height: '24px', margin: '2px 4px', backgroundColor: 'color-mix(in oklab,hsl(240 calc(1*4%) 60.784% /0.12156862745098039) 100%,hsl(0 0% 0% /0.12156862745098039) 0%)' }}></div>
        <Tooltip text="Add Reaction" position="top">
            <IconButton onClick={() => onAddReaction(null)} emoji={<ColoredIcon src={EmojieIcon} color={ICON_COLOR_DEFAULT} size="20px" />} />
        </Tooltip>
        {isOwner && (
            <Tooltip text="Edit" position="top">
                <IconButton onClick={onEdit} emoji={<ColoredIcon src={EditIcon} color={ICON_COLOR_DEFAULT} size="20px" />} />
            </Tooltip>
        )}
        <Tooltip text="Reply" position="top">
            <IconButton onClick={onReply} emoji={<ColoredIcon src={ReplyIcon} color={ICON_COLOR_DEFAULT} size="20px" />} />
        </Tooltip>
        <Tooltip text="More" position="top">
            <IconButton onClick={onMore} emoji={<ColoredIcon src={MoreIcon} color={ICON_COLOR_DEFAULT} size="20px" />} />
        </Tooltip>
    </div>
);

const MessageItem = React.memo(({
    msg,
    isGrouped,
    showDateDivider,
    showUnreadDivider,
    dateLabel,
    isMentioned,
    isOwner,
    isEditing,
    isHovered,
    editInput,
    username,
    onHover,
    onLeave,
    onContextMenu,
    onAddReaction,
    onEdit,
    onReply,
    onMore,
    onEditInputChange,
    onEditKeyDown,
    onEditSave,
    onEditCancel,
    onReactionClick,
    onScrollToMessage,
    onProfilePopup,
    onImageClick,
    scrollToBottom,
    Attachment,
    LinkPreview,
    DirectVideo,
}) => {
    const currentDate = new Date(msg.created_at);
    const userColor = getUserColor(msg.username || 'Unknown');

    const renderMessageContent = () => {
        const systemMsg = parseSystemMessage(msg.content);
        if (systemMsg) {
            return (
                <div className="system-message">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="#3ba55c" style={{ marginRight: '8px', flexShrink: 0 }}>
                        <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
                    </svg>
                    <span style={{ fontStyle: 'italic', color: 'var(--header-secondary)' }}>{systemMsg.text || 'System event'}</span>
                </div>
            );
        }

        const attachmentMetadata = parseAttachment(msg.content);
        if (attachmentMetadata) {
            return <Attachment metadata={attachmentMetadata} onLoad={scrollToBottom} onImageClick={onImageClick} />;
        }

        const urls = extractUrls(msg.content);
        const isOnlyUrl = urls.length === 1 && msg.content.trim() === urls[0];
        const isGif = isOnlyUrl && (urls[0].includes('tenor.com') || urls[0].includes('giphy.com') || urls[0].endsWith('.gif'));
        const isDirectVideo = isOnlyUrl && isVideoUrl(urls[0]);

        return (
            <>
                {!isGif && !isDirectVideo && (
                    <ReactMarkdown remarkPlugins={[remarkGfm]} urlTransform={(url) => url} components={markdownComponents}>
                        {formatEmojis(formatMentions(msg.content))}
                    </ReactMarkdown>
                )}
                {isDirectVideo && <DirectVideo src={urls[0]} marginTop={4} />}
                {urls.filter(u => !(isDirectVideo && u === urls[0])).map((url, i) => (
                    <LinkPreview key={i} url={url} />
                ))}
            </>
        );
    };

    const renderReactions = () => {
        if (!msg.reactions || Object.keys(msg.reactions).length === 0) return null;
        return (
            <div style={{ display: 'flex', gap: '4px', marginTop: '4px', flexWrap: 'wrap' }}>
                {Object.entries(msg.reactions).map(([emojiName, data]) => (
                    <div key={emojiName} onClick={() => onReactionClick(msg.id, emojiName, data.me)} style={{ display: 'flex', alignItems: 'center', backgroundColor: data.me ? 'rgba(88, 101, 242, 0.15)' : 'var(--embed-background)', border: data.me ? '1px solid var(--brand-experiment)' : '1px solid transparent', borderRadius: '8px', padding: '2px 6px', cursor: 'pointer', gap: '4px' }}>
                        <ColoredIcon src={getReactionIcon(emojiName)} size="16px" color={data.me ? null : 'var(--header-secondary)'} />
                        <span style={{ fontSize: '12px', color: data.me ? '#dee0fc' : 'var(--header-secondary)', fontWeight: 600 }}>{data.count}</span>
                    </div>
                ))}
            </div>
        );
    };

    return (
        <React.Fragment>
            {showUnreadDivider && (
                <div className="unread-divider" role="separator">
                    <span className="unread-pill">
                        <svg className="unread-pill-cap" width="8" height="13" viewBox="0 0 8 13">
                            <path stroke="currentColor" fill="transparent" d="M8.16639 0.5H9C10.933 0.5 12.5 2.067 12.5 4V9C12.5 10.933 10.933 12.5 9 12.5H8.16639C7.23921 12.5 6.34992 12.1321 5.69373 11.4771L0.707739 6.5L5.69373 1.52292C6.34992 0.86789 7.23921 0.5 8.16639 0.5Z" />
                        </svg>
                        NEW
                    </span>
                </div>
            )}
            {showDateDivider && <div className="date-divider"><span>{dateLabel}</span></div>}
            <div
                id={`msg-${msg.id}`}
                className={`message-item${isGrouped ? ' message-grouped' : ''}`}
                style={isMentioned ? { background: 'color-mix(in oklab,hsl(36.894 calc(1*100%) 31.569% /0.0784313725490196) 100%,hsl(0 0% 0% /0.0784313725490196) 0%)', position: 'relative' } : { position: 'relative' }}
                onMouseEnter={onHover}
                onMouseLeave={onLeave}
                onContextMenu={onContextMenu}
            >
                {isMentioned && <div style={{ background: 'color-mix(in oklab, hsl(34 calc(1*50.847%) 53.725% /1) 100%, #000 0%)', bottom: 0, display: 'block', left: 0, pointerEvents: 'none', position: 'absolute', top: 0, width: '2px' }} />}

                {msg.replyToId && msg.replyToUsername && (
                    <div className="message-reply-context" onClick={() => onScrollToMessage(msg.replyToId)}>
                        <div className="reply-spine" />
                        <Avatar username={msg.replyToUsername} avatarUrl={msg.replyToAvatarUrl} size={16} className="reply-avatar" />
                        <span className="reply-author" style={{ color: getUserColor(msg.replyToUsername) }}>
                            @{msg.replyToUsername}
                        </span>
                        <span className="reply-text">{msg.decryptedReply || '[Encrypted]'}</span>
                    </div>
                )}

                {isGrouped ? (
                    <div className="message-avatar-wrapper">
                    </div>
                ) : (
                    <div className="message-avatar-wrapper">
                        <Avatar
                            username={msg.username}
                            avatarUrl={msg.avatarUrl}
                            size={40}
                            className="message-avatar"
                            style={{ cursor: 'pointer' }}
                            onClick={(e) => onProfilePopup(e, msg)}
                        />
                    </div>
                )}
                <div className="message-body">
                    {!isGrouped && (
                        <div className="message-header">
                            <span
                                className="username"
                                style={{ color: userColor, cursor: 'pointer' }}
                                onClick={(e) => onProfilePopup(e, msg)}
                            >
                                {msg.username || 'Unknown'}
                            </span>
                            {!msg.isVerified && <span className="verification-failed" title="Signature Verification Failed!"><svg aria-hidden="true" role="img" width="16" height="16" viewBox="0 0 24 24" fill="var(--danger)"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"></path></svg></span>}
                            <span className="timestamp">{currentDate.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })}</span>
                        </div>
                    )}
                    <div style={{ position: 'relative' }}>
                        {isEditing ? (
                            <div className="message-editing">
                                <textarea
                                    className="message-edit-textarea"
                                    value={editInput}
                                    onChange={onEditInputChange}
                                    onKeyDown={onEditKeyDown}
                                    autoFocus
                                />
                                <div className="message-edit-hint">
                                    escape to <span onClick={onEditCancel}>cancel</span> · enter to <span onClick={onEditSave}>save</span>
                                </div>
                            </div>
                        ) : (
                            <div className="message-content">
                                {renderMessageContent()}
                                {msg.editedAt && <span className="edited-indicator">(edited)</span>}
                                {renderReactions()}
                            </div>
                        )}
                        {isHovered && !isEditing && (
                            <MessageToolbar isOwner={isOwner}
                                onAddReaction={onAddReaction}
                                onEdit={onEdit}
                                onReply={onReply}
                                onMore={onMore}
                            />
                        )}
                    </div>
                </div>
            </div>
        </React.Fragment>
    );
}, (prevProps, nextProps) => {
    return (
        prevProps.msg.id === nextProps.msg.id &&
        prevProps.msg.content === nextProps.msg.content &&
        prevProps.msg.editedAt === nextProps.msg.editedAt &&
        prevProps.msg.reactions === nextProps.msg.reactions &&
        prevProps.msg.decryptedReply === nextProps.msg.decryptedReply &&
        prevProps.msg.isVerified === nextProps.msg.isVerified &&
        prevProps.isHovered === nextProps.isHovered &&
        prevProps.isEditing === nextProps.isEditing &&
        prevProps.editInput === nextProps.editInput &&
        prevProps.isGrouped === nextProps.isGrouped &&
        prevProps.showDateDivider === nextProps.showDateDivider &&
        prevProps.showUnreadDivider === nextProps.showUnreadDivider &&
        prevProps.isMentioned === nextProps.isMentioned
    );
});

MessageItem.displayName = 'MessageItem';

export default MessageItem;
