import { useCallback, useEffect, useState } from "react";
import useExamEditorStore from "@/stores/examEditor";
import { ModuleState } from "@/stores/examEditor/types";
import { SpeakingExercise, InteractiveSpeakingExercise } from "@/interfaces/exam";
import useSectionEdit from "../../Hooks/useSectionEdit";
import Header from "../../Shared/Header";
import GenLoader from "../Shared/GenLoader";
import { Card, CardContent } from "@/components/ui/card";
import AutoExpandingTextArea from "@/components/Low/AutoExpandingTextarea";

interface Props {
    sectionId: number;
    exercise: SpeakingExercise | InteractiveSpeakingExercise;
}

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

    const [local, setLocal] = useState(exercise);
    const [loading, setLoading] = useState(generating === "context");
    const [questions, setQuestions] = useState(() => {
        if (sectionId === 1) {
            return (exercise as SpeakingExercise).prompts || Array(5).fill("");
        } else if (sectionId === 2) {
            return [(exercise as SpeakingExercise).text || "", ...(exercise as SpeakingExercise).prompts || Array(3).fill("")];
        } else {
            return (exercise as InteractiveSpeakingExercise).prompts?.map(p => p.text) || Array(5).fill("");
        }
    });

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

    const { editing, setEditing, handleSave, handleDiscard, modeHandle } = useSectionEdit({
        sectionId,
        mode: "edit",
        onSave: () => {
            let newExercise;
            if (sectionId === 1) {
                newExercise = { 
                    ...local,
                    prompts: questions
                } as SpeakingExercise;
            } else if (sectionId === 2) {
                newExercise = {
                    ...local,
                    text: questions[0],
                    prompts: questions.slice(1),
                } as SpeakingExercise;
            } else {
                // Section 3
                newExercise = {
                    ...local,
                    prompts: questions.map(text => ({
                        text,
                        video_url: (local as InteractiveSpeakingExercise).prompts?.[0]?.video_url || ""
                    }))
                } as InteractiveSpeakingExercise;
            }
            setEditing(false);
            dispatch({ 
                type: "UPDATE_SECTION_STATE", 
                payload: { 
                    sectionId: sectionId, 
                    update: newExercise 
                } 
            });
        },
        onDiscard: () => {
            setLocal(exercise);
            if (sectionId === 1) {
                setQuestions((exercise as SpeakingExercise).prompts || Array(5).fill(""));
            } else if (sectionId === 2) {
                setQuestions([(exercise as SpeakingExercise).text || "", ...(exercise as SpeakingExercise).prompts || Array(3).fill("")]);
            } else {
                setQuestions((exercise as InteractiveSpeakingExercise).prompts?.map(p => p.text) || Array(5).fill(""));
            }
        },
    });

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

        if (isLoading) {
            updateModule({ edit: Array.from(new Set([...edit, sectionId])) });
        }
    }, [generating, sectionId]);

    useEffect(() => {
        if (genResult && generating === "context") {
            setEditing(true);
            if (sectionId === 1) {
                setQuestions(genResult[0].questions);
            } else if (sectionId === 2) {
                setQuestions([genResult[0].question, ...genResult[0].prompts]);
            } else {
                setQuestions(genResult[0].questions);
            }
            
            dispatch({ 
                type: "UPDATE_SECTION_SINGLE_FIELD", 
                payload: { 
                    sectionId, 
                    module: currentModule, 
                    field: "genResult", 
                    value: undefined 
                }
            });
        }
    }, [genResult, generating, dispatch, sectionId, setEditing, currentModule]);

    const handleQuestionChange = (index: number, value: string) => {
        setQuestions(prev => {
            const newQuestions = [...prev];
            newQuestions[index] = value;
            return newQuestions;
        });
    };

    const getQuestionLabel = (index: number) => {
        if (sectionId === 2 && index === 0) {
            return "Main Question";
        } else if (sectionId === 2) {
            return `Prompt ${index}`;
        } else {
            return `Question ${index + 1}`;
        }
    };

    return (
        <>
            <div className='relative pb-4'>
                <Header
                    title={`Speaking ${sectionId} Script`}
                    description='Generate or write the script for the video.'
                    editing={editing}
                    handleSave={handleSave}
                    modeHandle={modeHandle}
                    handleDiscard={handleDiscard}
                />
            </div>
            {loading ? (
                <GenLoader module={currentModule} />
            ) : (
                <div className="mx-auto p-3 space-y-6">
                    <Card>
                        <CardContent>
                            <div className="p-4">
                                <div className="flex flex-col space-y-6">
                                    {questions.map((question: string, index: number) => (
                                        <div key={index} className="flex flex-col">
                                            <h2 className="font-semibold my-2">{getQuestionLabel(index)}</h2>
                                            <AutoExpandingTextArea
                                                value={question}
                                                onChange={(text) => handleQuestionChange(index, text)}
                                                className="w-full p-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent min-h-[80px] transition-all"
                                                placeholder={`Enter ${getQuestionLabel(index).toLowerCase()}`}
                                            />
                                        </div>
                                    ))}
                                </div>
                            </div>
                        </CardContent>
                    </Card>
                </div>
            )}
        </>
    );
};

export default Speaking;
