import EXERCISES from "./exercises";
import clsx from "clsx";
import { ExerciseGen, GeneratedExercises, GeneratorState } from "./generatedExercises";
import Modal from "@/components/Modal";
import { useState } from "react";
import ExerciseWizard, { ExerciseConfig } from "./ExerciseWizard";
import { generate } from "../../SettingsEditor/Shared/Generate";
import { Module } from "@/interfaces";
import useExamEditorStore from "@/stores/examEditor";
import { ListeningPart, Message, ReadingPart } from "@/interfaces/exam";
import { BsArrowRepeat } from "react-icons/bs";

interface ExercisePickerProps {
    module: string;
    sectionId: number;
    difficulty: string;
    extraArgs?: Record<string, any>;
}

const ExercisePicker: React.FC<ExercisePickerProps> = ({
    module,
    sectionId,
    extraArgs = undefined,
}) => {
    const { currentModule, dispatch } = useExamEditorStore();
    const { difficulty } = useExamEditorStore((store) => store.modules[currentModule]);
    const section = useExamEditorStore((store) => store.modules[currentModule].sections.find((s) => s.sectionId == sectionId));

    const [pickerOpen, setPickerOpen] = useState(false);

    if (section === undefined) return <></>;

    const { state, selectedExercises } = section;

    const getFullExerciseType = (exercise: ExerciseGen): string => {
        if (exercise.extra && exercise.extra.length > 0) {
            const extraValue = exercise.extra.find(e => e.param === 'name')?.value;
            return extraValue ? `${exercise.type}/?name=${extraValue}` : exercise.type;
        }
        return exercise.type;
    };

    const handleChange = (exercise: ExerciseGen) => {
        const fullType = getFullExerciseType(exercise);

        const newSelected = selectedExercises.includes(fullType)
            ? selectedExercises.filter(type => type !== fullType)
            : [...selectedExercises, fullType];

        dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { module: currentModule, sectionId, field: "selectedExercises", value: newSelected } })
    };

    const moduleExercises = (sectionId && module !== "level" ? EXERCISES.filter((ex) => ex.module === module && ex.sectionId == sectionId) : EXERCISES.filter((ex) => ex.module === module));

    const onModuleSpecific = (configurations: ExerciseConfig[]) => {
        const exercises = configurations.map(config => {
            const exerciseType = config.type.split('name=')[1];

            return {
                type: exerciseType,
                quantity: Number(config.params.quantity || 1),
                ...(config.params.num_random_words !== undefined && {
                    num_random_words: Number(config.params.num_random_words)
                }),
                ...(config.params.max_words !== undefined && {
                    max_words: Number(config.params.max_words)
                })
            };
        });

        let context, moduleState;

        switch (module) {
            case 'reading':
                moduleState = state as ReadingPart;
                context = {
                    text: moduleState.text.content
                }
                break;
            case 'listening':
                moduleState = state as ListeningPart;
                let script = moduleState.script;
                let text, dialog;
                switch (sectionId) {
                    case 1:
                    case 3:
                        dialog = script as Message[];
                        text = dialog.map((d) => `${d.name}: ${d.text}`).join("\n");
                        context = { text: text }
                        break;
                    case 2:
                    case 4:
                        text = script as string;
                        context = { text: text }
                        break;
                }
                break;
            default:
                context = {}
        }
        generate(
            sectionId,
            module as Module,
            "exercises",
            {
                method: 'POST',
                body: {
                    ...context,
                    exercises: exercises,
                    difficulty: difficulty
                }
            },
            (data: any) => [{
                exercises: data.exercises
            }]
        );
        dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { sectionId, module: currentModule, field: "selectedExercises", value: [] } })
        setPickerOpen(false);
    };


    return (
        <>
            <Modal isOpen={pickerOpen} onClose={() => setPickerOpen(false)} title="Exercise Wizard"
                titleClassName={clsx(
                    "text-2xl font-semibold text-center py-4",
                    `bg-ielts-${module} text-white`,
                    "shadow-sm",
                    "-mx-6 -mt-6",
                    "mb-6"
                )}
            >
                <ExerciseWizard
                    sectionId={sectionId}
                    exercises={moduleExercises}
                    onSubmit={onModuleSpecific}
                    onDiscard={() => setPickerOpen(false)}
                    extraArgs={extraArgs}
                />
            </Modal>
            <div className="flex flex-col gap-4 px-4" key={sectionId}>
                <div className="space-y-2">
                    {moduleExercises.map((exercise) => {
                        const fullType = getFullExerciseType(exercise);
                        return (
                            <label
                                key={fullType}
                                className={`flex items-center space-x-3 text-white font-semibold cursor-pointer p-2 hover:bg-ielts-${exercise.module}/70 rounded bg-ielts-${exercise.module}/90`}
                            >
                                <input
                                    type="checkbox"
                                    name="exercise"
                                    value={fullType}
                                    checked={selectedExercises.includes(fullType)}
                                    onChange={() => handleChange(exercise)}
                                    className="h-5 w-5"
                                />
                                <div className="flex items-center space-x-2">
                                    <exercise.icon className="h-5 w-5 text-white" />
                                    <span>{exercise.label}</span>
                                </div>
                            </label>
                        );
                    })}
                </div>
                <div className="flex flex-row justify-center">
                    <button
                        className={
                            clsx("flex items-center justify-center px-4 py-2 text-white rounded-xl transition-colors duration-300 disabled:cursor-not-allowed",
                                `bg-ielts-${module}/70 border border-ielts-${module} hover:bg-ielts-${module} disabled:bg-ielts-${module}/40 `,
                            )
                        }
                        onClick={() => setPickerOpen(true)}
                        disabled={selectedExercises.length == 0}
                    >
                        {section.generating === "exercises" ? (
                            <div key={`section-${sectionId}`} className="flex items-center justify-center">
                                <BsArrowRepeat className="text-white animate-spin" size={25} />
                            </div>
                        ) : (
                            <>Set Up Exercises ({selectedExercises.length})  </>
                        )}
                    </button>
                </div>
            </div>
        </>
    );
};

export default ExercisePicker;
