'use client'
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faFeather, faTimes} from "@fortawesome/free-solid-svg-icons";
import {ChangeEvent, forwardRef, useContext, useImperativeHandle, useState} from "react";
import System from "@/lib/models/System";
import axios, {AxiosResponse} from "axios";
import {AlertContext} from "@/context/AlertContext";
import {BookContext} from "@/context/BookContext";
import {SessionContext} from "@/context/SessionContext";
import TextInput from "@/components/form/TextInput";
import TexteAreaInput from "@/components/form/TexteAreaInput";
import InputField from "@/components/form/InputField";
import NumberInput from "@/components/form/NumberInput";
import DatePicker from "@/components/form/DatePicker";
import {configs} from "@/lib/configs";
import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext";
import {BookProps} from "@/lib/models/Book";
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 BasicInformationSetting(props: any, ref: any) {
    const t = useTranslations();
    const {lang} = useContext<LangContextProps>(LangContext)
    const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
    const {addToQueue} = useContext<LocalSyncQueueContextProps>(LocalSyncQueueContext);
    const {localSyncedBooks} = useContext<BooksSyncContextProps>(BooksSyncContext);

    const {session} = useContext(SessionContext);
    const {book, setBook} = useContext(BookContext);
    const userToken: string = session?.accessToken ? session?.accessToken : '';
    const {errorMessage, successMessage} = useContext(AlertContext);
    const bookId: string = book?.bookId ? book?.bookId.toString() : '';
    
    const [currentImage, setCurrentImage] = useState<string>(book?.coverImage ?? '');
    const [title, setTitle] = useState<string>(book?.title ? book?.title : '');
    const [subTitle, setSubTitle] = useState<string>(book?.subTitle ? book?.subTitle : '');
    const [summary, setSummary] = useState<string>(book?.summary ? book?.summary : '');
    const [publicationDate, setPublicationDate] = useState<string>(book?.publicationDate ? book?.publicationDate : '');
    const [wordCount, setWordCount] = useState<number>(book?.desiredWordCount ? book?.desiredWordCount : 0);
    
    useImperativeHandle(ref, function () {
        return {
            handleSave: handleSave
        };
    });
    
    async function handleCoverImageChange(e: ChangeEvent<HTMLInputElement>): Promise<void> {
        const file: File | undefined = e.target.files?.[0];
        
        if (!file) {
            errorMessage(t('basicInformationSetting.error.noFileSelected'));
            return;
        }
        
        const formData = new FormData();
        formData.append('bookId', bookId);
        formData.append('picture', file);
        
        try {
            const query: AxiosResponse<ArrayBuffer> = await axios({
                method: "POST",
                url: configs.apiUrl + `book/cover?bookid=${bookId}`,
                headers: {
                    'Authorization': `Bearer ${userToken}`,
                },
                params: {
                    lang: lang,
                    plateforme: 'desktop',
                },
                data: formData,
                responseType: 'arraybuffer'
            });
            
            const contentType: string = query.headers['content-type'] || 'image/jpeg';
            const blob = new Blob([query.data], {type: contentType});
            const reader = new FileReader();
            
            reader.onloadend = function (): void {
                if (typeof reader.result === 'string') {
                    setCurrentImage(reader.result);
                }
            };
            
            reader.readAsDataURL(blob);
        } catch (e: unknown) {
            if (axios.isAxiosError(e)) {
                const serverMessage: string = e.response?.data?.message || e.response?.data || e.message;
                throw new Error(serverMessage as string);
            } else if (e instanceof Error) {
                throw new Error(e.message);
            } else {
                throw new Error('An unexpected error occurred');
            }
        }
    }
    
    async function handleRemoveCurrentImage(): Promise<void> {
        try {
            const response: boolean = await System.authDeleteToServer<boolean>(`book/cover/delete`, {
                bookId: bookId
            }, userToken, lang);
            if (!response) {
                errorMessage(t('basicInformationSetting.error.removeCover'));
            }
            setCurrentImage('');
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t('basicInformationSetting.error.unknown'));
            }
        }
    }
    
    async function handleSave(): Promise<void> {
        if (!title) {
            errorMessage(t('basicInformationSetting.error.titleRequired'));
            return;
        }
        try {
            let response: boolean;
            const basicInfoData = {
                title: title,
                subTitle: subTitle,
                summary: summary,
                publicationDate: publicationDate,
                wordCount: wordCount,
                bookId: bookId
            };
            if (isCurrentlyOffline() || book?.localBook) {
                response = await window.electron.invoke<boolean>('db:book:updateBasicInformation', basicInfoData);
            } else {
                response = await System.authPostToServer<boolean>('book/basic-information', basicInfoData, userToken, lang);

                if (localSyncedBooks.find((syncedBook: SyncedBook): boolean => syncedBook.id === bookId)) {
                    addToQueue('db:book:updateBasicInformation', basicInfoData);
                }
            }
            if (!response) {
                errorMessage(t('basicInformationSetting.error.update'));
                return;
            }
            if (!book) {
                errorMessage(t('basicInformationSetting.error.unknown'));
                return;
            }
            const updatedBook: BookProps = {
                ...book,
                title: title,
                subTitle: subTitle,
                summary: summary,
                publicationDate: publicationDate,
                desiredWordCount: wordCount,
            };
            setBook!!(updatedBook);
            successMessage(t('basicInformationSetting.success.update'));
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t('basicInformationSetting.error.unknown'));
            }
        }
    }
    
    return (
        <div className="space-y-6">
            <div className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
                    <InputField fieldName={t('basicInformationSetting.fields.title')} input={<TextInput
                        value={title}
                        setValue={(e: ChangeEvent<HTMLInputElement>) => setTitle(e.target.value)}
                        placeholder={t('basicInformationSetting.fields.titlePlaceholder')}
                    />}/>
                    <InputField fieldName={t('basicInformationSetting.fields.subtitle')} input={<TextInput
                        value={subTitle}
                        setValue={(e: ChangeEvent<HTMLInputElement>) => setSubTitle(e.target.value)}
                        placeholder={t('basicInformationSetting.fields.subtitlePlaceholder')}
                    />}/>
                </div>
            </div>
            
            <div className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                <InputField fieldName={t('basicInformationSetting.fields.summary')} input={<TexteAreaInput
                    value={summary}
                    setValue={(e: ChangeEvent<HTMLTextAreaElement>) => setSummary(e.target.value)}
                    placeholder={t('basicInformationSetting.fields.summaryPlaceholder')}
                />}/>
            </div>
            
            <div className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                    <InputField fieldName={t('basicInformationSetting.fields.publicationDate')} input={
                        <DatePicker
                            date={publicationDate}
                            setDate={(e: ChangeEvent<HTMLInputElement>) => setPublicationDate(e.target.value)}
                        />
                    }/>
                    <InputField fieldName={t('basicInformationSetting.fields.wordCount')} input={
                        <NumberInput value={wordCount} setValue={setWordCount}
                                     placeholder={t('basicInformationSetting.fields.wordCountPlaceholder')}/>
                    }/>
                </div>
            </div>
            
            <div className="bg-tertiary/90 backdrop-blur-sm rounded-xl p-5 border border-secondary/50 shadow-md">
                {currentImage ? (
                    <div className="flex justify-center">
                        <div className="relative w-40">
                            <img src={currentImage} alt={t('basicInformationSetting.fields.coverImageAlt')}
                                 className="rounded-lg border border-secondary shadow-md w-full h-auto"/>
                            <button
                                type="button"
                                className="absolute -top-2 -right-2 bg-error/90 hover:bg-error text-white rounded-full w-8 h-8 flex items-center justify-center hover:scale-110 transition-all duration-200 shadow-lg"
                                onClick={handleRemoveCurrentImage}
                            >
                                <FontAwesomeIcon icon={faTimes} className={'w-5 h-5'}/>
                            </button>
                        </div>
                    </div>
                ) : (
                    <div className="flex justify-center">
                        <div className="w-full max-w-lg">
                            <div
                                className="p-6 border-2 border-dashed border-secondary/50 rounded-xl bg-secondary/20 hover:border-primary/60 hover:bg-secondary/30 transition-all duration-200 shadow-inner">
                                <InputField fieldName={t('basicInformationSetting.fields.coverImage')}
                                            actionIcon={faFeather}
                                            actionLabel={t('basicInformationSetting.fields.generateWithQuillSense')}
                                            action={async () => {
                                            }} input={<input
                                    type="file"
                                    id="coverImage"
                                    accept="image/png, image/jpeg"
                                    onChange={handleCoverImageChange}
                                    className="w-full text-text-secondary focus:outline-none file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-primary file:text-background hover:file:bg-primary-dark file:cursor-pointer"
                                />}/>
                            </div>
                        </div>
                    </div>
                )}
            </div>
        </div>
    );
}

export default forwardRef(BasicInformationSetting);