import { useEffect, useRef, useState } from "react";
import { BsStars } from "react-icons/bs";
import { FaSpinner } from "react-icons/fa";
import { MdClose } from "react-icons/md";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import TaleButton from "@components/TaleButton";
import { aiService } from "@/api/ai";
import { useTranslation } from "@/hooks/useTranslation";

/**
 * A conversation about the survey being edited, beside the questions themselves.
 *
 * It replaces the assistant that used to sit behind a button on every question card: that one could
 * only rewrite the question it was opened from, and ran the guided agent, which insists on framing a
 * whole study first. Here the person talks about the survey as a whole - "add something on price
 * sensitivity", "we need the company size" - and gets back questions they can check, adjust and
 * add, while still seeing the ones already there.
 *
 * Each message carries the survey as it stands, so a suggestion never repeats a question added a
 * minute ago. The conversation is kept per survey for the browser session, so leaving the step to
 * preview and coming back does not lose it.
 */

/** The question types the editor can show, in the order people reach for them. */
const ASSIST_TYPES = ["RADIO", "CHECKBOX", "COMMENT", "SCALE_OF_TEN", "STARS", "SMILE"];
const CHOICE_TYPES = ["RADIO", "CHECKBOX"];

const storageKey = (surveyId) => `tale.questionAssistant.${surveyId}`;

const loadConversation = (surveyId) => {
    try {
        const saved = JSON.parse(sessionStorage.getItem(storageKey(surveyId)) || "[]");
        return Array.isArray(saved) ? saved : [];
    } catch {
        // Blocked or corrupt storage: start fresh rather than fail to open the panel.
        return [];
    }
};

const saveConversation = (surveyId, entries) => {
    try {
        sessionStorage.setItem(storageKey(surveyId), JSON.stringify(entries));
    } catch {
        /* see loadConversation */
    }
};

export const QuestionAssistantPanel = ({
    surveyId,
    surveyTitle,
    surveyCategory,
    surveyLanguage,
    questions = [],
    onAddQuestions,
    onClose,
}) => {
    const { t } = useTranslation();
    // Each entry: { role: "user" | "assistant" | "error", content, suggestions?: [{ ...question, added }] }
    const [entries, setEntries] = useState(() => loadConversation(surveyId));
    const [draft, setDraft] = useState("");
    const [thinking, setThinking] = useState(false);
    const [adding, setAdding] = useState(false);
    const scroller = useRef(null);

    useEffect(() => saveConversation(surveyId, entries), [surveyId, entries]);

    useEffect(() => {
        scroller.current?.scrollTo({ top: scroller.current.scrollHeight, behavior: "smooth" });
    }, [entries, thinking]);

    const send = async () => {
        const message = draft.trim();
        if (!message || thinking) return;

        const next = [...entries, { role: "user", content: message }];
        setEntries(next);
        setDraft("");
        setThinking(true);

        try {
            const answer = await aiService.assistQuestions({
                // Errors shown in the panel are ours, not part of what was said.
                messages: next
                    .filter((e) => e.role === "user" || e.role === "assistant")
                    .map((e) => ({ role: e.role, content: e.content })),
                survey: {
                    title: surveyTitle,
                    category: surveyCategory,
                    language: surveyLanguage,
                    existingQuestions: questions.map((q) => q.question_text).filter(Boolean),
                },
            });
            const suggestions = (answer?.questions ?? []).map((q) => ({ ...q, added: false }));
            setEntries((current) => [
                ...current,
                {
                    role: "assistant",
                    content:
                        answer?.reply ||
                        (suggestions.length ? "" : t("surveyBuilder.questionAssistant.emptyReply")),
                    suggestions,
                },
            ]);
        } catch (error) {
            setEntries((current) => [
                ...current,
                {
                    role: "error",
                    content: error.timedOut
                        ? t("surveyBuilder.questionAssistant.timedOut")
                        : error.serverMessage || t("surveyBuilder.questionAssistant.unavailable"),
                },
            ]);
        } finally {
            setThinking(false);
        }
    };

    const updateSuggestion = (entryIndex, suggestionIndex, patch) =>
        setEntries((current) =>
            current.map((entry, i) =>
                i !== entryIndex
                    ? entry
                    : {
                          ...entry,
                          suggestions: entry.suggestions.map((s, j) =>
                              j === suggestionIndex ? { ...s, ...patch } : s
                          ),
                      }
            )
        );

    const add = async (entryIndex, suggestionIndexes) => {
        const entry = entries[entryIndex];
        const chosen = suggestionIndexes
            .map((j) => ({ j, suggestion: entry.suggestions[j] }))
            .filter(({ suggestion }) => !suggestion.added && suggestion.text.trim());
        if (!chosen.length) return;

        setAdding(true);
        try {
            await onAddQuestions(chosen.map(({ suggestion }) => suggestion));
            chosen.forEach(({ j }) => updateSuggestion(entryIndex, j, { added: true }));
        } catch {
            setEntries((current) => [
                ...current,
                { role: "error", content: t("surveyBuilder.questionAssistant.addFailed") },
            ]);
        } finally {
            setAdding(false);
        }
    };

    return (
        <div className="flex flex-col h-full bg-white rounded-2xl border shadow-sm overflow-hidden">
            <div className="flex items-center justify-between px-4 py-3 border-b">
                <div className="flex items-center gap-2">
                    <BsStars className="size-5 text-[#00BDA9]" />
                    <h2 className="font-semibold text-base">{t("surveyBuilder.questionAssistant.title")}</h2>
                </div>
                <div className="flex items-center gap-3">
                    {entries.length > 0 && (
                        <button
                            type="button"
                            className="text-xs text-gray-500 hover:text-gray-800"
                            onClick={() => setEntries([])}
                        >
                            {t("surveyBuilder.questionAssistant.clear")}
                        </button>
                    )}
                    {onClose && (
                        <button
                            type="button"
                            aria-label={t("surveyBuilder.questionAssistant.close")}
                            onClick={onClose}
                        >
                            <MdClose />
                        </button>
                    )}
                </div>
            </div>

            <div ref={scroller} className="flex-1 overflow-y-auto px-4 py-3 flex flex-col gap-3">
                {!entries.length && (
                    <div className="text-sm text-gray-500 flex flex-col gap-2">
                        <p>{t("surveyBuilder.questionAssistant.intro")}</p>
                        {["exampleOne", "exampleTwo", "exampleThree"].map((key) => (
                            <button
                                key={key}
                                type="button"
                                className="text-left rtl:text-right text-[#00BDA9] hover:underline"
                                onClick={() => setDraft(t(`surveyBuilder.questionAssistant.${key}`))}
                            >
                                “{t(`surveyBuilder.questionAssistant.${key}`)}”
                            </button>
                        ))}
                    </div>
                )}

                {entries.map((entry, i) => (
                    <div key={i} className="flex flex-col gap-2">
                        {entry.role === "user" && (
                            <p className="self-end max-w-[90%] rounded-2xl !rounded-tr-none bg-[#00000010] px-3 py-2 text-sm whitespace-pre-line">
                                {entry.content}
                            </p>
                        )}
                        {entry.role === "error" && (
                            <p className="text-sm text-red-600 bg-red-50 rounded-lg px-3 py-2">{entry.content}</p>
                        )}
                        {entry.role === "assistant" && (
                            <>
                                {entry.content && (
                                    <div className="markdown-body text-sm text-gray-700">
                                        <ReactMarkdown remarkPlugins={[remarkGfm]}>{entry.content}</ReactMarkdown>
                                    </div>
                                )}
                                {entry.suggestions?.map((s, j) => (
                                    <SuggestionCard
                                        key={j}
                                        suggestion={s}
                                        disabled={adding}
                                        onChange={(patch) => updateSuggestion(i, j, patch)}
                                        onAdd={() => add(i, [j])}
                                    />
                                ))}
                                {entry.suggestions?.filter((s) => !s.added).length > 1 && (
                                    <TaleButton
                                        role="normal"
                                        className="!w-fit !h-[36px] !px-4 self-end"
                                        disabled={adding}
                                        onClick={() => add(i, entry.suggestions.map((_, j) => j))}
                                    >
                                        {t("surveyBuilder.questionAssistant.addAll")}
                                    </TaleButton>
                                )}
                            </>
                        )}
                    </div>
                ))}

                {thinking && (
                    <p className="flex items-center gap-2 text-sm text-gray-500">
                        <FaSpinner className="animate-spin text-[#00BDA9]" />
                        {t("surveyBuilder.questionAssistant.thinking")}
                    </p>
                )}
            </div>

            <form
                className="border-t px-3 py-3 flex gap-2 items-end"
                onSubmit={(e) => {
                    e.preventDefault();
                    send();
                }}
            >
                <textarea
                    value={draft}
                    onChange={(e) => setDraft(e.target.value)}
                    onKeyDown={(e) => {
                        // Enter sends; Shift+Enter keeps writing a longer brief.
                        if (e.key === "Enter" && !e.shiftKey) {
                            e.preventDefault();
                            send();
                        }
                    }}
                    rows={2}
                    placeholder={t("surveyBuilder.questionAssistant.placeholder")}
                    className="grow min-w-0 resize-none rounded-xl border px-3 py-2 text-sm outline-none focus:border-[#00BDA9]"
                />
                <TaleButton
                    role="normal"
                    type="submit"
                    className="!w-fit shrink-0 !h-[40px] !px-4"
                    disabled={thinking || !draft.trim()}
                >
                    {t("surveyBuilder.questionAssistant.send")}
                </TaleButton>
            </form>
        </div>
    );
};

/** One proposed question, editable before it is added: wording, type, answers, mandatory. */
const SuggestionCard = ({ suggestion, disabled, onChange, onAdd }) => {
    const { t } = useTranslation();
    const isChoice = CHOICE_TYPES.includes(suggestion.questionType);

    return (
        <div
            className={`rounded-xl border p-3 flex flex-col gap-2 ${
                suggestion.added ? "bg-gray-50 opacity-70" : ""
            }`}
        >
            <textarea
                value={suggestion.text}
                disabled={suggestion.added}
                onChange={(e) => onChange({ text: e.target.value })}
                rows={2}
                className="w-full resize-none rounded-lg border px-2 py-1 text-sm font-medium outline-none focus:border-[#00BDA9]"
            />
            <div className="flex flex-wrap items-center gap-3">
                <select
                    value={suggestion.questionType}
                    disabled={suggestion.added}
                    onChange={(e) => onChange({ questionType: e.target.value })}
                    className="rounded-lg border px-2 py-1 text-xs"
                >
                    {ASSIST_TYPES.map((type) => (
                        <option key={type} value={type}>
                            {t(`surveyBuilder.questionAssistant.types.${type}`)}
                        </option>
                    ))}
                </select>
                <label className="flex items-center gap-1 text-xs text-gray-600">
                    <input
                        type="checkbox"
                        checked={!!suggestion.mandatory}
                        disabled={suggestion.added}
                        onChange={(e) => onChange({ mandatory: e.target.checked })}
                    />
                    {t("surveyBuilder.questionAssistant.mandatory")}
                </label>
            </div>
            {isChoice && (
                <div className="flex flex-col gap-1">
                    <span className="text-xs text-gray-500">{t("surveyBuilder.questionAssistant.answersHint")}</span>
                    <textarea
                        value={(suggestion.options ?? []).join("\n")}
                        disabled={suggestion.added}
                        onChange={(e) => onChange({ options: e.target.value.split("\n") })}
                        rows={Math.min(8, Math.max(2, (suggestion.options ?? []).length))}
                        className="w-full resize-y rounded-lg border px-2 py-1 text-xs outline-none focus:border-[#00BDA9]"
                    />
                </div>
            )}
            <div className="flex justify-end">
                {suggestion.added ? (
                    <span className="text-xs font-semibold text-[#00BDA9]">
                        {t("surveyBuilder.questionAssistant.added")}
                    </span>
                ) : (
                    <TaleButton
                        role="normal"
                        variant="outlined"
                        className="!w-fit !h-[32px] !px-3 !text-xs"
                        disabled={disabled || !suggestion.text.trim()}
                        onClick={onAdd}
                    >
                        {t("surveyBuilder.questionAssistant.add")}
                    </TaleButton>
                )}
            </div>
        </div>
    );
};

export default QuestionAssistantPanel;
