'use client'
import {ChangeEvent, forwardRef, useContext, useEffect, useImperativeHandle, useState} from 'react';
import System from '@/lib/models/System';
import {AlertContext} from "@/context/AlertContext";
import {BookContext} from '@/context/BookContext';
import {SessionContext} from "@/context/SessionContext";
import {GuideLine, GuideLineAI} from "@/lib/models/Book";
import TexteAreaInput from "@/components/form/TexteAreaInput";
import InputField from "@/components/form/InputField";
import TextInput from "@/components/form/TextInput";
import SelectBox from "@/components/form/SelectBox";
import {
    advancedDialogueTypes,
    advancedNarrativePersons,
    beginnerDialogueTypes,
    beginnerNarrativePersons,
    intermediateDialogueTypes,
    intermediateNarrativePersons,
    langues,
    verbalTime
} from "@/lib/models/Story";
import {useTranslations} from "next-intl";
import {LangContext} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
import {LocalSyncQueueContext, LocalSyncQueueContextProps} from "@/context/SyncQueueContext";
import {BooksSyncContext, BooksSyncContextProps} from "@/context/BooksSyncContext";
import {SyncedBook} from "@/lib/models/SyncedBook";

function GuideLineSetting(props: any, ref: any) {
    const t = useTranslations();
    const {lang} = useContext(LangContext);
    const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
    const {addToQueue} = useContext<LocalSyncQueueContextProps>(LocalSyncQueueContext);
    const {localSyncedBooks} = useContext<BooksSyncContextProps>(BooksSyncContext);
    const {book} = useContext(BookContext);
    const {session} = useContext(SessionContext);
    const userToken: string = session?.accessToken ? session?.accessToken : '';
    const {errorMessage, successMessage} = useContext(AlertContext);
    const bookId = book?.bookId as string;
    const [activeTab, setActiveTab] = useState('personal');
    const authorLevel: string = session.user?.writingLevel?.toString() ?? '1';
    
    const [tone, setTone] = useState<string>('');
    const [atmosphere, setAtmosphere] = useState<string>('');
    const [writingStyle, setWritingStyle] = useState<string>('');
    const [themes, setThemes] = useState<string>('');
    const [symbolism, setSymbolism] = useState<string>('');
    const [motifs, setMotifs] = useState<string>('');
    const [narrativeVoice, setNarrativeVoice] = useState<string>('');
    const [pacing, setPacing] = useState<string>('');
    const [intendedAudience, setIntendedAudience] = useState<string>('');
    const [keyMessages, setKeyMessages] = useState<string>('');
    
    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>('');
    
    useEffect((): void => {
        if (activeTab === 'personal') {
            getGuideLine().then();
        } else {
            getAIGuideLine().then();
        }
    }, [activeTab]);
    
    useImperativeHandle(ref, () => {
        {
            if (activeTab === 'personal') {
                return {
                    handleSave: savePersonal
                };
            } else {
                return {
                    handleSave: saveQuillSense
                };
            }
        }
    });
    
    async function getAIGuideLine(): Promise<void> {
        try {
            let response: GuideLineAI;
            if (isCurrentlyOffline()) {
                response = await window.electron.invoke<GuideLineAI>('db:book:guideline:ai:get', {id: bookId});
            } else {
                if (book?.localBook) {
                    response = await window.electron.invoke<GuideLineAI>('db:book:guideline:ai:get', {id: bookId});
                } else {
                    response = await System.authGetQueryToServer<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 getGuideLine(): Promise<void> {
        try {
            let response: GuideLine;
            if (isCurrentlyOffline()) {
                response = await window.electron.invoke<GuideLine>('db:book:guideline:get', {id: bookId});
            } else {
                if (book?.localBook) {
                    response = await window.electron.invoke<GuideLine>('db:book:guideline:get', {id: bookId});
                } else {
                    response = await System.authGetQueryToServer<GuideLine>(
                        `book/guide-line`,
                        userToken,
                        lang,
                        {id: bookId},
                    );
                }
            }
            if (response) {
                setTone(response.tone);
                setAtmosphere(response.atmosphere);
                setWritingStyle(response.writingStyle);
                setThemes(response.themes);
                setSymbolism(response.symbolism);
                setMotifs(response.motifs);
                setNarrativeVoice(response.narrativeVoice);
                setPacing(response.pacing);
                setIntendedAudience(response.intendedAudience);
                setKeyMessages(response.keyMessages);
            }
        } catch (error: unknown) {
            if (error instanceof Error) {
                errorMessage(error.message);
            } else {
                errorMessage(t("guideLineSetting.errorUnknown"));
            }
        }
    }
    
    async function savePersonal(): Promise<void> {
        try {
            let response: boolean;
            const guidelineData = {
                bookId: bookId,
                tone: tone,
                atmosphere: atmosphere,
                writingStyle: writingStyle,
                themes: themes,
                symbolism: symbolism,
                motifs: motifs,
                narrativeVoice: narrativeVoice,
                pacing: pacing,
                intendedAudience: intendedAudience,
                keyMessages: keyMessages,
            };
            if (isCurrentlyOffline() || book?.localBook) {
                response = await window.electron.invoke<boolean>('db:book:guideline:update', guidelineData);
            } else {
                response = await System.authPostToServer<boolean>(
                    'book/guide-line',
                    guidelineData,
                    userToken,
                    lang,
                );

                if (localSyncedBooks.find((syncedBook: SyncedBook): boolean => syncedBook.id === bookId)) {
                    addToQueue('db:book:guideline:update', guidelineData);
                }
            }
            if (!response) {
                errorMessage(t("guideLineSetting.saveError"));
                return;
            }
            successMessage(t("guideLineSetting.saveSuccess"));
        } catch (error: unknown) {
            if (error instanceof Error) {
                errorMessage(error.message);
            } else {
                errorMessage(t("guideLineSetting.errorUnknown"));
            }
        }
    }
    
    async function saveQuillSense(): Promise<void> {
        try {
            let response: boolean;
            const aiGuidelineData = {
                bookId: bookId,
                plotSummary: plotSummary,
                verbTense: verbTense,
                narrativeType: narrativeType,
                dialogueType: dialogueType,
                toneAtmosphere: toneAtmosphere,
                language: language,
                themes: themes,
            };
            if (isCurrentlyOffline() || book?.localBook) {
                response = await window.electron.invoke<boolean>('db:book:guideline:ai:update', aiGuidelineData);
            } else {
                response = await System.authPostToServer<boolean>(
                    'quillsense/book/guide-line',
                    aiGuidelineData,
                    userToken,
                    lang,
                );

                if (localSyncedBooks.find((syncedBook: SyncedBook): boolean => syncedBook.id === bookId)) {
                    addToQueue('db:book:guideline:ai:update', aiGuidelineData);
                }
            }
            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"));
            }
        }
    }
    
    return (
        <div className="space-y-6">
            <div className="flex gap-2 border-b border-secondary/50 mb-6">
                <button
                    className={`px-5 py-2.5 font-medium rounded-t-xl transition-all duration-200 ${
                        activeTab === 'personal'
                            ? 'border-b-2 border-primary text-primary bg-primary/10 shadow-md'
                            : 'text-text-secondary hover:text-text-primary hover:bg-secondary/30'
                    }`}
                    onClick={(): void => setActiveTab('personal')}
                >
                    {t("guideLineSetting.personal")}
                </button>
                <button
                    className={`px-5 py-2.5 font-medium rounded-t-xl transition-all duration-200 ${
                        activeTab === 'quillsense'
                            ? 'border-b-2 border-primary text-primary bg-primary/10 shadow-md'
                            : 'text-text-secondary hover:text-text-primary hover:bg-secondary/30'
                    }`}
                    onClick={() => setActiveTab('quillsense')}
                >
                    {t("guideLineSetting.quillsense")}
                </button>
            </div>
            
            {activeTab === 'personal' && (
                <div className="space-y-4">
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.tone")} input={
                            <TexteAreaInput
                                value={tone}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>) => setTone(e.target.value)}
                                placeholder={t("guideLineSetting.tonePlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.atmosphere")} input={
                            <TexteAreaInput
                                value={atmosphere}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>) => setAtmosphere(e.target.value)}
                                placeholder={t("guideLineSetting.atmospherePlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.writingStyle")} input={
                            <TexteAreaInput
                                value={writingStyle}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setWritingStyle(e.target.value)}
                                placeholder={t("guideLineSetting.writingStylePlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.themes")} input={
                            <TexteAreaInput
                                value={themes}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setThemes(e.target.value)}
                                placeholder={t("guideLineSetting.themesPlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.symbolism")} input={
                            <TexteAreaInput
                                value={symbolism}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setSymbolism(e.target.value)}
                                placeholder={t("guideLineSetting.symbolismPlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.motifs")} input={
                            <TexteAreaInput
                                value={motifs}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setMotifs(e.target.value)}
                                placeholder={t("guideLineSetting.motifsPlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.narrativeVoice")} input={
                            <TexteAreaInput
                                value={narrativeVoice}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setNarrativeVoice(e.target.value)}
                                placeholder={t("guideLineSetting.narrativeVoicePlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.pacing")} input={
                            <TexteAreaInput
                                value={pacing}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setPacing(e.target.value)}
                                placeholder={t("guideLineSetting.pacingPlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.intendedAudience")} input={
                            <TexteAreaInput
                                value={intendedAudience}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setIntendedAudience(e.target.value)}
                                placeholder={t("guideLineSetting.intendedAudiencePlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.keyMessages")} input={
                            <TexteAreaInput
                                value={keyMessages}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setKeyMessages(e.target.value)}
                                placeholder={t("guideLineSetting.keyMessagesPlaceholder")}
                            />
                        }/>
                    </div>
                </div>
            )}
            
            {activeTab === 'quillsense' && (
                <div className="space-y-4">
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.plotSummary")} input={
                            <TexteAreaInput
                                value={plotSummary}
                                setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setPlotSummary(e.target.value)}
                                placeholder={t("guideLineSetting.plotSummaryPlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.toneAtmosphere")} input={
                            <TextInput
                                value={toneAtmosphere}
                                setValue={(e: ChangeEvent<HTMLInputElement>): void => setToneAtmosphere(e.target.value)}
                                placeholder={t("guideLineSetting.toneAtmospherePlaceholder")}
                            />
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.themes")} input={
                            <TextInput
                                value={themes}
                                setValue={(e: ChangeEvent<HTMLInputElement>) => setThemes(e.target.value)}
                                placeholder={t("guideLineSetting.themesPlaceholderQuill")}
                            />
                        }/>
                    </div>
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <InputField fieldName={t("guideLineSetting.verbTense")} input={
                            <SelectBox
                                defaultValue={verbTense}
                                onChangeCallBack={(event: ChangeEvent<HTMLSelectElement>): void => setVerbTense(event.target.value)}
                                data={verbalTime}
                                placeholder={t("guideLineSetting.verbTensePlaceholder")}
                            />
                        }/>
                    </div>
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <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")}/>
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <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")}/>
                        }/>
                    </div>
                    
                    <div
                        className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                        <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>
            )}
        </div>
    );
}

export default forwardRef(GuideLineSetting);