import AutoExpandingTextArea from "@/components/Low/AutoExpandingTextarea";
import { Card, CardContent } from "@/components/ui/card";
import { AiOutlinePlus, AiOutlineDelete } from 'react-icons/ai';
import { LevelPart, SpeakingExercise } from "@/interfaces/exam";
import useExamEditorStore from "@/stores/examEditor";
import { useEffect, useState } from "react";
import useSectionEdit from "../../Hooks/useSectionEdit";
import Header from "../../Shared/Header";
import { Tooltip } from "react-tooltip";
import { BsFileText } from 'react-icons/bs';
import { AiOutlineUnorderedList } from 'react-icons/ai';
import { BiQuestionMark, BiMessageRoundedDetail } from "react-icons/bi";
import GenLoader from "../Shared/GenLoader";
import { RiVideoLine } from 'react-icons/ri';
import { Module } from "@/interfaces";

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

const Speaking2: React.FC<Props> = ({ sectionId, exercise, module = "speaking" }) => {
    const { dispatch } = useExamEditorStore();
    const [local, setLocal] = useState(exercise);

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

    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: section!.levelGenResults.filter((res) => res.generating !== `${local.id ? `${local.id}-` : ''}speakingScript`),
                        module
                    }
                })
            }   
        },
        onDiscard: () => {
            setLocal(exercise);
        },
        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") {
            const updatedLocal = {
                ...local,
                title: genResult.result[0].topic,
                text: genResult.result[0].question,
                prompts: genResult.result[0].prompts
            };
            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, video_url: genResult.result[0].video_url };
            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 generating = levelGenerating.find((res) => res === `${local.id}-speakingScript`);
        if (speakingScript && generating) {
            const updatedLocal = {
                ...local,
                title: speakingScript.result[0].topic,
                text: speakingScript.result[0].question,
                prompts: speakingScript.result[0].prompts
            };
            setEditing(true);
            setLocal(updatedLocal);
            dispatch({
                type: "UPDATE_SECTION_SINGLE_FIELD", payload: {
                    sectionId,
                    field: "levelGenerating",
                    value: section!.levelGenerating.filter((g) => g !== `${local.id ? `${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 generating = levelGenerating.find((res) => res === `${local.id}-video`);

        if (speakingVideo && generating) {
            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: section!.levelGenerating.filter((g) => g !== `${local.id ? `${local.id}-` : ''}video`),
                    module
                }
            });
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [levelGenResults, levelGenerating]);

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

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

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

    const isUnedited = local.text === "" ||
        (local.title === undefined || local.title === "") ||
        local.prompts.length === 0;

    const tooltipContent = `
        <div class='p-2 max-w-xs'>
        <p class='text-sm text-white'>
            Prompts are guiding points that help candidates structure their talk. They typically include aspects like:
            <ul class='list-disc pl-4 mt-1'>
            <li>Describing what/who/where</li>
            <li>Explaining why</li>
            <li>Sharing feelings or preferences</li>
            </ul>
        </p>
        </div>
    `;

    return (
        <>
            <div className='relative pb-4'>
                <Header
                    title={`Speaking ${module === "level" ? local.sectionId : sectionId} Script`}
                    description='Generate or write the script for the video.'
                    editing={editing}
                    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="flex flex-col py-2 mt-2">
                                        <h2 className="font-semibold text-xl mb-2">Title</h2>
                                        <AutoExpandingTextArea
                                            value={local.title || ''}
                                            onChange={(text) => setLocal(prev => ({ ...prev, 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 topic"
                                        />
                                    </div>
                                </CardContent>
                            </Card>
                            <Card>
                                <CardContent>
                                    <div className="flex flex-col py-2 mt-2">
                                        <h2 className="font-semibold text-xl mb-2">Question</h2>
                                        <AutoExpandingTextArea
                                            value={local.text}
                                            onChange={(text) => setLocal(prev => ({ ...prev, text: 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 main question"
                                        />
                                    </div>
                                </CardContent>
                            </Card>
                            <Card>
                                <CardContent>
                                    <div className="flex items-center justify-between mb-4 mt-6">
                                        <h2 className="font-semibold text-xl">Prompts</h2>
                                        <Tooltip id="prompt-tp" />
                                        <a
                                            data-tooltip-id="prompt-tp"
                                            data-tooltip-html={tooltipContent}
                                            className='ml-1 w-6 h-6 flex items-center justify-center rounded-full hover:bg-gray-200 border bg-gray-100'
                                        >
                                            <BiQuestionMark
                                                className="w-5 h-5 text-gray-500"
                                            />
                                        </a>
                                    </div>

                                    <div className="space-y-5">
                                        {local.prompts.length === 0 ? (
                                            <div className="py-12 text-center bg-gray-200 rounded-lg border-2 border-dashed border-gray-400">
                                                <p className="text-gray-600">No prompts added yet</p>
                                            </div>
                                        ) : (
                                            local.prompts.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">Prompt {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)}
                                                                >
                                                                    <AiOutlineDelete className="h-5 w-5" />
                                                                </button>
                                                            </div>
                                                            <AutoExpandingTextArea
                                                                value={prompt}
                                                                onChange={(text) => updatePrompt(index, 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 prompt ${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 Prompt
                                        </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 script!
                        </p>
                    ) : (
                        <div className="space-y-6">
                            {local.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">
                                            <RiVideoLine className="h-5 w-5 text-amber-500 mt-1" />
                                            <h3 className="font-semibold text-xl">Video</h3>
                                        </div>
                                        <div className="flex flex-col gap-4 w-full items-center">
                                            <video controls className="w-full rounded-xl">
                                                <source src={local.video_url} />
                                            </video>
                                        </div>
                                    </div>
                                </CardContent>
                            </Card>
                            }
                            {((generating === "video") || (levelGenerating.find((g) => g === `${local.id}-video`) !== undefined)) &&
                                <GenLoader module={module} custom="Generating the video ... This may take a while ..." />
                            }
                            <Card>
                                <CardContent className="pt-6">
                                    <div className="flex flex-col items-start gap-3">
                                        <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">Title</h3>
                                        </div>
                                        <div className="w-full px-4 py-3 bg-white shadow-inner rounded-lg border border-gray-100">
                                            <p className="text-lg">{local.title || 'Untitled'}</p>
                                        </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">
                                            <BiMessageRoundedDetail className="h-5 w-5 text-green-500 mt-1" />
                                            <h3 className="font-semibold text-xl">Question</h3>
                                        </div>
                                        <div className="w-full px-4 py-3 bg-white shadow-inner rounded-lg border border-gray-100">
                                            <p className="text-lg">{local.text || 'No question provided'}</p>
                                        </div>
                                    </div>
                                </CardContent>
                            </Card>
                            {local.prompts && local.prompts.length > 0 && (
                                <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">Prompts</h3>
                                            </div>
                                            <div className="w-full p-4 bg-gray-50 shadow-inner rounded-lg border border-gray-100">
                                                <div className="flex flex-col gap-3">
                                                    {local.prompts.map((prompt, index) => (
                                                        <div key={index} className="px-4 py-3 bg-white shadow rounded-lg border border-gray-100">
                                                            <p className="text-gray-700">{prompt}</p>
                                                        </div>
                                                    ))}
                                                </div>
                                            </div>
                                        </div>
                                    </CardContent>
                                </Card>
                            )}
                        </div>
                    )}
                </>
            )}
        </>
    );
}

export default Speaking2;