import React, { useEffect, useState } from 'react';
import { Tooltip } from 'react-tooltip';
import { ExerciseGen } from './generatedExercises';
import Image from 'next/image';
import clsx from 'clsx';
import { GiBrain } from 'react-icons/gi';
import { IoTextOutline } from 'react-icons/io5';
import { Switch } from '@headlessui/react';
import useExamEditorStore from '@/stores/examEditor';
import { Module } from '@/interfaces';

interface Props {
    module: Module;
    sectionId: number;
    exercises: ExerciseGen[];
    extraArgs?: Record<string, any>;
    onSubmit: (configurations: ExerciseConfig[]) => void;
    onDiscard: () => void;
    selectedExercises: string[];
}

export interface ExerciseConfig {
    type: string;
    params: {
        [key: string]: string | number | boolean;
    };
}

const ExerciseWizard: React.FC<Props> = ({
    module,
    exercises,
    extraArgs,
    sectionId,
    selectedExercises,
    onSubmit,
    onDiscard,
}) => {
    const [configurations, setConfigurations] = useState<ExerciseConfig[]>([]);

    useEffect(() => {
        const initialConfigs = selectedExercises.map(exerciseType => {
            const exercise = exercises.find(ex => {
                const fullType = ex.extra?.find(e => e.param === 'name')?.value
                    ? `${ex.type}/?name=${ex.extra.find(e => e.param === 'name')?.value}`
                    : ex.type;
                return fullType === exerciseType;
            });

            const params: { [key: string]: string | number | boolean } = {};
            exercise?.extra?.forEach(param => {
                if (param.param !== 'name') {
                    if (exerciseType.includes('paragraphMatch') && param.param === 'quantity') {
                        params[param.param] = extraArgs?.text.split("\n\n").length || 1;
                    } else {
                        params[param.param || ''] = param.value ?? '';
                    }
                }
            });

            return {
                type: exerciseType,
                params
            };
        });

        setConfigurations(initialConfigs);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [selectedExercises, exercises]);

    const handleParameterChange = (
        exerciseIndex: number,
        paramName: string,
        value: string | number | boolean
    ) => {
        setConfigurations(prev => {
            const newConfigs = [...prev];
            newConfigs[exerciseIndex] = {
                ...newConfigs[exerciseIndex],
                params: {
                    ...newConfigs[exerciseIndex].params,
                    [paramName]: value
                }
            };
            return newConfigs;
        });
    };

    const renderParameterInput = (
        param: NonNullable<ExerciseGen['extra']>[0],
        exerciseIndex: number,
        config: ExerciseConfig
    ) => {
        if (typeof param.value === 'boolean') {
            const currentValue = Boolean(config.params[param.param || '']);
            return (
                <div className="flex flex-row items-center ml-auto">
                    <GiBrain
                        className="mx-4"
                        size={28}
                        color={currentValue ? `#F3F4F6` : `#1F2937`}
                    />
                    <Switch
                        checked={currentValue}
                        onChange={(value) => handleParameterChange(
                            exerciseIndex,
                            param.param || '',
                            value
                        )}
                        className={clsx(
                            "relative inline-flex h-[30px] w-[58px] shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white/75",
                            currentValue ? `bg-[#F3F4F6]` : `bg-[#1F2937]`
                        )}
                    >
                        <span
                            aria-hidden="true"
                            className={clsx(
                                "pointer-events-none inline-block h-[26px] w-[26px] transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out",
                                currentValue ? 'translate-x-7' : 'translate-x-0'
                            )}
                        />
                    </Switch>
                    <IoTextOutline
                        className="mx-4"
                        size={28}
                        color={!currentValue ? `#F3F4F6` : `#1F2937`}
                    />
    
                    <Tooltip id={`${exerciseIndex}`} className="z-50 bg-white shadow-md rounded-sm" />
                    <a data-tooltip-id={`${exerciseIndex}`} data-tooltip-html="Generate or use placeholder?" className='ml-1 flex items-center justify-center'>
                        <Image src="/mat-icon-info.svg" width={24} height={24} alt={"AI Generated?"} />
                    </a>
                </div>
            );
        }
        
        if ('type' in param && param.type === 'text') {
            return (
                <div className="space-y-2">
                    <div className="flex items-center gap-2">
                        <label className="text-sm font-medium text-white">
                            {param.label}
                        </label>
                        {param.tooltip && (
                            <>
                                <Tooltip id={config.type} className="z-50 bg-white shadow-md rounded-sm" />
                                <a data-tooltip-id={config.type} data-tooltip-html={param.tooltip} className='ml-1 flex items-center justify-center'>
                                    <Image src="/mat-icon-info.svg" width={24} height={24} alt={param.tooltip} />
                                </a>
                            </>
                        )}
                    </div>
                    <input
                        type="text"
                        value={config.params[param.param || ''] as string}
                        onChange={(e) => handleParameterChange(
                            exerciseIndex,
                            param.param || '',
                            e.target.value
                        )}
                        className="px-3 py-2 shadow-lg rounded-md text-mti-gray-dim w-full"
                        placeholder="Enter here..."
                    />
                </div>
            );
        }
    
        const inputValue = Number(config.params[param.param || '1'].toString());
        const isParagraphMatch = config.type.split("?name=")[1] === "paragraphMatch";
        const maxParagraphs = isParagraphMatch ? extraArgs!.text.split("\n\n").length : 50;
    
        return (
            <div className="space-y-2">
                <div className="flex items-center gap-2">
                    <label className="text-sm font-medium text-white">
                        {`${param.label}${isParagraphMatch ? ` (out of ${extraArgs!.text.split("\n\n").length} paragraphs)` : ""}`}
                    </label>
                    {param.tooltip && (
                        <>
                            <Tooltip id={config.type} className="z-50 bg-white shadow-md rounded-sm" />
                            <a data-tooltip-id={config.type} data-tooltip-html={param.tooltip} className='ml-1 flex items-center justify-center'>
                                <Image src="/mat-icon-info.svg" width={24} height={24} alt={param.tooltip} />
                            </a>
                        </>
                    )}
                </div>
                <input
                    type="number"
                    value={inputValue}
                    onChange={(e) => handleParameterChange(
                        exerciseIndex,
                        param.param || '',
                        e.target.value ? Number(e.target.value) : ''
                    )}
                    className="px-3 py-2 shadow-lg rounded-md text-mti-gray-dim w-full"
                    min={1}
                    max={maxParagraphs}
                />
            </div>
        );
    };

    const renderExerciseHeader = (
        exercise: ExerciseGen,
        exerciseIndex: number,
        config: ExerciseConfig,
        extraParams: boolean,
    ) => {
        const generateParam = exercise.extra?.find(param => param.param === 'generate');

        return (
            <div className={clsx("flex items-center w-full", extraParams ? "mb-4" : "py-4")}>
                <div className="flex items-center gap-2">
                    <exercise.icon className="h-5 w-5" />
                    <h3 className="font-medium text-lg">{exercise.label}</h3>
                </div>
                {/* when placeholders are done uncomment this*/}
                {/*generateParam && renderParameterInput(generateParam, exerciseIndex, config)*/}
            </div>
        );
    };

    return (
        <div className="space-y-6 px-4 py-6">
            {configurations.map((config, exerciseIndex) => {
                const exercise = exercises.find(ex => {
                    const fullType = ex.extra?.find(e => e.param === 'name')?.value
                        ? `${ex.type}/?name=${ex.extra.find(e => e.param === 'name')?.value}`
                        : ex.type;
                    return fullType === config.type;
                });

                if (!exercise) return null;

                const nonGenerateParams = exercise.extra?.filter(
                    param => param.param !== 'name' && param.param !== 'generate'
                );

                return (
                    <div
                        key={config.type}
                        className={`bg-ielts-${module}/70 text-white rounded-lg p-4 shadow-xl`}
                    >
                        {renderExerciseHeader(exercise, exerciseIndex, config, (exercise.extra || []).length > 2)}

                        {nonGenerateParams && nonGenerateParams.length > 0 && (
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                {nonGenerateParams.map(param => (
                                    <div key={param.param}>
                                        {renderParameterInput(param, exerciseIndex, config)}
                                    </div>
                                ))}
                            </div>
                        )}
                    </div>
                );
            })}

            <div className="flex justify-between">
                <button
                    onClick={onDiscard}
                    className={`px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-400 transition-colors`}
                >
                    Cancel
                </button>
                <button
                    onClick={() => onSubmit(configurations)}
                    className={`px-4 py-2 bg-ielts-${module} text-white rounded-md hover:bg-ielts-${module}/80 transition-colors`}
                >
                    Add Exercises
                </button>
            </div>
        </div>
    );
};

export default ExerciseWizard;