import React, {
    Suspense,
    useCallback,
    useEffect,
    useLayoutEffect,
    useRef,
    useState,
} from "react";
import { Link /*useParams*/, useNavigate } from "react-router-dom";

// import { fetchBalanceInLocaleCurrency } from "@pages/Dashboard/Api";
import "@assets/style/global.css";
import TaleButton from "@components/TaleButton";
import { TaleLoadingFallback } from "@components/TaleLoadingFallback";
import { TaleBorderFul } from "@components/TaleBorderFul";
import { IntroSamples } from "@pages/survey/new/ai/IntroSamples";
import { lazily } from "react-lazily";
import { FaSpinner } from "react-icons/fa";
import { TaleModal } from "@components/TaleModal";
import { TaleAreYouSure } from "@components/TaleAreYouSure";
import { AgentChat } from "@pages/survey/new/ai/AgentChat";
import { useLayoutSidebarVisible } from "@/hooks/useLayoutSidebarVisible";
import { aiService } from "@/api/ai";
import { useTranslation } from "@/hooks/useTranslation";
import { agentItemsToQuestions, agentLanguage } from "@/api/agent";

const { Messages } = lazily(() => import("@pages/survey/new/ai/Messages"));

const DraftGenerated = React.lazy(() =>
    import("@pages/survey/new/ai/DraftGenerated")
);

// const opencage = require("opencage-api-client");

const SurveyAIGeneration = ({ basePath = "/survey/new" }) => {
    const { t } = useTranslation();
    useLayoutSidebarVisible(false);
    const nav = useNavigate();

    const [state, setstate] = useState({
        fixTextareaHeight: true,
        messages: [],
        canSendMessages: true,
        loadingDraftGeneration: false,
        showDraftGenerationSettings: false,
        draft: {},
        textareaOverflow: false,
        warnLeavingConversation: null,
    });

    // Two ways to get a survey written, and they are not variations of one another: "fast" is a
    // chat with a model that answers in seconds, "guided" is the Tale agent walking through its
    // phases for several minutes. Each keeps its own conversation, so switching to compare does not
    // throw the other one away.
    const [mode, setMode] = useState("fast");

    const hasOverflow = useCallback((el) => {
        return el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth;
    }, []);

    const adjustHeight = useCallback(() => {
        if (state.loadingDraftGeneration) {
            textbox.current.value = "";
            return;
        }
        textbox.current.style.height = "inherit";
        textbox.current.style.height = `${textbox.current.scrollHeight}px`;
        const value = textbox.current.scrollHeight <= 48 || !textbox.current.value;
        const overflowStatus = hasOverflow(textbox.current);
        setstate((prev) => ({
            ...prev,
            textareaOverflow:
                overflowStatus !== prev.textareaOverflow
                    ? overflowStatus
                    : prev.textareaOverflow,
            fixTextareaHeight:
                prev.fixTextareaHeight !== value ? value : prev.fixTextareaHeight,
        }));
    }, [state.loadingDraftGeneration, hasOverflow]);

    const textbox = useRef(null);

    useLayoutEffect(adjustHeight, [adjustHeight]);

    const addMessage = useCallback(
        async ({ isAI = false, content = "" }) => {
            if (
                state.loadingDraftGeneration ||
                !state.canSendMessages ||
                (!isAI && !content)
            )
                return;
            const message = {
                role: isAI ? "assistant" : "user",
                content,
            };
            const newMessagesList = [...state.messages, message];
            setstate((prev) => ({
                ...prev,
                canSendMessages: isAI, // if sent by isAI, then user can send message again
                messages: [...prev.messages, message],
            }));

            if (isAI) return; // if message sent by AI, it has nothing more to do :)

            textbox.current.value = "";
            adjustHeight();

            let response;
            try {
                response = await aiService.sendMessage(newMessagesList, "stats");
            } catch (error) {
                // Say why instead of leaving an empty bubble: the backend's message names the cause
                // and, for an administrator, the fix.
                addMessage({
                    isAI: true,
                    content: error?.serverMessage || t("aiAssistant.unavailable"),
                });
                return;
            }

            const AIReturned = aiService.parseSurveyFormat(response?.reply ?? "");
            addMessage({
                isAI: true,
                content: AIReturned.text ?? response?.reply ?? t("aiAssistant.emptyReply"),
            });
            if (AIReturned.generate_draft) {
                setstate((prev) => ({ ...prev, loadingDraftGeneration: true }));
                try {
                    const draft = await aiService.generateDraft(state.messages);
                    setstate((prev) => ({
                        ...prev,
                        loadingDraftGeneration: false,
                        showDraftGenerationSettings: true,
                        draft,
                    }));
                } catch (error) {
                    // A draft that never arrives must not leave the page waiting for it forever.
                    setstate((prev) => ({ ...prev, loadingDraftGeneration: false }));
                    addMessage({
                        isAI: true,
                        content: error?.serverMessage || t("aiAssistant.unavailable"),
                    });
                }
            }
        },
        [
            adjustHeight,
            state.canSendMessages,
            state.loadingDraftGeneration,
            state.messages,
            t,
        ]
    );

    useEffect(() => {
        const listenToTyping = (e) => {
            // Ignore if already focused on an input/textarea
            if (document.activeElement === textbox.current) return;

            // Only allow single character keys (letters, numbers, symbols)
            if (e.key.length === 1) {
                e.preventDefault(); // prevent accidental side effects (like scrolling with space)

                // Focus the textbox
                textbox.current.focus();

                // Insert the pressed key at the end of value
                textbox.current.value += e.key;

                // Move caret to end
                textbox.current.setSelectionRange(
                    textbox.current.value.length,
                    textbox.current.value.length
                );
            }
        };
        const listenToSend = (e) => {
            // If focused on the textbox
            if (document.activeElement === textbox.current) {
                if (e.ctrlKey && e.key === "Enter") {
                    e.preventDefault();
                    addMessage({ isAI: false, content: textbox.current.value });
                }
            }
        };
        document.addEventListener("keydown", listenToTyping);
        document.addEventListener("keydown", listenToSend);
        return () => {
            document.removeEventListener("keydown", listenToTyping);
            document.removeEventListener("keydown", listenToSend);
        };
    }, [addMessage]);

    return (
        <>
            {state.showDraftGenerationSettings && (
                <TaleModal className="flex items-center justify-center bg-black bg-opacity-40 !px-0">
                    <DraftGenerated rawDraft={state.draft} basePath={basePath} />
                </TaleModal>
            )}
            <div
                className={`shadow-lg flex flex-col justify-between p-4 min-h-[calc(100vh-100px)] max-h-[calc(100vh-100px)] ${
                    state.messages.length ? "gap-0" : "gap-12"
                }`}
                style={{
                    textAlign: "left",
                    background: "white",
                    borderRadius: 16,
                    position: "relative",
                }}
            >
                {/* TOP PART */}
                <div
                    className={`w-full flex justify-between items-center ${
                        state.messages.length ? "mb-12" : ""
                    }`}
                >
                    <div className="flex flex-col gap-0">
                        {/* AI DOES THE REST */}
                        <div className="flex gap-2">
                            <div
                                style={{
                                    color: "Black",
                                    fontSize: 34,
                                    fontFamily: "revert",
                                    fontWeight: "700",
                                    wordWrap: "break-word",
                                    textAlign: "left",
                                }}
                            >
                                {t("surveyBuilder.ai.enterQuery")}{" "}
                            </div>
                            <div
                                style={{
                                    background:
                                        "linear-gradient(90deg, #F9BC33 0%, #FE346E 100%)",
                                    WebkitBackgroundClip: "text",
                                    WebkitTextFillColor: "transparent",
                                    fontSize: 34,
                                    fontFamily: "revert",
                                    fontWeight: "700",
                                    wordWrap: "break-word",
                                }}
                            >
                                {t("surveyBuilder.ai.aiDoesRest")}
                            </div>
                        </div>
                        {/* COMPOSE QUERY */}
                        <div
                            style={{
                                color: "Black",
                                fontSize: 20,
                                fontFamily: "revert",
                                fontWeight: "400",
                                wordWrap: "break-word",
                                textAlign: "left",
                            }}
                        >
                            {t("surveyBuilder.ai.composeQueryHint")}{" "}
                        </div>
                    </div>
                    <div className="flex gap-3 items-center">
                        <div className="flex rounded-full border p-1 bg-gray-50">
                            {["fast", "guided"].map((option) => (
                                <button
                                    key={option}
                                    type="button"
                                    onClick={() => setMode(option)}
                                    className={`px-4 py-2 rounded-full text-sm transition-colors ${
                                        mode === option
                                            ? "bg-white shadow font-semibold text-[#00BDA9]"
                                            : "text-gray-500"
                                    }`}
                                >
                                    {t(`surveyBuilder.ai.mode.${option}`)}
                                </button>
                            ))}
                        </div>
                        <Link
                            onClick={(e) => {
                                if (state.messages.length) {
                                    e.preventDefault();
                                    setstate((prev) => ({
                                        ...prev,
                                        warnLeavingConversation: {
                                            text: t("surveyBuilder.ai.unsavedDataWarning"),
                                            onConfirm: () => nav(`${basePath}/simple`),
                                        },
                                    }));
                                }
                            }}
                            to={`${basePath}/simple`}
                        >
                            <TaleButton role="normal">{t("surveyBuilder.ai.useTemplate")}</TaleButton>
                        </Link>
                        <Link
                            onClick={(e) => {
                                if (state.messages.length) {
                                    e.preventDefault();
                                    setstate((prev) => ({
                                        ...prev,
                                        warnLeavingConversation: {
                                            text: t("surveyBuilder.ai.unsavedDataWarning"),
                                            onConfirm: () => nav(`${basePath}/scratch`),
                                        },
                                    }));
                                }
                            }}
                            to={`${basePath}/scratch`}
                        >
                            <TaleButton role="normal">{t("surveyBuilder.ai.createFromZero")}</TaleButton>
                        </Link>
                    </div>
                </div>

                {mode === "guided" ? (
                    <AgentChat
                        onFinished={(finished) =>
                            setstate((prev) => ({
                                ...prev,
                                // The agent's questionnaire joins the same road as a chat draft:
                                // link a brand, create the survey, open it for editing.
                                showDraftGenerationSettings: true,
                                draft: {
                                    title: t("surveyBuilder.agent.draftTitle"),
                                    description: "",
                                    language: agentLanguage(finished.langue_questionnaire),
                                    category: "",
                                    questions: agentItemsToQuestions(finished.items),
                                },
                            }))
                        }
                    />
                ) : !state.messages.length ? (
                    <IntroSamples ref={textbox} adjustHeight={adjustHeight} />
                ) : (
                    <Suspense fallback={<TaleLoadingFallback className="!py-20" />}>
                        <Messages
                            messages={state.messages}
                            canSendMessages={state.canSendMessages}
                        />
                    </Suspense>
                )}

                <div className={`flex items-center justify-center w-full ${mode === "guided" ? "hidden" : ""}`}>
                    <TaleBorderFul
                        role="normal"
                        className="flex gap-3 w-11/12"
                        directContainerClassName={`!rounded-2xl !justify-between ${
                            state.textareaOverflow ? "!items-end" : "!items-center"
                        } !py-1 pr-2`}
                        bgClassName="!rounded-2xl"
                    >
            <textarea
                ref={textbox}
                style={{
                    color: "#666666",
                    fontSize: 18,
                    fontFamily: "revert",
                    fontWeight: "400",
                    scrollbarWidth: state.textareaOverflow ? "thin" : "none",
                }}
                className={`basis-11/12 outline-none !ml-4 max-h-24 overflow-y-scroll !font-sans pt-2 resize-none ${
                    state.fixTextareaHeight ? "!h-12" : ""
                }`}
                onChange={adjustHeight}
                placeholder={t("surveyBuilder.ai.textareaPlaceholder")}
            />
                        <button
                            onClick={() =>
                                addMessage({ isAI: false, content: textbox.current.value })
                            }
                            className="bg-tale-blue-light rounded-full !size-10 flex items-center justify-center"
                        >
                            {!state.loadingDraftGeneration ? (
                                <img
                                    src={process.env.PUBLIC_URL + "/send.png"}
                                    alt={t("surveyBuilder.ai.sendAlt")}
                                    className="!max-h-5 !max-w-6 rtl:-scale-x-100"
                                />
                            ) : (
                                <FaSpinner className="animate-spin" />
                            )}
                        </button>
                    </TaleBorderFul>
                </div>
            </div>
            {state.warnLeavingConversation && (
                <TaleModal className="flex items-center justify-center">
                    <TaleAreYouSure
                        onCancel={() =>
                            setstate((prev) => ({ ...prev, warnLeavingConversation: null }))
                        }
                        onConfirm={state.warnLeavingConversation.onConfirm}
                        text={state.warnLeavingConversation.text}
                        title={t("surveyBuilder.ai.leavePage")}
                    />
                </TaleModal>
            )}
        </>
    );
};

export default SurveyAIGeneration;