'use client'
import React, {ChangeEvent, forwardRef, useContext, useEffect, useImperativeHandle, useState} from "react";
import {BookContext, BookContextProps} from "@/context/BookContext";
import {SessionContext, SessionContextProps} from "@/context/SessionContext";
import {AlertContext, AlertContextProps} from "@/context/AlertContext";
import {LangContext, LangContextProps} from "@/context/LangContext";
import {apiGet, apiPost, apiPut} from "@/lib/api/client";
import {QuillSenseSettingsProps} from "@/lib/types/quillsense";
import {GuideLineAI} from "@/lib/types/book";
import {useTranslations} from '@/lib/i18n';
import TextAreaInput from "@/components/form/TextAreaInput";
import TextInput from "@/components/form/TextInput";
import SelectBox from "@/components/form/SelectBox";
import InputField from "@/components/form/InputField";
import PulseLoader from '@/components/ui/PulseLoader';
import {SettingRef} from "@/lib/types/settings";
import {
    advancedDialogueTypes,
    advancedNarrativePersons,
    beginnerDialogueTypes,
    beginnerNarrativePersons,
    intermediateDialogueTypes,
    intermediateNarrativePersons,
    langues,
    verbalTime
} from "@/lib/constants/story";

type QuillSenseTab = 'ghostwriter' | 'guideline';

interface QuillSenseSettingProps {
    toolEnabled?: boolean;
}

const QuillSenseSetting = forwardRef<SettingRef, QuillSenseSettingProps>(function QuillSenseSetting({toolEnabled}: QuillSenseSettingProps, ref: React.ForwardedRef<SettingRef>): React.JSX.Element | null {
    const t = useTranslations();
    const {book}: BookContextProps = useContext<BookContextProps>(BookContext);
    const {session}: SessionContextProps = useContext<SessionContextProps>(SessionContext);
    const {errorMessage, successMessage}: AlertContextProps = useContext<AlertContextProps>(AlertContext);
    const {lang}: LangContextProps = useContext<LangContextProps>(LangContext);
    const bookId: string = book?.bookId ?? '';
    const userToken: string = session?.accessToken ?? '';
    const authorLevel: string = session.user?.writingLevel?.toString() ?? '1';
    
    const [activeTab, setActiveTab] = useState<QuillSenseTab>('ghostwriter');
    const [isLoading, setIsLoading] = useState<boolean>(true);
    
    // GhostWriter state
    const [advancedPrompt, setAdvancedPrompt] = useState<string>('');
    
    // Guideline AI state
    const [plotSummary, setPlotSummary] = useState<string>('');
    const [narrativeType, setNarrativeType] = useState<string>('');
    const [verbTense, setVerbTense] = useState<string>('');
    const [dialogueType, setDialogueType] = useState<string>('');
    const [toneAtmosphere, setToneAtmosphere] = useState<string>('');
    const [language, setLanguage] = useState<string>('');
    const [themes, setThemes] = useState<string>('');
    
    useImperativeHandle(ref, (): SettingRef => ({
        handleSave: activeTab === 'ghostwriter' ? handleSaveGhostWriter : handleSaveGuideline
    }));

    useEffect((): void => {
        if (book?.bookId) {
            fetchQuillSenseSettings();
        }
    }, [book?.bookId]);
    
    useEffect((): void => {
        if (activeTab === 'guideline' && !isLoading) {
            fetchAIGuideline();
        }
    }, [activeTab]);

    async function fetchQuillSenseSettings(): Promise<void> {
        try {
            setIsLoading(true);
            const settings: QuillSenseSettingsProps = await apiGet<QuillSenseSettingsProps>(
                'book/quillsense-settings',
                session.accessToken,
                lang,
                {bookId: book?.bookId}
            );
            setAdvancedPrompt(settings.advancedPrompt ?? '');
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t('quillsenseSetting.unknownError'));
            }
        } finally {
            setIsLoading(false);
        }
    }
    
    async function fetchAIGuideline(): Promise<void> {
        try {
            const response: GuideLineAI = await apiGet<GuideLineAI>(`book/ai/guideline`, userToken, lang, {id: bookId});
            if (response) {
                setPlotSummary(response.globalResume || '');
                setVerbTense(response.verbeTense?.toString() || '');
                setNarrativeType(response.narrativeType?.toString() || '');
                setDialogueType(response.dialogueType?.toString() || '');
                setToneAtmosphere(response.atmosphere || '');
                setLanguage(response.langue?.toString() || '');
                setThemes(response.themes || '');
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t("guideLineSetting.errorUnknown"));
            }
        }
    }

    async function handleSaveGhostWriter(): Promise<void> {
        try {
            const updateResult: boolean = await apiPut<boolean>(
                'book/quillsense-settings',
                {
                    bookId: book?.bookId,
                    advancedPrompt: advancedPrompt
                },
                session.accessToken,
                lang
            );
            if (updateResult) {
                successMessage(t('quillsenseSetting.saveSuccess'));
            } else {
                errorMessage(t('quillsenseSetting.saveError'));
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t('quillsenseSetting.unknownError'));
            }
        }
    }
    
    async function handleSaveGuideline(): Promise<void> {
        try {
            const response: boolean = await apiPost<boolean>(
                'quillsense/book/guide-line',
                {
                    bookId: bookId,
                    plotSummary: plotSummary,
                    verbTense: verbTense,
                    narrativeType: narrativeType,
                    dialogueType: dialogueType,
                    toneAtmosphere: toneAtmosphere,
                    language: language,
                    themes: themes,
                },
                userToken,
                lang,
            );
            if (response) {
                successMessage(t("guideLineSetting.saveSuccess"));
            } else {
                errorMessage(t("guideLineSetting.saveError"));
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t("guideLineSetting.errorUnknown"));
            }
        }
    }

    if (isLoading) {
        return <PulseLoader/>;
    }
    
    if (!toolEnabled) {
        return null;
    }

    return (
        <div className="space-y-6">
            <div className="flex gap-4 border-b border-secondary">
                <button
                    className={`pb-2 text-sm font-medium transition-colors duration-150 ${
                        activeTab === 'ghostwriter'
                            ? 'border-b-2 border-primary text-text-primary'
                            : 'text-muted hover:text-text-primary'
                    }`}
                    onClick={(): void => setActiveTab('ghostwriter')}
                >
                    GhostWriter
                </button>
                <button
                    className={`pb-2 text-sm font-medium transition-colors duration-150 ${
                        activeTab === 'guideline'
                            ? 'border-b-2 border-primary text-text-primary'
                            : 'text-muted hover:text-text-primary'
                    }`}
                    onClick={(): void => setActiveTab('guideline')}
                >
                    {t("bookSetting.guideLine")}
                </button>
            </div>
            
            {activeTab === 'ghostwriter' && (
                <div className="space-y-4">
                    <InputField
                        fieldName={t('quillsenseSetting.advancedPrompt')}
                        input={
                            <TextAreaInput
                                value={advancedPrompt}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setAdvancedPrompt(e.target.value)}
                                placeholder={t('quillsenseSetting.advancedPromptPlaceholder')}
                            />
                        }
                    />
                    <p className="text-muted text-xs">
                        {t('quillsenseSetting.advancedPromptDescription')}
                    </p>
                </div>
            )}
            
            {activeTab === 'guideline' && (
                <div className="space-y-4">
                    <InputField fieldName={t("guideLineSetting.plotSummary")} input={
                        <TextAreaInput
                            value={plotSummary}
                            setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setPlotSummary(e.target.value)}
                            placeholder={t("guideLineSetting.plotSummaryPlaceholder")}
                        />
                    }/>
                    <InputField fieldName={t("guideLineSetting.toneAtmosphere")} input={
                        <TextInput
                            value={toneAtmosphere}
                            setValue={(e: ChangeEvent<HTMLInputElement>): void => setToneAtmosphere(e.target.value)}
                            placeholder={t("guideLineSetting.toneAtmospherePlaceholder")}
                        />
                    }/>
                    <InputField fieldName={t("guideLineSetting.themes")} input={
                        <TextInput
                            value={themes}
                            setValue={(e: ChangeEvent<HTMLInputElement>): void => setThemes(e.target.value)}
                            placeholder={t("guideLineSetting.themesPlaceholderQuill")}
                        />
                    }/>
                    <InputField fieldName={t("guideLineSetting.verbTense")} input={
                        <SelectBox
                            defaultValue={verbTense}
                            onChangeCallBack={(event: ChangeEvent<HTMLSelectElement>): void => setVerbTense(event.target.value)}
                            data={verbalTime}
                            placeholder={t("guideLineSetting.verbTensePlaceholder")}
                        />
                    }/>
                    <InputField fieldName={t("guideLineSetting.narrativeType")} input={
                        <SelectBox defaultValue={narrativeType} data={
                            authorLevel === '1'
                                ? beginnerNarrativePersons
                                : authorLevel === '2'
                                    ? intermediateNarrativePersons
                                    : advancedNarrativePersons
                        } onChangeCallBack={(event: ChangeEvent<HTMLSelectElement>): void => {
                            setNarrativeType(event.target.value)
                        }} placeholder={t("guideLineSetting.narrativeTypePlaceholder")}/>
                    }/>
                    <InputField fieldName={t("guideLineSetting.dialogueType")} input={
                        <SelectBox defaultValue={dialogueType} data={authorLevel === '1'
                            ? beginnerDialogueTypes
                            : authorLevel === '2'
                                ? intermediateDialogueTypes
                                : advancedDialogueTypes}
                                   onChangeCallBack={(event: ChangeEvent<HTMLSelectElement>) => {
                                       setDialogueType(event.target.value)
                                   }} placeholder={t("guideLineSetting.dialogueTypePlaceholder")}/>
                    }/>
                    <InputField fieldName={t("guideLineSetting.language")} input={
                        <SelectBox defaultValue={language} data={langues}
                                   onChangeCallBack={(event: ChangeEvent<HTMLSelectElement>) => {
                                       setLanguage(event.target.value)
                                   }} placeholder={t("guideLineSetting.languagePlaceholder")}/>
                    }/>
                </div>
            )}
        </div>
    );
});

export default QuillSenseSetting;
