'use client'
import React, {ChangeEvent, forwardRef, useContext, useEffect, useImperativeHandle, useState} from 'react';
import {apiGet, apiPost} from '@/lib/api/client';
import {isDesktop} from '@/lib/configs';
import * as tauri from '@/lib/tauri';
import OfflineContext, {OfflineContextType} from '@/context/OfflineContext';
import {AlertContext, AlertContextProps} from "@/context/AlertContext";
import {BookContext, BookContextProps} from '@/context/BookContext';
import {SessionContext, SessionContextProps} from "@/context/SessionContext";
import {GuideLine} from "@/lib/types/book";
import TextAreaInput from "@/components/form/TextAreaInput";
import InputField from "@/components/form/InputField";
import {useTranslations} from '@/lib/i18n';
import {LangContext, LangContextProps} from "@/context/LangContext";
import {SettingRef} from "@/lib/types/settings";

function GuideLineSetting(_props: object, ref: React.ForwardedRef<SettingRef>): React.JSX.Element {
    const t = useTranslations();
    const {lang}: LangContextProps = useContext<LangContextProps>(LangContext);
    const {book}: BookContextProps = useContext<BookContextProps>(BookContext);
    const {session}: SessionContextProps = useContext<SessionContextProps>(SessionContext);
    const userToken: string = session?.accessToken ? session?.accessToken : '';
    const {errorMessage, successMessage}: AlertContextProps = useContext<AlertContextProps>(AlertContext);
    const {isCurrentlyOffline}: OfflineContextType = useContext<OfflineContextType>(OfflineContext);
    const bookId: string = book?.bookId ?? '';

    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>('');

    useEffect((): void => {
        getGuideLine().then();
    }, []);
    
    useImperativeHandle(ref, (): SettingRef => ({
        handleSave: savePersonal
    }));

    async function getGuideLine(): Promise<void> {
        try {
            let response: GuideLine;
            if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                response = await tauri.getGuideLine(bookId);
            } else {
                response = await apiGet<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;
            if (isDesktop && (isCurrentlyOffline() || book?.localBook)) {
                response = await tauri.updateGuideLine({
                    bookId: bookId,
                    tone: tone,
                    atmosphere: atmosphere,
                    writingStyle: writingStyle,
                    themes: themes,
                    symbolism: symbolism,
                    motifs: motifs,
                    narrativeVoice: narrativeVoice,
                    pacing: pacing,
                    intendedAudience: intendedAudience,
                    keyMessages: keyMessages,
                });
            } else {
                response = await apiPost<boolean>(
                    'book/guide-line',
                    {
                        bookId: bookId,
                        tone: tone,
                        atmosphere: atmosphere,
                        writingStyle: writingStyle,
                        themes: themes,
                        symbolism: symbolism,
                        motifs: motifs,
                        narrativeVoice: narrativeVoice,
                        pacing: pacing,
                        intendedAudience: intendedAudience,
                        keyMessages: keyMessages,
                    },
                    userToken,
                    lang,
                );
            }
            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"));
            }
        }
    }

    return (
        <div className="space-y-4">
            <InputField fieldName={t("guideLineSetting.tone")} input={
                <TextAreaInput
                    value={tone}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setTone(e.target.value)}
                    placeholder={t("guideLineSetting.tonePlaceholder")}
                />
            }/>
            <InputField fieldName={t("guideLineSetting.atmosphere")} input={
                <TextAreaInput
                    value={atmosphere}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setAtmosphere(e.target.value)}
                    placeholder={t("guideLineSetting.atmospherePlaceholder")}
                />
            }/>
            <InputField fieldName={t("guideLineSetting.writingStyle")} input={
                <TextAreaInput
                    value={writingStyle}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setWritingStyle(e.target.value)}
                    placeholder={t("guideLineSetting.writingStylePlaceholder")}
                />
            }/>
            <InputField fieldName={t("guideLineSetting.themes")} input={
                <TextAreaInput
                    value={themes}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setThemes(e.target.value)}
                    placeholder={t("guideLineSetting.themesPlaceholder")}
                />
            }/>
            <InputField fieldName={t("guideLineSetting.symbolism")} input={
                <TextAreaInput
                    value={symbolism}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setSymbolism(e.target.value)}
                    placeholder={t("guideLineSetting.symbolismPlaceholder")}
                />
            }/>
            <InputField fieldName={t("guideLineSetting.motifs")} input={
                <TextAreaInput
                    value={motifs}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setMotifs(e.target.value)}
                    placeholder={t("guideLineSetting.motifsPlaceholder")}
                />
            }/>
            <InputField fieldName={t("guideLineSetting.narrativeVoice")} input={
                <TextAreaInput
                    value={narrativeVoice}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setNarrativeVoice(e.target.value)}
                    placeholder={t("guideLineSetting.narrativeVoicePlaceholder")}
                />
            }/>
            <InputField fieldName={t("guideLineSetting.pacing")} input={
                <TextAreaInput
                    value={pacing}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setPacing(e.target.value)}
                    placeholder={t("guideLineSetting.pacingPlaceholder")}
                />
            }/>
            <InputField fieldName={t("guideLineSetting.intendedAudience")} input={
                <TextAreaInput
                    value={intendedAudience}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setIntendedAudience(e.target.value)}
                    placeholder={t("guideLineSetting.intendedAudiencePlaceholder")}
                />
            }/>
            <InputField fieldName={t("guideLineSetting.keyMessages")} input={
                <TextAreaInput
                    value={keyMessages}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>): void => setKeyMessages(e.target.value)}
                    placeholder={t("guideLineSetting.keyMessagesPlaceholder")}
                />
            }/>
        </div>
    );
}

export default forwardRef<SettingRef, object>(GuideLineSetting);
