import { useSensors, useSensor, PointerSensor, KeyboardSensor, DragEndEvent, DndContext, closestCenter } from "@dnd-kit/core";
import { sortableKeyboardCoordinates, arrayMove, SortableContext, horizontalListSortingStrategy } from "@dnd-kit/sortable";
import { useState } from "react";
import { BsCursorText } from "react-icons/bs";
import { MdSpaceBar } from "react-icons/md";
import { toast } from "react-toastify";
import { formatDisplayContent, formatStorageContent, PromptPart, reconstructLine } from "./parsing";
import SortableBlank from "./SortableBlank";
import { validatePlaceholders } from "./validation";

interface Props {
    parts: PromptPart[];
    onUpdate: (newText: string) => void;
}

interface EditingState {
    text: string;
    isPlaceholderMode: boolean;
}


const BlanksFormEditor: React.FC<Props> = ({ parts, onUpdate }) => {
    const sensors = useSensors(
        useSensor(PointerSensor),
        useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
    );

    const [editingState, setEditingState] = useState<EditingState>({
        text: formatDisplayContent(reconstructLine(parts)),
        isPlaceholderMode: true
    });

    const handleTextChange = (newText: string) => {
        const placeholder = parts.find(p => p.isPlaceholder);
        if (!placeholder) return;

        const displayPlaceholder = formatDisplayContent(placeholder.content);

        if (!newText.includes(displayPlaceholder)) {
            const placeholderIndex = editingState.text.indexOf(displayPlaceholder);
            
            if (placeholderIndex >= 0) {
                const beforePlaceholder = newText.slice(0, Math.min(placeholderIndex, newText.length));
                const afterPlaceholder = newText.slice(Math.min(placeholderIndex, newText.length));
                newText = beforePlaceholder + displayPlaceholder + afterPlaceholder;
            } else {
                newText = newText + ' ' + displayPlaceholder;
            }
        }

        setEditingState(prev => ({
            ...prev,
            text: newText
        }));
    };

    const handleDragEnd = (event: DragEndEvent) => {
        const { active, over } = event;
        if (!over || active.id === over.id) return;
    
        const oldIndex = parts.findIndex(part => part.id === active.id);
        const newIndex = parts.findIndex(part => part.id === over.id);
    
        const newParts = [...parts];
        const [movedPart] = newParts.splice(oldIndex, 1);
        newParts.splice(newIndex, 0, movedPart);
    
        onUpdate(reconstructLine(newParts));
        
        setEditingState(prev => ({
            ...prev,
            text: formatDisplayContent(reconstructLine(newParts))
        }));
    };

    const toggleEditMode = () => {
        setEditingState(prev => ({
            ...prev,
            isPlaceholderMode: !prev.isPlaceholderMode
        }));
    };

    const saveTextChanges = () => {
        const placeholderId = parts.find(p => p.isPlaceholder)?.id;
        if (!placeholderId) return;

        const validation = validatePlaceholders(editingState.text, placeholderId);
        if (!validation.isValid) {
            toast.error(validation.message);
            setEditingState(prev => ({
                ...prev,
                text: formatDisplayContent(reconstructLine(parts))
            }));
            return;
        }

        onUpdate(formatStorageContent(editingState.text));
    };

    return (
        <div className="flex flex-row items-center gap-2">
            <div className="flex-grow">
                {editingState.isPlaceholderMode ? (
                    <DndContext
                        sensors={sensors}
                        collisionDetection={closestCenter}
                        onDragEnd={handleDragEnd}
                    >
                        <SortableContext 
                            items={parts.map(part => part.id)} 
                            strategy={horizontalListSortingStrategy}
                        >
                            <div className="flex flex-wrap items-center gap-1 min-h-[40px] p-2 border rounded-lg bg-white">
                                {parts.map((part) => (
                                    <SortableBlank
                                        key={part.id}
                                        id={part.id}
                                        isPlaceholder={part.isPlaceholder}
                                    >
                                        {part.isPlaceholder ? (
                                            <div className="bg-blue-200 px-2 py-1 rounded cursor-move">
                                                {formatDisplayContent(part.content)}
                                            </div>
                                        ) : /^\s+$/.test(part.content) ? (
                                            <div className="px-1 border-l-2 border-r-2 border-transparent">
                                                &nbsp;
                                            </div>
                                        ) : (
                                            <div className="px-1">
                                                {part.content}
                                            </div>
                                        )}
                                    </SortableBlank>
                                ))}
                            </div>
                        </SortableContext>
                    </DndContext>
                ) : (
                    <input
                        type="text"
                        value={editingState.text}
                        onChange={(e) => handleTextChange(e.target.value)}
                        onPaste={(e) => e.preventDefault()}
                        onBlur={saveTextChanges}
                        className="w-full p-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:outline-none"
                    />
                )}
            </div>
            <button
                className={`p-2 rounded ${editingState.isPlaceholderMode ? 'bg-blue-500 text-white' : 'bg-gray-200'}`}
                onClick={toggleEditMode}
                title={editingState.isPlaceholderMode ? "Switch to text editing" : "Switch to placeholder editing"}
            >
                {editingState.isPlaceholderMode ? <BsCursorText size={20} /> : <MdSpaceBar size={20} />}
            </button>
        </div>
    );
};

export default BlanksFormEditor;
