import AutoExpandingTextArea from "@/components/Low/AutoExpandingTextarea";
import { Card, CardContent } from "@/components/ui/card";
import { WriteBlanksExercise, ReadingPart, Difficulty } from "@/interfaces/exam";
import useExamEditorStore from "@/stores/examEditor";
import { DragEndEvent } from "@dnd-kit/core";
import { arrayMove } from "@dnd-kit/sortable";
import { useState, useEffect, useCallback } from "react";
import { MdEditOff, MdEdit, MdDelete, MdAdd } from "react-icons/md";
import { toast } from "react-toastify";
import useSectionEdit from "../../Hooks/useSectionEdit";
import Alert, { AlertItem } from "../Shared/Alert";
import QuestionsList from "../Shared/QuestionsList";
import setEditingAlert from "../Shared/setEditingAlert";
import SortableQuestion from "../Shared/SortableQuestion";
import { ParsedQuestion, parseLine, reconstructLine } from "./parsing";
import { validateQuestions, validateEmptySolutions, validateWordCount } from "./validation";
import Header from "../../Shared/Header";
import BlanksFormEditor from "./BlanksFormEditor";
import PromptEdit from "../Shared/PromptEdit";
import { uuidv4 } from "@firebase/util";


const WriteBlanksForm: React.FC<{ sectionId: number; exercise: WriteBlanksExercise }> = ({ sectionId, exercise }) => {
    const { currentModule, dispatch } = useExamEditorStore();
    const difficulty = useExamEditorStore((state) => state.modules[currentModule].difficulty);
    const { state } = useExamEditorStore(
        (state) => state.modules[currentModule].sections.find((section) => section.sectionId === sectionId)!
    );

    const section = state as ReadingPart;
    
    const [alerts, setAlerts] = useState<AlertItem[]>([]);
    const [local, setLocal] = useState(exercise);
    const [editingPrompt, setEditingPrompt] = useState(false);
    const [parsedQuestions, setParsedQuestions] = useState<ParsedQuestion[]>([]);

    const { editing, handleSave, handleDiscard, handleDelete, handlePractice, setEditing } = useSectionEdit({
        sectionId,
        onSave: () => {
            const isQuestionsValid = validateQuestions(parsedQuestions, setAlerts);
            const isSolutionsValid = validateEmptySolutions(local.solutions, setAlerts);

            if (!isQuestionsValid || !isSolutionsValid) {
                toast.error("Please fix the errors before saving!");
                return;
            }

            setEditing(false);
            setAlerts([]);

            const newSection = {
                ...section,
                exercises: section.exercises.map((ex) => ex.id === local.id ? local : ex)
            };
            dispatch({ type: "UPDATE_SECTION_STATE", payload: { sectionId, update: newSection, module: currentModule } });
        },
        onDiscard: () => {
            setLocal(exercise);
            setParsedQuestions([]);
        },
        onDelete: () => {
            const newSection = {
                ...section,
                exercises: section.exercises.filter((ex) => ex.id !== local.id)
            };
            dispatch({ type: "UPDATE_SECTION_STATE", payload: { sectionId, update: newSection, module: currentModule } });
        },
        onPractice: () => {
            const updatedExercise = {
                ...local,
                isPractice: !local.isPractice
            };
            const newState = { ...section };
            newState.exercises = newState.exercises.map((ex) =>
                ex.id === exercise.id ? updatedExercise : ex
            );
            setLocal((prev) => ({...prev, isPractice: !local.isPractice}))
            dispatch({ type: 'UPDATE_SECTION_STATE', payload: { sectionId, update: newState, module: currentModule } });
        }
    });

    useEffect(() => {
        const questions = local.text.split('\\n')
            .filter(line => line.trim())
            .map(line => {
                const match = line.match(/{{(\d+)}}/);
                return {
                    id: match ? match[1] : `unknown-${Date.now()}`,
                    parts: parseLine(line),
                    editingPlaceholders: true
                };
            });
        setParsedQuestions(questions);
    }, [local.text]);

    useEffect(() => {
        setEditingAlert(editing, setAlerts);
    }, [editing]);

    useEffect(() => {
        validateWordCount(local.solutions, local.maxWords, setAlerts);
    }, [local.maxWords, local.solutions]);

    const updateLocal = (exercise: WriteBlanksExercise) => {
        setLocal(exercise);
        setEditing(true);
    };

    const addQuestion = () => {
        const existingIds = parsedQuestions.map(q => parseInt(q.id));
        const newId = (Math.max(...existingIds, 0) + 1).toString();

        const newLine = `New question with blank {{${newId}}}`;
        const updatedQuestions = [...parsedQuestions, {
            uuid: uuidv4(),
            id: newId,
            parts: parseLine(newLine),
            editingPlaceholders: true
        }];

        const newText = updatedQuestions
            .map(q => reconstructLine(q.parts))
            .join('\\n') + '\\n';

        const updatedSolutions = [...local.solutions, {
            uuid: uuidv4(),
            id: newId,
            solution: [""]
        }];

        updateLocal({
            ...local,
            text: newText,
            solutions: updatedSolutions
        });
    };

    const deleteQuestion = (id: string) => {
        if (parsedQuestions.length === 1) {
            toast.error("There needs to be at least one question!");
            return;
        }
        const updatedQuestions = parsedQuestions.filter(q => q.id !== id);
        const newText = updatedQuestions
            .map(q => reconstructLine(q.parts))
            .join('\\n') + '\\n';

        const updatedSolutions = local.solutions.filter(s => s.id !== id);
        updateLocal({
            ...local,
            text: newText,
            solutions: updatedSolutions
        });
    };

    const handleQuestionUpdate = (questionId: string, newText: string) => {
        const updatedQuestions = parsedQuestions.map(q =>
            q.id === questionId ? { ...q, parts: parseLine(newText) } : q
        );

        const updatedText = updatedQuestions
            .map(q => reconstructLine(q.parts))
            .join('\\n') + '\\n';

        updateLocal({ ...local, text: updatedText });
    };

    const addSolution = (questionId: string) => {
        const newSolutions = local.solutions.map(s =>
            s.id === questionId
                ? { ...s, solution: [...s.solution, ""] }
                : s
        );
        updateLocal({ ...local, solutions: newSolutions });
    };

    const updateSolution = (questionId: string, index: number, value: string) => {
        const newSolutions = local.solutions.map(s =>
            s.id === questionId
                ? { ...s, solution: s.solution.map((sol, i) => i === index ? value : sol) }
                : s
        );
        updateLocal({ ...local, solutions: newSolutions });
    };

    const deleteSolution = (questionId: string, index: number) => {
        const solutions = local.solutions.find(s => s.id === questionId);
        if (solutions && solutions.solution.length <= 1) {
            toast.error("Each question must have at least one solution!");
            return;
        }
        const newSolutions = local.solutions.map(s =>
            s.id === questionId
                ? { ...s, solution: s.solution.filter((_, i) => i !== index) }
                : s
        );
        updateLocal({ ...local, solutions: newSolutions });
    };

    const handleQuestionsReorder = (event: DragEndEvent) => {
        const { active, over } = event;
        if (!over || active.id === over.id) return;

        const oldIndex = parsedQuestions.findIndex(q => q.id === active.id);
        const newIndex = parsedQuestions.findIndex(q => q.id === over.id);

        const reorderedQuestions = arrayMove(parsedQuestions, oldIndex, newIndex);
        const newText = reorderedQuestions
            .map(q => reconstructLine(q.parts))
            .join('\\n') + '\\n';

        updateLocal({ ...local, text: newText });
    };

    const saveDifficulty = useCallback((diff: Difficulty) => {
        if (!difficulty.includes(diff)) {
            dispatch({ type: 'UPDATE_MODULE', payload: { updates: { difficulty: [...difficulty, diff]} } });
        }
        const updatedExercise = { ...exercise, difficulty: diff };
        const newState = { ...section };
        newState.exercises = newState.exercises.map((ex) => ex.id === exercise.id ? updatedExercise : ex );
        dispatch({ type: 'UPDATE_SECTION_STATE', payload: { sectionId, update: newState, module: currentModule } });
    }, [currentModule, difficulty, dispatch, exercise, section, sectionId]);

    return (
        <div className="p-4">
            <Header
                title="Write Blanks: Form Exercise"
                description="Edit questions and their solutions"
                editing={editing}
                difficulty={exercise.difficulty}
                saveDifficulty={saveDifficulty}
                handleSave={handleSave}
                handleDiscard={handleDiscard}
                handleDelete={handleDelete}
                handlePractice={handlePractice}
            />
            <div className="space-y-4">
                {alerts.length > 0 && <Alert alerts={alerts} />}
                <PromptEdit value={local.prompt} onChange={(prompt: string) => updateLocal({ ...local, prompt })}/>
                <div className="space-y-4">
                    <QuestionsList
                        ids={parsedQuestions.map(q => q.id)}
                        handleDragEnd={handleQuestionsReorder}
                    >
                        {parsedQuestions.map((question, index) => (
                            <SortableQuestion
                                key={question.id}
                                id={question.id}
                                index={index}
                                deleteQuestion={() => deleteQuestion(question.id)}
                                variant="del-up"
                            >
                                <div className="space-y-4">
                                    <BlanksFormEditor
                                        parts={question.parts}
                                        onUpdate={(newText) => handleQuestionUpdate(question.id, newText)}
                                    />

                                    <div className="space-y-2">
                                        <h4 className="text-sm font-medium text-gray-700">Solutions:</h4>
                                        {local.solutions.find(s => s.id === question.id)?.solution.map((solution, index) => (
                                            <div key={index} className="flex gap-2 items-center">
                                                <input
                                                    type="text"
                                                    value={solution}
                                                    onChange={(e) => updateSolution(question.id, index, e.target.value)}
                                                    className="flex-1 p-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:outline-none"
                                                    placeholder={`Solution ${index + 1}`}
                                                />
                                                <button
                                                    onClick={() => deleteSolution(question.id, index)}
                                                    className="p-2 text-gray-500 hover:text-red-500 hover:bg-red-50 rounded-lg transition-colors"
                                                    title="Delete solution"
                                                >
                                                    <MdDelete size={20} />
                                                </button>
                                            </div>
                                        ))}
                                        <button
                                            onClick={() => addSolution(question.id)}
                                            className="w-full p-2 border-2 border-dashed border-gray-300 rounded-lg hover:border-blue-500 hover:bg-blue-50 transition-colors flex items-center justify-center gap-2 text-gray-600 hover:text-blue-600"
                                        >
                                            <MdAdd size={18} />
                                            Add Alternative Solution
                                        </button>
                                    </div>
                                </div>
                            </SortableQuestion>
                        ))}
                    </QuestionsList>
                    <button
                        onClick={addQuestion}
                        className="w-full p-4 border-2 border-dashed border-gray-300 rounded-lg hover:border-blue-500 hover:bg-blue-50 transition-colors flex items-center justify-center gap-2 text-gray-600 hover:text-blue-600"
                    >
                        <MdAdd size={18} />
                        Add New Question
                    </button>
                </div>
            </div>
        </div>
    );
};

export default WriteBlanksForm;
