import { MultipleChoiceQuestion } from "@/interfaces/exam";
import clsx from "clsx";
import { useEffect, useState } from "react";
import { MdEdit, MdEditOff } from "react-icons/md";

interface UnderlineQuestionProps {
    question: MultipleChoiceQuestion;
    onQuestionChange: (updatedQuestion: MultipleChoiceQuestion) => void;
    onValidationChange?: (isValid: boolean) => void;
}

interface Option {
    id: string;
    text?: string;
    src?: string;
}

export const UnderlineQuestion: React.FC<UnderlineQuestionProps> = ({
    question,
    onQuestionChange,
    onValidationChange,
}) => {
    const [isEditing, setIsEditing] = useState(false);
    const [validationErrors, setValidationErrors] = useState<string[]>([]);

    const stripUnderlineTags = (text: string = '') => text.replace(/<\/?u>/g, '');

    const addUnderlineTags = (text: string, options: Option[]) => {
        let result = text;
        
        // Sort options by length (longest first) to handle overlapping matches
        const sortedOptions = [...options]
            .filter(opt => opt.text?.trim() && opt.text.trim().length > 1)
            .sort((a, b) => ((b.text?.length || 0) - (a.text?.length || 0)));

        for (const option of sortedOptions) {
            if (!option.text?.trim()) continue;
            
            const optionText = stripUnderlineTags(option.text).trim();
            const textLower = result.toLowerCase();
            const optionLower = optionText.toLowerCase();
            
            let startIndex = textLower.indexOf(optionLower);
            while (startIndex !== -1) {
                // Check if this portion is already underlined
                const beforeTag = result.slice(Math.max(0, startIndex - 3), startIndex);
                const afterTag = result.slice(startIndex + optionText.length, startIndex + optionText.length + 4);
                
                if (!beforeTag.includes('<u>') && !afterTag.includes('</u>')) {
                    const before = result.substring(0, startIndex);
                    const match = result.substring(startIndex, startIndex + optionText.length);
                    const after = result.substring(startIndex + optionText.length);
                    result = `${before}<u>${match}</u>${after}`;
                }
                
                // Find next occurrence
                startIndex = textLower.indexOf(optionLower, startIndex + 1);
            }
        }
        
        return result;
    };

    const validateQuestion = (q: MultipleChoiceQuestion) => {
        const errors: string[] = [];
        const rawPrompt = stripUnderlineTags(q.prompt).toLowerCase();

        q.options.forEach((option) => {
            if (option.text?.trim() && !rawPrompt.includes(stripUnderlineTags(option.text).trim().toLowerCase())) {
                errors.push(`Option ${option.id} text not found in prompt`);
            }
        });

        setValidationErrors(errors);
        onValidationChange?.(errors.length === 0);
        return errors.length === 0;
    };

    useEffect(() => {
        validateQuestion(question);
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [question]);

    const handlePromptChange = (value: string) => {
        const newPrompt = addUnderlineTags(value, question.options);
        onQuestionChange({
            ...question,
            prompt: newPrompt
        });
    };

    const handleOptionChange = (optionIndex: number, value: string) => {
        const updatedOptions = question.options.map((opt, idx) => 
            idx === optionIndex ? { ...opt, text: value } : opt
        );
        
        const strippedPrompt = stripUnderlineTags(question.prompt);
        const newPrompt = addUnderlineTags(strippedPrompt, updatedOptions);

        onQuestionChange({
            ...question,
            prompt: newPrompt,
            options: updatedOptions
        });
    };

    return (
        <div className="space-y-4">
            <div className="flex gap-2 items-center">
                {isEditing ? (
                    <input
                        value={stripUnderlineTags(question.prompt)}
                        onChange={(e) => handlePromptChange(e.target.value)}
                        className="flex-1 p-3 border rounded-lg focus:outline-none"
                        placeholder="Enter text for underlining..."
                    />
                ) : (
                    <div
                        className="flex-1 p-3 border rounded-lg min-h-[50px]"
                        dangerouslySetInnerHTML={{ __html: question.prompt || '' }}
                    />
                )}
                <button
                    onClick={() => setIsEditing(!isEditing)}
                    className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
                >
                    {isEditing ?
                        <MdEditOff size={24} className="text-gray-500" /> :
                        <MdEdit size={24} className="text-gray-500" />
                    }
                </button>
            </div>

            {validationErrors.length > 0 && (
                <div className="text-red-500 text-sm">
                    {validationErrors.map((error, index) => (
                        <div key={index}>{error}</div>
                    ))}
                </div>
            )}

            <div className="space-y-2">
                {question.options.map((option, optionIndex) => {
                    const isInvalidOption = option.text?.trim() &&
                        !stripUnderlineTags(question.prompt || '').toLowerCase()
                            .includes(stripUnderlineTags(option.text).trim().toLowerCase());

                    return (
                        <div key={option.id} className="flex gap-2">
                            <label
                                className={clsx(
                                    "flex-none w-12 p-3 text-center rounded-lg border-2 transition-all cursor-pointer",
                                    question.solution === option.id
                                        ? 'border-blue-500 bg-blue-50 text-blue-700'
                                        : 'border-gray-200 hover:border-gray-300'
                                )}
                            >
                                <input
                                    type="radio"
                                    name={`solution-${question.id}`}
                                    value={option.id}
                                    checked={question.solution === option.id}
                                    onChange={(e) => onQuestionChange({
                                        ...question,
                                        solution: e.target.value
                                    })}
                                    className="sr-only"
                                />
                                {option.id}
                            </label>
                            <input
                                type="text"
                                value={stripUnderlineTags(option.text || '')}
                                onChange={(e) => handleOptionChange(optionIndex, e.target.value)}
                                className={clsx(
                                    "flex-1 p-3 border rounded-lg focus:ring-2 focus:outline-none",
                                    isInvalidOption
                                        ? "border-red-500 focus:ring-red-500 bg-red-50"
                                        : "focus:ring-blue-500"
                                )}
                                placeholder={`Option ${option.id}...`}
                            />
                        </div>
                    );
                })}
            </div>
        </div>
    );
};

export default UnderlineQuestion;
