import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import { Editor, EditorContent, useEditor } from '@tiptap/react';
import { StarterKit } from '@tiptap/starter-kit';
import { Table } from '@tiptap/extension-table';
import { TableCell } from '@tiptap/extension-table-cell';
import { TableHeader } from '@tiptap/extension-table-header';
import { TableRow } from '@tiptap/extension-table-row';
import { TextAlign } from '@tiptap/extension-text-align';
import { Underline } from '@tiptap/extension-underline';
import { Placeholder } from '@tiptap/extension-placeholder';
import { normalizeSignatureSlots } from './normalize-slots';
import { SignatureSlot } from './signature-slot-extension';
import {
    AlignCenter,
    AlignLeft,
    AlignRight,
    Bold,
    Heading1,
    Heading2,
    Heading3,
    Italic,
    List,
    ListOrdered,
    PencilLine,
    Redo2,
    Stamp,
    Table as TableIcon,
    Trash2,
    Underline as UnderlineIcon,
    Undo2,
} from 'lucide-react';
import * as React from 'react';

interface DocumentEditorProps {
    value: string;
    onChange: (html: string) => void;
    placeholder?: string;
    editable?: boolean;
    className?: string;
    /** Pre-existing TLL (sender) signature URL — rendered inline in the slot. */
    senderSignatureUrl?: string | null;
    /** TLL cachet URL — hardcoded by the server but rendered alongside the sig. */
    senderStampUrl?: string | null;
}

export function DocumentEditor({
    value,
    onChange,
    placeholder = 'Commencez à rédiger le document…',
    editable = true,
    className,
    senderSignatureUrl = null,
    senderStampUrl = null,
}: DocumentEditorProps) {
    const editor = useEditor({
        extensions: [
            StarterKit,
            Underline,
            TextAlign.configure({ types: ['heading', 'paragraph'] }),
            Table.configure({ resizable: true }),
            TableRow,
            TableHeader,
            TableCell,
            Placeholder.configure({ placeholder }),
            SignatureSlot,
        ],
        // Normalize old saves where bracket text exists without the
        // data-signature-slot attribute, so Tiptap can parse them as nodes.
        content: normalizeSignatureSlots(value),
        editable,
        onUpdate: ({ editor }: { editor: Editor }) => onChange(editor.getHTML()),
        editorProps: {
            attributes: {
                class: 'tiptap-content focus:outline-none min-h-[400px] px-4 py-6',
            },
        },
        // Custom option read by the SignatureSlot NodeView to render images
        // inline when available.
        signatureContext: {
            senderSignatureUrl,
            senderStampUrl,
            recipientSignatureUrl: null,
        },
    } as Parameters<typeof useEditor>[0]);

    // Keep the slot context fresh when the parent props change (e.g. admin
    // just drew their signature → the slot should reflect it immediately).
    React.useEffect(() => {
        if (!editor) return;
        (editor.options as unknown as { signatureContext: unknown }).signatureContext = {
            senderSignatureUrl,
            senderStampUrl,
            recipientSignatureUrl: null,
        };
        // Force a re-render of node views
        editor.view.dispatch(editor.state.tr);
    }, [editor, senderSignatureUrl, senderStampUrl]);

    // Sync external value changes (e.g. "Load template" button)
    React.useEffect(() => {
        if (!editor) return;
        if (value !== editor.getHTML()) {
            editor.commands.setContent(value || '', false);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [value, editor]);

    if (!editor) {
        return (
            <div className={cn('rounded-md border bg-white p-6 text-sm text-muted-foreground', className)}>
                Chargement de l'éditeur…
            </div>
        );
    }

    const insertSignatureSlot = (slot: 'sender' | 'recipient') => {
        // Use the custom node command — survives editor round-trip and renders
        // the actual signature image inline when one is available.
        editor.chain().focus().insertSignatureSlot(slot).run();
    };

    return (
        <div className={cn('rounded-md border bg-white', className)}>
            {editable && (
                <div className="flex flex-wrap items-center gap-1 border-b bg-muted/40 px-2 py-1">
                    <ToolbarBtn active={editor.isActive('bold')} onClick={() => editor.chain().focus().toggleBold().run()} title="Gras">
                        <Bold className="h-4 w-4" />
                    </ToolbarBtn>
                    <ToolbarBtn active={editor.isActive('italic')} onClick={() => editor.chain().focus().toggleItalic().run()} title="Italique">
                        <Italic className="h-4 w-4" />
                    </ToolbarBtn>
                    <ToolbarBtn active={editor.isActive('underline')} onClick={() => editor.chain().focus().toggleUnderline().run()} title="Souligné">
                        <UnderlineIcon className="h-4 w-4" />
                    </ToolbarBtn>
                    <Separator />
                    <ToolbarBtn
                        active={editor.isActive('heading', { level: 1 })}
                        onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
                        title="Titre 1"
                    >
                        <Heading1 className="h-4 w-4" />
                    </ToolbarBtn>
                    <ToolbarBtn
                        active={editor.isActive('heading', { level: 2 })}
                        onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
                        title="Titre 2"
                    >
                        <Heading2 className="h-4 w-4" />
                    </ToolbarBtn>
                    <ToolbarBtn
                        active={editor.isActive('heading', { level: 3 })}
                        onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
                        title="Titre 3"
                    >
                        <Heading3 className="h-4 w-4" />
                    </ToolbarBtn>
                    <Separator />
                    <ToolbarBtn active={editor.isActive('bulletList')} onClick={() => editor.chain().focus().toggleBulletList().run()} title="Liste à puces">
                        <List className="h-4 w-4" />
                    </ToolbarBtn>
                    <ToolbarBtn active={editor.isActive('orderedList')} onClick={() => editor.chain().focus().toggleOrderedList().run()} title="Liste numérotée">
                        <ListOrdered className="h-4 w-4" />
                    </ToolbarBtn>
                    <Separator />
                    <ToolbarBtn
                        active={editor.isActive({ textAlign: 'left' })}
                        onClick={() => editor.chain().focus().setTextAlign('left').run()}
                        title="Aligner à gauche"
                    >
                        <AlignLeft className="h-4 w-4" />
                    </ToolbarBtn>
                    <ToolbarBtn
                        active={editor.isActive({ textAlign: 'center' })}
                        onClick={() => editor.chain().focus().setTextAlign('center').run()}
                        title="Centrer"
                    >
                        <AlignCenter className="h-4 w-4" />
                    </ToolbarBtn>
                    <ToolbarBtn
                        active={editor.isActive({ textAlign: 'right' })}
                        onClick={() => editor.chain().focus().setTextAlign('right').run()}
                        title="Aligner à droite"
                    >
                        <AlignRight className="h-4 w-4" />
                    </ToolbarBtn>
                    <Separator />
                    <ToolbarBtn
                        onClick={() => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()}
                        title="Insérer un tableau"
                    >
                        <TableIcon className="h-4 w-4" />
                    </ToolbarBtn>
                    <ToolbarBtn
                        onClick={() => editor.chain().focus().addRowAfter().run()}
                        title="Ajouter une ligne"
                        disabled={!editor.can().addRowAfter()}
                    >
                        +L
                    </ToolbarBtn>
                    <ToolbarBtn
                        onClick={() => editor.chain().focus().addColumnAfter().run()}
                        title="Ajouter une colonne"
                        disabled={!editor.can().addColumnAfter()}
                    >
                        +C
                    </ToolbarBtn>
                    <ToolbarBtn
                        onClick={() => editor.chain().focus().deleteTable().run()}
                        title="Supprimer le tableau"
                        disabled={!editor.can().deleteTable()}
                    >
                        <Trash2 className="h-4 w-4" />
                    </ToolbarBtn>
                    <Separator />
                    <ToolbarBtn onClick={() => insertSignatureSlot('sender')} title="Insérer un emplacement Signature Conciergerie">
                        <PencilLine className="h-4 w-4 text-emerald-600" />
                        <span className="ml-1 hidden text-xs sm:inline">Sig. Conciergerie</span>
                    </ToolbarBtn>
                    <ToolbarBtn onClick={() => insertSignatureSlot('recipient')} title="Insérer un emplacement Signature Partenaire">
                        <Stamp className="h-4 w-4 text-blue-600" />
                        <span className="ml-1 hidden text-xs sm:inline">Sig. Partenaire</span>
                    </ToolbarBtn>
                    <Separator />
                    <ToolbarBtn onClick={() => editor.chain().focus().undo().run()} disabled={!editor.can().undo()} title="Annuler">
                        <Undo2 className="h-4 w-4" />
                    </ToolbarBtn>
                    <ToolbarBtn onClick={() => editor.chain().focus().redo().run()} disabled={!editor.can().redo()} title="Refaire">
                        <Redo2 className="h-4 w-4" />
                    </ToolbarBtn>
                </div>
            )}
            <EditorContent editor={editor} />
        </div>
    );
}

function ToolbarBtn({
    active,
    onClick,
    title,
    disabled,
    children,
}: {
    active?: boolean;
    onClick: () => void;
    title: string;
    disabled?: boolean;
    children: React.ReactNode;
}) {
    return (
        <Button
            type="button"
            variant="ghost"
            size="sm"
            onClick={onClick}
            title={title}
            disabled={disabled}
            className={cn('h-8 px-2 text-xs', active && 'bg-primary/10 text-primary')}
        >
            {children}
        </Button>
    );
}

function Separator() {
    return <span className="mx-1 inline-block h-5 w-px bg-border" />;
}
