import { useCallback, useEffect, useState } from "react";
import useExamEditorStore from "@/stores/examEditor";
import ExamEditorStore, { ModuleState } from "@/stores/examEditor/types";
import AutoExpandingTextArea from "@/components/Low/AutoExpandingTextarea";
import { WritingExercise } from "@/interfaces/exam";
import Header from "../../Shared/Header";
import Alert, { AlertItem } from "../Shared/Alert";
import clsx from "clsx";
import useSectionEdit from "../../Hooks/useSectionEdit";
import GenLoader from "../Shared/GenLoader";
import setEditingAlert from "../Shared/setEditingAlert";

interface Props {
    sectionId: number;
    exercise: WritingExercise;
}

const Writing: React.FC<Props> = ({ sectionId }) => {
    const { currentModule, dispatch } = useExamEditorStore();
    const { edit } = useExamEditorStore((store) => store.modules[currentModule]);
    const { generating, genResult, state } = useExamEditorStore(
        (state) => state.modules[currentModule].sections.find((section) => section.sectionId === sectionId)!
    );

    const exercise = state as WritingExercise;

    const [local, setLocal] = useState(exercise);
    const [prompt, setPrompt] = useState(exercise.prompt);
    const [loading, setLoading] = useState(generating && generating == "exercises");
    const [alerts, setAlerts] = useState<AlertItem[]>([]);

    const updateModule = useCallback((updates: Partial<ModuleState>) => {
        dispatch({ type: 'UPDATE_MODULE', payload: { updates } });
    }, [dispatch]);

    const { editing, handleSave, handleDiscard, modeHandle, setEditing } = useSectionEdit({
        sectionId,
        onSave: () => {
            const newExercise = { ...local } as WritingExercise;
            newExercise.prompt = prompt;
            setAlerts([]);
            setEditing(false);
            dispatch({ type: "UPDATE_SECTION_STATE", payload: { sectionId: sectionId, update: newExercise } });
        },
        onDiscard: () => {
            setLocal(exercise);
        },
    });

    useEffect(() => {
        const loading = generating && generating == "context";
        setLoading(loading);

        if (loading) {
            updateModule({ edit: Array.from(new Set(edit).add(sectionId)) });
        }

        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [generating, updateModule]);

    useEffect(() => {
        if (genResult !== undefined && generating === "context") {
            setEditing(true);
            setPrompt(genResult[0].prompt);
            dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { sectionId, module: currentModule, field: "genResult", value: undefined } })
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [genResult, dispatch, sectionId, setEditing, currentModule]);

    useEffect(() => {
        setLocal(state as WritingExercise);
    }, [state]);

    useEffect(() => {
        setEditingAlert(prompt !== local.prompt, setAlerts);
    }, [prompt, local.prompt]);

    return (
        <>
            <div className='relative pb-4'>
                <Header
                    title={`Task ${sectionId} Instructions`}
                    description='Generate or edit the instructions for the task'
                    editing={editing}
                    handleSave={handleSave}
                    modeHandle={modeHandle}
                    handleDiscard={handleDiscard}
                    mode="edit"
                    module={"writing"}
                />
                {alerts.length !== 0 && <Alert alerts={alerts} />}
            </div>
            <div className="mt-4">
                {loading ?
                    <GenLoader module={currentModule} /> :
                    (
                        editing ? (
                            <div className="text-gray-600 p-4">
                                <AutoExpandingTextArea
                                    value={prompt}
                                    onChange={(text) => setPrompt(text)}
                                    placeholder="Instructions ..."
                                />
                            </div>
                        ) : (
                            <p className={
                                clsx("w-full px-7 py-8 border-2 bg-white rounded-3xl whitespace-pre-line",
                                    prompt === "" ? "text-gray-600/50" : "text-gray-600"
                                )
                            }>
                                {prompt === "" ? "Instructions ..." : prompt}
                            </p>
                        )
                    )}
            </div>
        </>
    );
};

export default Writing;
