import { useCallback, useEffect, useState } from "react";
import { LevelPart, ListeningPart, Script } from "@/interfaces/exam";
import SectionContext from ".";
import useExamEditorStore from "@/stores/examEditor";
import useSectionEdit from "../../Hooks/useSectionEdit";
import ScriptRender from "../../Exercises/Script";
import { Card, CardContent } from "@/components/ui/card";
import Dropdown from "@/components/Dropdown";
import AudioPlayer from "@/components/Low/AudioPlayer";
import { MdHeadphones } from "react-icons/md";
import clsx from "clsx";
import { Module } from "@/interfaces";
import GenLoader from "../../Exercises/Shared/GenLoader";

interface Props {
    module: Module;
    sectionId: number;
    listeningSection?: number;
    level?: boolean;
}


const ListeningContext: React.FC<Props> = ({ sectionId, module, listeningSection, level = false }) => {
    const { dispatch } = useExamEditorStore();
    const { genResult, state, generating, levelGenResults, levelGenerating, scriptLoading } = useExamEditorStore(
        (state) => state.modules[module].sections.find((section) => section.sectionId === sectionId)!
    );

    const listeningPart = state as ListeningPart | LevelPart;
    const [isDialogDropdownOpen, setIsDialogDropdownOpen] = useState(false);

    const [scriptLocal, setScriptLocal] = useState(listeningPart.script);

    const { editing, handleSave, handleDiscard, setEditing, handleEdit } = useSectionEdit({
        sectionId,
        onSave: () => {
            const newState = { ...listeningPart };
            newState.script = scriptLocal;
            dispatch({ type: 'UPDATE_SECTION_STATE', payload: { sectionId, update: newState, module } })
            setEditing(false);

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

            if (levelGenResults.find((res) => res.generating === "listeningScript")) {
                dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { sectionId, module, field: "levelGenResults", value: levelGenResults.filter((res) => res.generating !== "listeningScript") } })
            }
        },
        onDiscard: () => {
            setScriptLocal(listeningPart.script);
        },
    });

    useEffect(() => {
        if (listeningPart.script == undefined) {
            setScriptLocal(undefined);
        } else {
            setScriptLocal(listeningPart.script);
        }
    }, [listeningPart])

    useEffect(() => {
        if (genResult && generating === "listeningScript") {
            setEditing(true);
            setScriptLocal(genResult.result[0].script);
            setIsDialogDropdownOpen(true);
            dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { sectionId, module, field: "generating", value: undefined } })
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [genResult]);

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

    useEffect(() => {
        const scriptRes = levelGenResults.find((res) => res.generating === "listeningScript");
        if (levelGenResults && scriptRes) {
            setEditing(true);
            setScriptLocal(scriptRes.result[0].script);
            dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { sectionId, module, field: "levelGenerating", value: levelGenerating.filter(g => g !== "listeningScript") } })
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [levelGenResults]);


    useEffect(() => {
        const scriptRes = levelGenResults.find((res) => res.generating === "audio");
        if (levelGenResults && scriptRes) {
            dispatch({ type: "UPDATE_SECTION_SINGLE_FIELD", payload: { sectionId, module, field: "levelGenerating", value: levelGenerating.filter(g => g !== "audio") } })
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [levelGenResults]);

    const memoizedRenderContent = useCallback(() => {
        if (scriptLocal === undefined && !editing && !scriptLoading) {
            return (
                <Card>
                    <CardContent className="py-10">
                        <span>Edit, generate or import your own audio.</span>
                    </CardContent>
                </Card>
            );
        }
        return (
            <>
                {(generating === "audio" || scriptLoading) ? (
                    <GenLoader
                        module="listening"
                        custom={scriptLoading ? 'Transcribing Audio ...' : 'Generating audio ...'}
                    />
                ) : (
                    <>
                        {listeningPart.audio?.source !== undefined && (
                            <AudioPlayer
                                key={`${sectionId}-${scriptLocal?.length}`}
                                src={listeningPart.audio?.source ?? ''}
                                color="listening"
                            />
                        )}
                    </>
                )}
                {!scriptLoading && <Dropdown
                    className="mt-8 w-full flex items-center justify-between p-4 bg-white hover:bg-gray-50 transition-colors border rounded-xl border-gray-200"
                    contentWrapperClassName="rounded-xl mt-2"
                    customTitle={
                        <div className="flex items-center space-x-3">
                            <MdHeadphones className={clsx(
                                "h-5 w-5",
                                `text-ielts-${module}`
                            )} />
                            <span className="font-medium text-gray-900">
                                {listeningSection === undefined
                                    ? ([1, 3].includes(sectionId) ? "Conversation" : "Monologue")
                                    : ([1, 3].includes(listeningSection) ? "Conversation" : "Monologue")}
                            </span>
                        </div>
                    }
                    open={isDialogDropdownOpen}
                    setIsOpen={setIsDialogDropdownOpen}
                >
                    <ScriptRender
                        key={scriptLocal?.length}
                        local={scriptLocal}
                        setLocal={setScriptLocal}
                        section={level ? listeningSection! : sectionId}
                        editing={editing}
                    />
                </Dropdown>
                }
            </>
        );
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [
        scriptLoading,
        generating,
        listeningPart.audio?.source,
        listeningPart.script,
        sectionId,
        module,
        isDialogDropdownOpen,
        setIsDialogDropdownOpen,
        setScriptLocal,
        level,
        scriptLocal,
        editing,
        listeningSection
    ]);

    return (
        <SectionContext
            sectionId={sectionId}
            title={
                listeningSection === undefined ?
                    ([1, 3].includes(sectionId) ? "Conversation" : "Monologue") :
                    ([1, 3].includes(listeningSection) ? "Conversation" : "Monologue")
            }
            description={`Enter the section's ${(sectionId === 1 || sectionId === 3) ? "conversation" : "monologue"} or import your own`}
            renderContent={memoizedRenderContent}
            editing={editing}
            onSave={handleSave}
            onEdit={handleEdit}
            onDiscard={handleDiscard}
            module={module}
            context="listeningScript"
        />
    );
};

export default ListeningContext;
