import React, { useCallback, useEffect, useState } from 'react';
import AutoExpandingTextArea from "@/components/Low/AutoExpandingTextarea";
import { Card, CardContent } from "@/components/ui/card";
import { AiOutlineUnorderedList, AiOutlinePlus, AiOutlineDelete } from 'react-icons/ai';
import Header from "../../Shared/Header";
import GenLoader from "../Shared/GenLoader";
import useSectionEdit from "../../Hooks/useSectionEdit";
import useExamEditorStore from "@/stores/examEditor";
import { Difficulty, InteractiveSpeakingExercise, LevelPart } from "@/interfaces/exam";
import { BsFileText } from "react-icons/bs";
import { RiVideoLine } from 'react-icons/ri';
import { FaChevronLeft, FaChevronRight } from 'react-icons/fa6';
import { Module } from '@/interfaces';

interface Props {
    sectionId: number;
    exercise: InteractiveSpeakingExercise;
    module?: Module;
}

const Speaking1: React.FC<Props> = ({ sectionId, exercise, module = "speaking" }) => {
    const { currentModule, dispatch } = useExamEditorStore();
    const difficulty = useExamEditorStore((state) => state.modules[currentModule].difficulty);
    const [local, setLocal] = useState(() => {
        const defaultPrompts = [
            { text: "Hello my name is {avatar}, what is yours?", video_url: "" },
            { text: "Do you work or do you study?", video_url: "" },
            ...exercise.prompts.slice(2)
        ];
        return { ...exercise, prompts: defaultPrompts };
    });

    const [currentVideoIndex, setCurrentVideoIndex] = useState(0);

    const { generating, genResult, state, levelGenResults, levelGenerating } = useExamEditorStore(
        (state) => state.modules[module].sections.find((section) => section.sectionId === sectionId)!
    );

    const { editing, setEditing, handleSave, handleDiscard, handleEdit, handlePractice } = useSectionEdit({
        sectionId,
        onSave: () => {
            setEditing(false);

            if (module === "level") {
                const updatedState = {
                    ...state,
                    exercises: (state as LevelPart).exercises.map((ex) =>
                        ex.id === local.id ? local : ex
                    )
                };
                dispatch({
                    type: "UPDATE_SECTION_STATE",
                    payload: { sectionId, update: updatedState, module }
                });
            } else {
                dispatch({
                    type: "UPDATE_SECTION_STATE",
                    payload: { sectionId, update: local, module }
                });
            }

            if (genResult) {
                dispatch({
                    type: "UPDATE_SECTION_SINGLE_FIELD",
                    payload: {
                        sectionId,
                        module,
                        field: "genResult",
                        value: undefined
                    }
                });
            }

            const speakingScript = levelGenResults?.find((res) => res.generating === `${local.id}-speakingScript`);
            if (module === "level" && speakingScript) {
                dispatch({
                    type: "UPDATE_SECTION_SINGLE_FIELD", payload: {
                        sectionId,
                        field: "levelGenResults",
                        value: levelGenResults.filter((res) => res.generating !== `${local.id}-speakingScript`),
                        module
                    }
                });
            }
        },
        onDiscard: () => {
            setLocal({
                ...exercise,
                prompts: [
                    { text: "Hello my name is {avatar}, what is yours?", video_url: "" },
                    { text: "Do you work or do you study?", video_url: "" },
                    ...exercise.prompts.slice(2)
                ]
            });
        },
        onPractice: () => {
            const updatedLocal = { ...local, isPractice: !local.isPractice };
            setLocal(updatedLocal);

            if (module === "level") {
                const updatedState = {
                    ...state,
                    exercises: (state as LevelPart).exercises.map((ex) =>
                        ex.id === local.id ? updatedLocal : ex
                    )
                };
                dispatch({
                    type: "UPDATE_SECTION_STATE",
                    payload: { sectionId, update: updatedState, module }
                });
            } else {
                dispatch({
                    type: "UPDATE_SECTION_STATE",
                    payload: { sectionId, update: updatedLocal, module }
                });
            }
        },
    });

    useEffect(() => {
        if (genResult && generating === "speakingScript") {
            if (!difficulty.includes(genResult.result[0].difficulty)) {
                dispatch({ type: 'UPDATE_MODULE', payload: { updates: { difficulty: [...difficulty, genResult.result[0].difficulty]} } });
            }
            const updatedLocal = {
                ...local,
                first_title: genResult.result[0].first_topic,
                second_title: genResult.result[0].second_topic,
                prompts: [
                    local.prompts[0],
                    local.prompts[1],
                    ...genResult.result[0].prompts.map((item: any) => ({
                        text: item,
                        video_url: ""
                    }))
                ],
                difficulty: genResult.result[0].difficulty
            };
            setEditing(true);
            setLocal(updatedLocal);

            dispatch({
                type: "UPDATE_SECTION_SINGLE_FIELD",
                payload: {
                    sectionId,
                    module,
                    field: "generating",
                    value: undefined
                }
            });
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [genResult, generating]);

    useEffect(() => {
        if (genResult && generating === "video") {
            const updatedLocal = { ...local, prompts: genResult.result[0].prompts };
            setLocal(updatedLocal);

            dispatch({
                type: "UPDATE_SECTION_STATE",
                payload: { sectionId, update: updatedLocal, module }
            });


            dispatch({
                type: "UPDATE_SECTION_SINGLE_FIELD",
                payload: {
                    sectionId,
                    module,
                    field: "generating",
                    value: undefined
                }
            });
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [genResult, generating]);

    useEffect(() => {
        const speakingScript = levelGenResults?.find((res) => res.generating === `${local.id}-speakingScript`);
        const isGenerating = levelGenerating?.includes(`${local.id}-speakingScript`);

        if (speakingScript && isGenerating) {
            if (!difficulty.includes(speakingScript.result[0].difficulty)) {
                dispatch({ type: 'UPDATE_MODULE', payload: { updates: { difficulty: [...difficulty, speakingScript.result[0].difficulty]} } });
            }
            const updatedLocal = {
                ...local,
                first_title: speakingScript.result[0].first_topic,
                second_title: speakingScript.result[0].second_topic,
                difficulty: speakingScript.result[0].difficulty,
                prompts: [
                    local.prompts[0],
                    local.prompts[1],
                    ...speakingScript.result[0].prompts.map((item: any) => ({
                        text: item,
                        video_url: ""
                    }))
                ]
            };
            setEditing(true);
            setLocal(updatedLocal);

            dispatch({
                type: "UPDATE_SECTION_SINGLE_FIELD", payload: {
                    sectionId,
                    field: "levelGenerating",
                    value: levelGenerating.filter((g) => g !== `${local.id}-speakingScript`),
                    module
                }
            });
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [levelGenResults, levelGenerating]);

    useEffect(() => {
        const speakingVideo = levelGenResults?.find((res) => res.generating === `${local.id}-video`);
        const isGenerating = levelGenerating?.includes(`${local.id}-video`);

        if (speakingVideo && isGenerating) {
            const updatedLocal = { ...local, video_url: speakingVideo.result[0].video_url };
            setLocal(updatedLocal);

            const updatedState = {
                ...state,
                exercises: (state as LevelPart).exercises.map((ex) =>
                    ex.id === local.id ? updatedLocal : ex
                )
            };

            dispatch({
                type: "UPDATE_SECTION_STATE",
                payload: { sectionId, update: updatedState, module }
            });

            dispatch({
                type: "UPDATE_SECTION_SINGLE_FIELD", payload: {
                    sectionId,
                    field: "levelGenerating",
                    value: levelGenerating.filter((g) => g !== `${local.id}-video`),
                    module
                }
            });
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [levelGenResults, levelGenerating]);


    const addPrompt = () => {
        setLocal(prev => ({
            ...prev,
            prompts: [...prev.prompts, { text: "", video_url: "" }]
        }));
    };

    const removePrompt = (index: number) => {
        if (index < 2) return;
        setLocal(prev => ({
            ...prev,
            prompts: prev.prompts.filter((_, i) => i !== index)
        }));
    };

    const updatePrompt = (index: number, text: string) => {
        if (index < 2) return;
        setLocal(prev => {
            const newPrompts = [...prev.prompts];
            newPrompts[index] = { ...newPrompts[index], text };
            return { ...prev, prompts: newPrompts };
        });
    };

    const isUnedited = local.prompts.length === 2;


    useEffect(() => {
        if (genResult && generating === "video") {
            setLocal({ ...local, prompts: genResult.result[0].prompts });
            dispatch({ type: "UPDATE_SECTION_STATE", payload: { sectionId, update: { ...local, prompts: genResult.result[0].prompts }, module } });
            dispatch({
                type: "UPDATE_SECTION_SINGLE_FIELD",
                payload: {
                    sectionId,
                    module: module,
                    field: "generating",
                    value: undefined
                }
            });
            dispatch({
                type: "UPDATE_SECTION_SINGLE_FIELD",
                payload: {
                    sectionId,
                    module: module,
                    field: "genResult",
                    value: undefined
                }
            });
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [genResult, generating]);

    const handlePrevVideo = () => {
        setCurrentVideoIndex((prev) => (prev > 0 ? prev - 1 : prev));
    };

    const handleNextVideo = () => {
        setCurrentVideoIndex((prev) =>
            (prev < local.prompts.length - 1 ? prev + 1 : prev)
        );
    };

    const saveDifficulty = useCallback((diff: Difficulty)=> {
        if (!difficulty.includes(diff)) {
            dispatch({ type: 'UPDATE_MODULE', payload: { updates: { difficulty: [...difficulty, diff]} } });
        }
        if (module !== "level") {
            const updatedExercise = { ...exercise, difficulty: diff };
            dispatch({ type: 'UPDATE_SECTION_STATE', payload: { sectionId, update: updatedExercise, module: currentModule } });
        } else {
            const updatedExercise = { ...exercise, difficulty: diff };
            const newState = { ...state as LevelPart };
            newState.exercises = (newState as LevelPart).exercises.map((ex) => ex.id === exercise.id ? updatedExercise : ex );
            dispatch({ type: 'UPDATE_SECTION_STATE', payload: { sectionId, update: newState, module: currentModule } });
        }
    }, [currentModule, difficulty, dispatch, exercise, module, sectionId, state]);

    return (
        <>
            <div className='relative pb-4'>
                <Header
                    title={`Speaking 1 Script`}
                    description='Generate or write the scripts for the videos.'
                    editing={editing}
                    difficulty={exercise.difficulty}
                    saveDifficulty={saveDifficulty}
                    handleSave={handleSave}
                    handleEdit={handleEdit}
                    handleDiscard={handleDiscard}
                    handlePractice={handlePractice}
                    isEvaluationEnabled={!local.isPractice}
                    module="speaking"
                />
            </div>
            {(generating && generating === "speakingScript") || (levelGenerating.find((g) => g === `${local.id}-speakingScript`)) ? (
                <GenLoader module={module} />
            ) : (
                <>
                    {editing ? (
                        <>
                            <Card>
                                <CardContent>
                                    <div className="py-2 mt-2">
                                        <div className="flex flex-row mb-3 gap-4">
                                            <BsFileText className="h-5 w-5 text-blue-500 mt-1" />
                                            <h3 className="font-semibold text-xl">Titles</h3>
                                        </div>
                                        <div className="flex gap-6 mt-6">
                                            <div className="flex-1">
                                                <h2 className="font-semibold text-lg mb-2">First Title</h2>
                                                <AutoExpandingTextArea
                                                    value={local.first_title || ''}
                                                    onChange={(text) => setLocal(prev => ({ ...prev, first_title: 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 the first title"
                                                />
                                            </div>
                                            <div className="flex-1">
                                                <h2 className="font-semibold text-lg mb-2">Second Title</h2>
                                                <AutoExpandingTextArea
                                                    value={local.second_title || ''}
                                                    onChange={(text) => setLocal(prev => ({ ...prev, second_title: 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 the second title"
                                                />
                                            </div>
                                        </div>
                                    </div>
                                </CardContent>
                            </Card>
                            <Card>
                                <CardContent>
                                    <div className="flex items-center justify-between mb-4 mt-6">
                                        <h2 className="font-semibold text-xl">Questions</h2>
                                    </div>

                                    <div className="space-y-5">
                                        {local.prompts.length === 2 ? (
                                            <div className="py-12 text-center bg-gray-200 rounded-lg border-2 border-dashed border-gray-400">
                                                <p className="text-gray-600">No questions added yet</p>
                                            </div>
                                        ) : (
                                            local.prompts.slice(2).map((prompt, index) => (
                                                <Card key={index}>
                                                    <CardContent>
                                                        <div className="bg-gray-50 rounded-lg pt-4">
                                                            <div className="flex justify-between items-center mb-3">
                                                                <h3 className="font-medium text-gray-700">Question {index + 1}</h3>
                                                                <button
                                                                    type="button"
                                                                    className="p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 rounded-full transition-colors"
                                                                    onClick={() => removePrompt(index + 2)}
                                                                >
                                                                    <AiOutlineDelete className="h-5 w-5" />
                                                                </button>
                                                            </div>
                                                            <AutoExpandingTextArea
                                                                value={prompt.text}
                                                                onChange={(text) => updatePrompt(index + 2, text)}
                                                                className="w-full p-3 border border-gray-200 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent min-h-[80px] transition-all bg-white"
                                                                placeholder={`Enter question ${index + 1}`}
                                                            />
                                                        </div>
                                                    </CardContent>
                                                </Card>
                                            ))
                                        )}
                                    </div>

                                    <div className="mt-6">
                                        <button
                                            type="button"
                                            onClick={addPrompt}
                                            className="w-full py-3 px-4 bg-gray-50 border border-gray-200 rounded-lg hover:bg-gray-100 transition-colors flex items-center justify-center gap-2 text-gray-600 font-medium"
                                        >
                                            <AiOutlinePlus className="h-5 w-5" />
                                            Add Question
                                        </button>
                                    </div>
                                </CardContent>
                            </Card>
                        </>
                    ) : isUnedited ? (
                        <p className="w-full text-gray-600 px-7 py-8 border-2 bg-white rounded-3xl whitespace-pre-line">
                            Generate or edit the questions!
                        </p>
                    ) : (
                        <div className="space-y-6">
                            {local.prompts.every((p) => p.video_url !== "") && (
                                <Card>
                                    <CardContent className="pt-6">
                                        <div className="flex flex-col items-start gap-3">
                                            <div className="flex flex-row mb-3 gap-4 w-full justify-between items-center">
                                                <div className="flex flex-row gap-4">
                                                    <RiVideoLine className="h-5 w-5 text-amber-500 mt-1" />
                                                    <h3 className="font-semibold text-xl">Videos</h3>
                                                </div>
                                                <div className="flex items-center gap-4">
                                                    <button
                                                        onClick={handlePrevVideo}
                                                        disabled={currentVideoIndex === 0}
                                                        className={`p-2 rounded-full ${currentVideoIndex === 0
                                                            ? 'text-gray-400 cursor-not-allowed'
                                                            : 'text-gray-600 hover:bg-gray-100'
                                                            }`}
                                                    >
                                                        <FaChevronLeft className="w-4 h-4" />
                                                    </button>
                                                    <span className="text-sm text-gray-600">
                                                        {currentVideoIndex + 1} / {local.prompts.length}
                                                    </span>
                                                    <button
                                                        onClick={handleNextVideo}
                                                        disabled={currentVideoIndex === local.prompts.length - 1}
                                                        className={`p-2 rounded-full ${currentVideoIndex === local.prompts.length - 1
                                                            ? 'text-gray-400 cursor-not-allowed'
                                                            : 'text-gray-600 hover:bg-gray-100'
                                                            }`}
                                                    >
                                                        <FaChevronRight className="w-4 h-4" />
                                                    </button>
                                                </div>
                                            </div>
                                            <div className="flex flex-col gap-4 w-full items-center">
                                                <div className="w-full">
                                                    <video
                                                        key={local.prompts[currentVideoIndex].video_url}
                                                        controls
                                                        className="w-full rounded-xl"
                                                    >
                                                        <source src={local.prompts[currentVideoIndex].video_url} />
                                                    </video>
                                                </div>
                                            </div>
                                        </div>
                                    </CardContent>
                                </Card>
                            )}
                            {(generating && generating === "video") || levelGenerating.find((g) => g === `${local.id}-video`) &&
                                <GenLoader module={module} custom="Generating the videos ... This may take a while ..." />
                            }
                            <Card>
                                <CardContent className="pt-6">
                                    <div className="flex flex-col items-start">
                                        <div className="flex flex-row mb-4 gap-4">
                                            <BsFileText className="h-5 w-5 text-blue-500 mt-1" />
                                            <h3 className="font-semibold text-xl">Titles</h3>
                                        </div>
                                        <div className="w-full flex gap-6 mt-6">
                                            <div className="flex-1">
                                                <h4 className="font-medium text-gray-700 mb-2">First Title</h4>
                                                <div className="w-full px-4 py-3 bg-white shadow-inner rounded-lg border border-gray-100">
                                                    <p className="text-lg">{local.first_title || 'No first title'}</p>
                                                </div>
                                            </div>
                                            <div className="flex-1">
                                                <h4 className="font-medium text-gray-700 mb-2">Second Title</h4>
                                                <div className="w-full px-4 py-3 bg-white shadow-inner rounded-lg border border-gray-100">
                                                    <p className="text-lg">{local.second_title || 'No second title'}</p>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </CardContent>
                            </Card>
                            <Card>
                                <CardContent className="pt-6">
                                    <div className="flex flex-col items-start gap-3">
                                        <div className="flex flex-row mb-3 gap-4">
                                            <AiOutlineUnorderedList className="h-5 w-5 text-purple-500 mt-1" />
                                            <h3 className="font-semibold text-xl">Questions</h3>
                                        </div>
                                        <div className="w-full space-y-4">
                                            {local.prompts.slice(2)
                                                .filter(prompt => prompt.text !== "")
                                                .map((prompt, index) => (
                                                    <div key={index} className="bg-white shadow-inner rounded-lg border border-gray-100 p-4">
                                                        <h4 className="font-medium text-gray-700 mb-2">Question {index + 1}</h4>
                                                        <p className="text-gray-700">{prompt.text}</p>
                                                    </div>
                                                ))
                                            }
                                        </div>
                                    </div>
                                </CardContent>
                            </Card>
                        </div>
                    )}
                </>
            )}
        </>
    );
};

export default Speaking1;