/**
 * Chat input — layout from Discord, colors from Google AI Studio / Linear.
 *
 * Layout: Discord — icon toolbar left, send right, compact input
 * Colors: Clean modern palette, no Discord reference
 */

import {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
import {EditorContent, Extension, useEditor} from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import Placeholder from '@tiptap/extension-placeholder';
import {CustomEmojiNode} from './EmojiNode';
import {MentionNodeType} from './MentionNode';
import type {EditorNode, MentionItem, MentionType, MessageAST} from './types';
import {Paperclip, Send, Smile, X} from 'lucide-react';
import {cn} from '@/lib/utils';
import {COMMON_EMOJIS} from '../../shared';
import {useTheme} from '@/contexts';
import {useImageCompress} from '@/hooks/useImageCompress';

export interface IMEditorProps {
    replyingTo?: { id: string; display_name?: string; content: string } | null;
    onCancelReply?: () => void;
    onSend: (content: string, ast: MessageAST) => void;
    mentionItems: {
        users: MentionItem[];
        channels: MentionItem[];
        ai: MentionItem[];
        repos: MentionItem[];
        commands: MentionItem[];
        specialMentions?: MentionItem[];
    };
    onUploadFile?: (file: File) => Promise<{ id: string; url: string }>;
    placeholder?: string;
    /** Called whenever the editor content changes (on every keystroke) */
    onUpdate?: (text: string) => void;
}

export interface IMEditorHandle {
    focus: () => void;
    clearContent: () => void;
    getContent: () => string;
    insertMention: (type: string, id: string, label: string) => void;
    getAttachmentIds: () => string[];
}

// ─── Color System (Google AI Studio / Linear palette, no Discord) ────────────

const LIGHT = {
    bg: '#ffffff',
    bgHover: '#f7f7f8',
    bgActive: '#ececf1',
    border: '#e3e3e5',
    borderFocus: '#1c7ded',
    text: '#1f1f1f',
    textMuted: '#8a8a8e',
    textSubtle: '#b0b0b4',
    icon: '#8a8a8e',
    iconHover: '#5c5c60',
    sendBg: '#1c7ded',
    sendBgHover: '#1a73d4',
    sendIcon: '#ffffff',
    sendDisabled: '#e3e3e5',
    popupBg: '#ffffff',
    popupBorder: '#e3e3e5',
    popupHover: '#f5f5f7',
    popupSelected: '#e8f0fe',
    replyBg: '#f5f5f7',
    badgeAi: '#dbeafe text-blue-700',
    badgeChan: '#f3f4f6 text-gray-500',
    badgeCmd: '#fef3c7 text-amber-700',
};

const DARK = {
    bg: '#1a1a1e',
    bgHover: '#222226',
    bgActive: '#2a2a2f',
    border: '#2e2e33',
    borderFocus: '#4a9eff',
    text: '#ececf1',
    textMuted: '#8a8a91',
    textSubtle: '#5c5c63',
    icon: '#7a7a82',
    iconHover: '#b0b0b8',
    sendBg: '#4a9eff',
    sendBgHover: '#6aafff',
    sendIcon: '#ffffff',
    sendDisabled: '#2e2e33',
    popupBg: '#222226',
    popupBorder: '#2e2e33',
    popupHover: '#2a2a30',
    popupSelected: '#2a3a55',
    replyBg: '#1f1f23',
    badgeAi: 'bg-blue-900/40 text-blue-300',
    badgeChan: 'bg-gray-800 text-gray-400',
    badgeCmd: 'bg-amber-900/30 text-amber-300',
};

type Palette = typeof LIGHT;

// ─── Emoji Picker ─────────────────────────────────────────────────────────────

function EmojiPicker({onClose, onSelect, p}: { onClose: () => void; onSelect: (emoji: string) => void; p: Palette }) {
    return (
        <div
            className="absolute bottom-full left-0 mb-2 z-50"
            style={{
                background: p.popupBg,
                border: `1px solid ${p.popupBorder}`,
                borderRadius: 12,
                boxShadow: p === DARK
                    ? '0 8px 32px rgba(0,0,0,0.6)'
                    : '0 8px 32px rgba(0,0,0,0.10)',
            }}
        >
            <div
                className="flex items-center justify-between px-3 pt-3 pb-2"
                style={{borderBottom: `1px solid ${p.popupBorder}`}}
            >
        <span className="text-[11px] font-semibold tracking-wide uppercase" style={{color: p.textMuted}}>
          Emoji
        </span>
                <button onClick={onClose}
                        className="flex items-center justify-center w-5 h-5 rounded cursor-pointer transition-colors"
                        style={{color: p.icon}}>
                    <X size={11}/>
                </button>
            </div>
            <div className="grid p-2 gap-0.5" style={{gridTemplateColumns: 'repeat(6, 1fr)'}}>
                {COMMON_EMOJIS.map(emoji => (
                    <button
                        key={emoji}
                        onClick={() => onSelect(emoji)}
                        className="w-9 h-9 flex items-center justify-center rounded-lg transition-all duration-100 cursor-pointer hover:scale-110 text-[18px]"
                        style={{background: 'transparent'}}
                    >
                        {emoji}
                    </button>
                ))}
            </div>
        </div>
    );
}

// ─── Helpers ─────────────────────────────────────────────────────────────────

function filterMentionItems(all: MentionItem[], q: string): MentionItem[] {
    return all.filter(m => m.label.toLowerCase().includes(q.toLowerCase())).slice(0, 8);
}

function getBadge(type: MentionType): { label: string; cls: string } | null {
    if (type === 'ai') return {label: 'AI', cls: 'bg-blue-50 text-blue-600'};
    if (type === 'channel') return {label: '#', cls: 'bg-gray-100 text-gray-500'};
    if (type === 'command') return {label: 'cmd', cls: 'bg-amber-50 text-amber-600'};
    if (type === 'repo') return {label: 'repo', cls: 'bg-green-50 text-green-600'};
    return null;
}

/** Serialize tiptap AST to backend-parseable string. */
function serializeAstForSend(ast: MessageAST): string {
    return ast.content.map(serializeAstNode).join('\n');
}

function serializeAstNode(node: EditorNode): string {
    if (node.type === 'text') return node.text;
    if (node.type === 'mention') return `@[${node.attrs.type}:${node.attrs.id}:${node.attrs.label}]`;
    if (node.type === 'hardBreak') return '\n';
    if (node.type === 'emoji') return `[emoji:${node.attrs.name}]`;
    if (node.type === 'file') return '';
    // Recurse into container nodes (paragraph, bulletList, etc.)
    const children = (node as any).content as EditorNode[] | undefined;
    if (children) return children.map(serializeAstNode).join('');
    return '';
}

// ─── Mention Dropdown (sectioned by type) ────────────────────────────────────

const SECTION_ORDER = ['special_here', 'special_channel', 'ai', 'user', 'repo', 'channel', 'command'] as const;
const SECTION_LABELS: Record<string, string> = {
    special_here: 'Notify',
    special_channel: 'Notify',
    ai: 'AI',
    user: 'Members',
    repo: 'Repositories',
    channel: 'Channels',
    command: 'Commands',
};
const SPECIAL_TYPES = ['special_here', 'special_channel'];

function MentionDropdown({
    items, selectedIndex, onSelect, p, query,
}: {
    items: MentionItem[];
    selectedIndex: number;
    onSelect: (item: MentionItem) => void;
    p: Palette;
    query: string;
}) {
    const scrollRef = useRef<HTMLDivElement>(null);

    // Auto-scroll selected item into view
    useEffect(() => {
        if (!scrollRef.current) return;
        const selectedEl = scrollRef.current.querySelector(`[data-mention-idx="${selectedIndex}"]`);
        if (selectedEl) {
            selectedEl.scrollIntoView({ block: 'nearest' });
        }
    }, [selectedIndex]);
    // Group items by section
    const sections: Map<string, MentionItem[]> = new Map();
    for (const sectionType of SECTION_ORDER) {
        const sectionItems = items.filter(
            (item) => sectionType === 'special_here' || sectionType === 'special_channel'
                ? item.type === sectionType
                : SPECIAL_TYPES.includes(sectionType)
                    ? false
                    : item.type === sectionType,
        );
        if (sectionItems.length > 0) {
            sections.set(sectionType, sectionItems);
        }
    }

    // Build flat index map: item → its position in the overall items array
    const flatIndexMap = new Map<MentionItem, number>();
    items.forEach((item, i) => flatIndexMap.set(item, i));

    return (
        <div
            className="absolute bottom-full left-0 mb-1 z-50 overflow-hidden"
            style={{
                background: p.popupBg,
                border: `1px solid ${p.popupBorder}`,
                borderRadius: 10,
                boxShadow: p === DARK ? '0 12px 40px rgba(0,0,0,0.55)' : '0 8px 30px rgba(0,0,0,0.09)',
                minWidth: 240,
                maxWidth: 300,
            }}
        >
            {items.length === 0 ? (
                <div className="px-4 py-5 text-sm text-center" style={{color: p.textMuted}}>
                    No results for &ldquo;{query}&rdquo;
                </div>
            ) : (
                <div className="py-1 max-h-60 overflow-y-auto" ref={scrollRef}>
                    {Array.from(sections.entries()).map(([sectionType, sectionItems], si) => (
                        <div key={sectionType}>
                            {/* Section header — only show if there are other sections after or before */}
                            {sections.size > 1 && (
                                <div className="px-3 py-1 text-[10px] font-semibold uppercase tracking-wide" style={{color: p.textSubtle}}>
                                    {SECTION_LABELS[sectionType]}
                                </div>
                            )}
                            {sectionItems.map((item) => {
                                const realIndex = flatIndexMap.get(item) ?? 0;
                                const isSpecial = SPECIAL_TYPES.includes(item.type);
                                const icon = item.type === 'special_here' ? '📍' : item.type === 'special_channel' ? '📢' : undefined;

                                if (isSpecial) {
                                    return (
                                        <button
                                            key={item.id}
                                            data-mention-idx={realIndex}
                                            onClick={() => onSelect(item)}
                                            className="w-full flex items-center gap-3 px-3 py-2.5 transition-colors text-left cursor-pointer"
                                            style={{background: realIndex === selectedIndex ? p.popupSelected : 'transparent'}}
                                        >
                                            <span className="w-7 h-7 rounded-full shrink-0 flex items-center justify-center text-base">
                                                {icon}
                                            </span>
                                            <span className="flex-1 truncate text-sm font-medium" style={{color: p.text}}>
                                                @{item.label}
                                            </span>
                                            {item.description && (
                                                <span className="text-[10px] text-muted-foreground mr-1">
                                                    {item.description}
                                                </span>
                                            )}
                                        </button>
                                    );
                                }

                                const badge = getBadge(item.type);
                                return (
                                    <button
                                        key={item.id}
                                        data-mention-idx={realIndex}
                                        onClick={() => onSelect(item)}
                                        className="w-full flex items-center gap-3 px-3 py-2.5 transition-colors text-left cursor-pointer"
                                        style={{background: realIndex === selectedIndex ? p.popupSelected : 'transparent'}}
                                    >
                                        {item.avatar ? (
                                            <img src={item.avatar} alt={item.label} className="w-7 h-7 rounded-full shrink-0"/>
                                        ) : (
                                            <span
                                                className="w-7 h-7 rounded-full shrink-0 flex items-center justify-center text-xs font-semibold"
                                                style={{background: p === DARK ? '#2a2a30' : '#eeeef0', color: p.text}}
                                            >
                                                {item.label.charAt(0).toUpperCase()}
                                            </span>
                                        )}
                                        <span className="flex-1 truncate text-sm font-medium" style={{color: p.text}}>
                                            {item.label}
                                        </span>
                                        {badge && (
                                            <span
                                                className={cn('shrink-0 text-[10px] font-bold px-1.5 py-0.5 rounded-full', badge.cls)}>
                                                {badge.label}
                                            </span>
                                        )}
                                    </button>
                                );
                            })}
                            {/* Divider between sections */}
                            {si < sections.size - 1 && (
                                <div className="mx-3 my-1 border-t border-border" />
                            )}
                        </div>
                    ))}
                </div>
            )}
        </div>
    );
}

// ─── Main Component ────────────────────────────────────────────────────────────

export const IMEditor = forwardRef<IMEditorHandle, IMEditorProps>(function IMEditor(
    {replyingTo, onCancelReply, onSend, mentionItems, onUploadFile, placeholder = 'Message…', onUpdate},
    ref,
) {
    const {resolvedTheme} = useTheme();
    const p = resolvedTheme === 'dark' ? DARK : LIGHT;
    const {compress} = useImageCompress();

    const [showEmoji, setShowEmoji] = useState(false);
    const [mentionOpen, setMentionOpen] = useState(false);
    const [mentionQuery, setMentionQuery] = useState('');
    const [mentionItems2, setMentionItems2] = useState<MentionItem[]>([]);
    const [mentionIdx, setMentionIdx] = useState(0);
    const [, setMentionPos] = useState({top: 0, left: 0});
    const [focused, setFocused] = useState(false);

    // Refs for keyboard shortcut closures (tiptap can't read React state directly)
    const mentionOpenRef = useRef(false);
    const mentionIdxRef = useRef(0);
    const mentionItemsRef = useRef<MentionItem[]>([]);
    const editorRef = useRef<ReturnType<typeof useEditor>>(null);

    // Sync refs with state
    useEffect(() => { mentionOpenRef.current = mentionOpen; }, [mentionOpen]);
    useEffect(() => { mentionIdxRef.current = mentionIdx; }, [mentionIdx]);
    useEffect(() => { mentionItemsRef.current = mentionItems2; }, [mentionItems2]);

    const wrapRef = useRef<HTMLDivElement>(null);

    // Candidate pools by trigger character
    const atPool = useMemo(() => [
        ...(mentionItems.specialMentions ?? []),
        ...mentionItems.ai,
        ...mentionItems.users,
        ...mentionItems.repos,
    ], [mentionItems.specialMentions, mentionItems.ai, mentionItems.users, mentionItems.repos]);

    const hashPool = useMemo(() => [...mentionItems.channels], [mentionItems.channels]);

    const slashPool = useMemo(() => [...mentionItems.commands], [mentionItems.commands]);

    const selectMention = useCallback((item: MentionItem) => {
        const editor = editorRef.current;
        if (!editor) return;

        // Delete the trigger + query text first, then insert the mention node
        const text = editor.getText();
        const {from} = editor.state.selection;
        let triggerStart = from;
        for (let i = from - 1; i >= 1; i--) {
            const c = text[i - 1];
            if (c === '@' || c === '#' || c === '/') {
                triggerStart = i;
                break;
            }
            if (/\s/.test(c)) break;
        }

        // Delete from triggerStart-1 to from (the @query / #query / /query text)
        if (triggerStart < from) {
            editor.chain().focus().deleteRange({from: triggerStart - 1, to: from}).run();
        }

        // Insert mention node
        editor.chain().focus().insertContent({
            type: 'mention',
            attrs: { id: item.id, label: item.label, type: item.type },
        }).insertContent(' ').run();

        setMentionOpen(false);
    }, []);

    const moveMentionIdx = useCallback((delta: number) => {
        const len = mentionItemsRef.current.length;
        if (len === 0) return;
        const next = (mentionIdxRef.current + delta + len) % len;
        setMentionIdx(next);
    }, []);

    const selectCurrentMention = useCallback(() => {
        const items = mentionItemsRef.current;
        const idx = mentionIdxRef.current;
        if (items[idx]) {
            selectMention(items[idx]);
        }
    }, [selectMention]);

    const closeMention = useCallback(() => {
        setMentionOpen(false);
    }, []);

    const editor = useEditor({
        extensions: [
            StarterKit.configure({undoRedo: {depth: 100}}),
            Placeholder.configure({placeholder}),
            CustomEmojiNode,
            MentionNodeType,
            Extension.create({
                name: 'mentionKeyboard',
                addKeyboardShortcuts() {
                    return {
                        Enter: () => {
                            if (mentionOpenRef.current) {
                                selectCurrentMention();
                                return true;
                            }
                            const ed = editorRef.current;
                            if (!ed) return true;
                            const ast = ed.getJSON() as MessageAST;
                            const serialized = serializeAstForSend(ast);
                            if (!serialized.trim()) return true;
                            (ed.storage as any).mentionKeyboard?.onSend?.(serialized, ast);
                            return true;
                        },
                        'Shift-Enter': ({editor: ed}) => {
                            ed.chain().focus().setHardBreak().run();
                            return true;
                        },
                        ArrowUp: () => {
                            if (mentionOpenRef.current) {
                                moveMentionIdx(-1);
                                return true;
                            }
                            return false;
                        },
                        ArrowDown: () => {
                            if (mentionOpenRef.current) {
                                moveMentionIdx(1);
                                return true;
                            }
                            return false;
                        },
                        Escape: () => {
                            if (mentionOpenRef.current) {
                                closeMention();
                                return true;
                            }
                            return false;
                        },
                        Tab: () => {
                            if (mentionOpenRef.current) {
                                selectCurrentMention();
                                return true;
                            }
                            return false;
                        },
                    };
                },
                addStorage() {
                    return {onSend: null as ((t: string, a: MessageAST) => void) | null};
                },
            }),
        ],
        editorProps: {
            handlePaste: (_v, e) => {
                const img = Array.from(e.clipboardData?.items ?? []).find(i => i.type.startsWith('image'));
                if (img) {
                    e.preventDefault();
                    const file = img.getAsFile();
                    if (file && onUploadFile) void doUpload(file);
                    return true;
                }
                return false;
            },
            handleDrop: (_v, e) => {
                if (e.dataTransfer?.files?.[0] && onUploadFile) {
                    e.preventDefault();
                    void doUpload(e.dataTransfer.files[0]);
                    return true;
                }
                return false;
            },
        },
        onUpdate: ({editor: ed}) => {
            const text = ed.getText();
            const {from} = ed.state.selection;

            // Backward scan from cursor to find trigger character
            let ts = from;
            let trigger: string | null = null;
            for (let i = from - 1; i >= 1; i--) {
                const c = text[i - 1];
                if (c === '@' || c === '#' || c === '/') {
                    ts = i;
                    trigger = c;
                    break;
                }
                if (/\s/.test(c)) break;
            }

            const q = text.slice(ts - 1, from);

            if (trigger === '@' && q.length >= 1) {
                const results = filterMentionItems(atPool, q.slice(1));
                setMentionQuery(q.slice(1));
                setMentionItems2(results);
                setMentionIdx(0);
                setMentionOpen(results.length > 0);

                if (wrapRef.current) {
                    const sel = window.getSelection();
                    if (sel?.rangeCount) {
                        const r = sel.getRangeAt(0).getBoundingClientRect();
                        const cr = wrapRef.current.getBoundingClientRect();
                        setMentionPos({top: r.bottom - cr.top + 6, left: Math.max(0, r.left - cr.left)});
                    }
                }
            } else if (trigger === '#' && q.length >= 1) {
                const results = filterMentionItems(hashPool, q.slice(1));
                setMentionQuery(q.slice(1));
                setMentionItems2(results);
                setMentionIdx(0);
                setMentionOpen(results.length > 0);

                if (wrapRef.current) {
                    const sel = window.getSelection();
                    if (sel?.rangeCount) {
                        const r = sel.getRangeAt(0).getBoundingClientRect();
                        const cr = wrapRef.current.getBoundingClientRect();
                        setMentionPos({top: r.bottom - cr.top + 6, left: Math.max(0, r.left - cr.left)});
                    }
                }
            } else if (trigger === '/' && q.length >= 1) {
                const results = filterMentionItems(slashPool, q.slice(1));
                setMentionQuery(q.slice(1));
                setMentionItems2(results);
                setMentionIdx(0);
                setMentionOpen(results.length > 0);

                if (wrapRef.current) {
                    const sel = window.getSelection();
                    if (sel?.rangeCount) {
                        const r = sel.getRangeAt(0).getBoundingClientRect();
                        const cr = wrapRef.current.getBoundingClientRect();
                        setMentionPos({top: r.bottom - cr.top + 6, left: Math.max(0, r.left - cr.left)});
                    }
                }
            } else {
                setMentionOpen(false);
            }
            onUpdate?.(text);
        },
        onFocus: () => setFocused(true),
        onBlur: () => setFocused(false),
    });

    // Store editor ref
    useEffect(() => {
        editorRef.current = editor;
    }, [editor]);

    useEffect(() => {
        if (editor) (editor.storage as any).mentionKeyboard = {onSend};
    }, [editor, onSend]);

    const doUpload = async (file: File) => {
        if (!editor || !onUploadFile) return;
        try {
            // Compress image before upload (only if it's an image and > 500KB)
            let uploadFile = file;
            if (file.type.startsWith('image/') && file.size > 500 * 1024) {
                const result = await compress(file, {maxSizeMB: 1, maxWidthOrHeight: 1920, useWebWorker: true});
                uploadFile = result.file;
            }
            const res = await onUploadFile(uploadFile);
            editor.chain().focus().insertContent({
                type: 'file',
                attrs: {
                    id: res.id,
                    name: uploadFile.name,
                    url: res.url,
                    size: uploadFile.size,
                    type: uploadFile.type,
                    status: 'done'
                }
            }).insertContent(' ').run();
        } catch (err) {
            console.warn('[IMEditor] Upload failed:', err);
        }
    };

    const send = () => {
        if (!editor) return;
        const ast = editor.getJSON() as MessageAST;
        const serialized = serializeAstForSend(ast);
        if (!serialized.trim()) return;
        onSend(serialized, ast);
        editor.commands.clearContent();
    };

    const hasContent = !!editor && editor.state.doc.content.size > 2;

    useImperativeHandle(ref, () => ({
        focus: () => editor?.commands.focus(),
        clearContent: () => editor?.commands.clearContent(),
        getContent: () => editor?.getText() ?? '',
        insertMention: (type: string, id: string, label: string) => {
            if (!editor) return;
            editor.chain().focus().insertContent({
                type: 'mention',
                attrs: { id, label, type },
            }).insertContent(' ').run();
        },
        getAttachmentIds: () => {
            if (!editor) return [];
            const json = editor.getJSON();
            const ids: string[] = [];
            const walk = (node: Record<string, unknown>) => {
                if (node['type'] === 'file' && node['attrs']) {
                    const attrs = node['attrs'] as Record<string, unknown>;
                    if (attrs['id']) ids.push(String(attrs['id']));
                }
                const children = node['content'] as Record<string, unknown>[] | undefined;
                if (children) children.forEach(walk);
            };
            walk(json as Record<string, unknown>);
            return ids;
        },
    }));

    
    // Dynamic styles
    const borderColor = focused ? p.borderFocus : p.border;
    const boxShadow = focused
        ? (p === DARK ? `0 0 0 3px rgba(74,158,255,0.18)` : `0 0 0 3px rgba(28,125,237,0.12)`)
        : 'none';

    return (
        <div className="relative flex flex-col mt-2 ml-3 mr-3 mb-1" ref={wrapRef}>
            {replyingTo && (
                <div
                    className="flex items-center gap-3 px-4 py-2.5"
                    style={{
                        background: p.replyBg,
                        borderRadius: '12px 12px 0 0',
                        borderBottom: `1px solid ${p.border}`
                    }}
                >
                    <div className="flex-1 min-w-0 flex items-center gap-2">
                        <span className="text-[11px] font-semibold shrink-0"
                              style={{color: p.borderFocus}}>Replying to</span>
                        <span className="truncate text-sm font-medium"
                              style={{color: p.text}}>{replyingTo.display_name}</span>
                        <span className="truncate shrink-1 text-sm"
                              style={{color: p.textMuted}}>— {replyingTo.content}</span>
                    </div>
                    {onCancelReply && (
                        <button onClick={onCancelReply}
                                className="flex items-center justify-center w-6 h-6 rounded-full cursor-pointer shrink-0 transition-colors"
                                style={{color: p.icon}}>
                            <X size={13}/>
                        </button>
                    )}
                </div>
            )}

            {/* Input area */}
            <div
                className="relative"
                onClick={() => editor?.commands.focus()}
                style={{
                    background: p.bg,
                    border: `1.5px solid ${borderColor}`,
                    borderRadius: replyingTo ? '0 0 14px 14px' : '14px',
                    boxShadow,
                    transition: 'border-color 160ms ease, box-shadow 160ms ease',
                }}
            >
                {/* Mention dropdown */}
                {mentionOpen && (
                    <MentionDropdown
                        items={mentionItems2}
                        selectedIndex={mentionIdx}
                        onSelect={selectMention}
                        p={p}
                        query={mentionQuery}
                    />
                )}

                {/* Editor */}
                <div
                    className="ai-editor"
                    style={{padding: '12px 14px 10px'}}
                >
                    <EditorContent editor={editor}/>
                </div>

                {/* Discord-style toolbar: icons left, send right */}
                <div className="flex items-center justify-between px-2 pb-2">
                    {/* Left — emoji + attach */}
                    <div className="flex items-center gap-0.5">
                        <div className="relative">
                            <button
                                onClick={(e) => {
                                    e.stopPropagation();
                                    setShowEmoji(v => !v);
                                }}
                                className="flex items-center justify-center w-8 h-8 rounded-lg transition-colors cursor-pointer"
                                style={{
                                    color: showEmoji ? p.iconHover : p.icon,
                                    background: showEmoji ? p.bgActive : 'transparent'
                                }}
                                title="Emoji"
                            >
                                <Smile size={18}/>
                            </button>
                            {showEmoji && <EmojiPicker onClose={() => setShowEmoji(false)} onSelect={(emoji) => {
                                editor?.chain().focus().insertContent(emoji).insertContent(' ').run();
                                setShowEmoji(false);
                            }} p={p}/>}
                        </div>

                        <label
                            className="flex items-center justify-center w-8 h-8 rounded-lg transition-colors cursor-pointer"
                            style={{color: p.icon}}
                            title="Attach file"
                        >
                            <Paperclip size={18}/>
                            <input type="file" className="hidden" onChange={e => {
                                e.stopPropagation();
                                const f = e.target.files?.[0];
                                if (f && onUploadFile) void doUpload(f);
                                e.target.value = '';
                            }}/>
                        </label>
                    </div>

                    {/* Right — hint + send */}
                    <div className="flex items-center gap-2.5">
                        <span className="text-[11px]" style={{color: p.textSubtle}}>↵ send</span>
                        <button
                            onClick={(e) => {
                                e.stopPropagation();
                                send();
                            }}
                            disabled={!hasContent}
                            className="flex items-center justify-center w-8 h-8 rounded-full transition-all duration-150 cursor-pointer"
                            style={{
                                background: hasContent ? p.sendBg : p.sendDisabled,
                                color: hasContent ? p.sendIcon : p.icon,
                                opacity: hasContent ? 1 : 0.55,
                                transform: hasContent ? 'scale(1)' : 'scale(0.92)',
                            }}
                            title="Send"
                        >
                            <Send size={13}/>
                        </button>
                    </div>
                </div>
            </div>

            <style>{`
        .ai-editor .ProseMirror {
          outline: none;
          white-space: pre-wrap;
          word-break: break-word;
          min-height: 22px;
          font-size: 15px;
          line-height: 1.6;
        }
        .ai-editor .ProseMirror p { margin: 0; }
        .ai-editor .ProseMirror p.is-editor-empty:first-child::before {
          color: hsl(220 9% 60%);
          content: attr(data-placeholder);
          float: left;
          height: 0;
          pointer-events: none;
        }
        .ai-editor .ProseMirror::-webkit-scrollbar { display: none; }
      `}</style>
        </div>
    );
});

IMEditor.displayName = 'IMEditor';