'use client';
import React, {ReactNode, useContext, useEffect} from 'react';
import {useParams} from '@/lib/navigation';
import {BookContext, BookContextProps} from '@/context/BookContext';
import {SessionContext, SessionContextProps} from '@/context/SessionContext';
import {LangContext, LangContextProps} from '@/context/LangContext';
import {AlertContext, AlertContextProps} from '@/context/AlertContext';
import {apiGet} from '@/lib/api/client';
import {isDesktop} from '@/lib/configs';
import * as tauri from '@/lib/tauri';
import OfflineContext, {OfflineContextType} from '@/context/OfflineContext';
import {BookProps} from '@/lib/types/book';
import {useTranslations} from '@/lib/i18n';
import {BooksSyncContext, BooksSyncContextProps} from '@/context/BooksSyncContext';
import {SyncedBook} from '@/lib/types/synced-book';

export default function BookLayout({children}: { children: ReactNode }) {
    const params: { bookId: string } = useParams<{ bookId: string }>();
    const {book, setBook}: BookContextProps = useContext<BookContextProps>(BookContext);
    const {session}: SessionContextProps = useContext<SessionContextProps>(SessionContext);
    const {lang}: LangContextProps = useContext<LangContextProps>(LangContext);
    const {errorMessage}: AlertContextProps = useContext<AlertContextProps>(AlertContext);
    const {isCurrentlyOffline}: OfflineContextType = useContext<OfflineContextType>(OfflineContext);
    const {localOnlyBooks}: BooksSyncContextProps = useContext<BooksSyncContextProps>(BooksSyncContext);
    const t = useTranslations();

    useEffect((): void => {
        if (session.accessToken && params.bookId) {
            if (!book || book.bookId !== params.bookId) {
                fetchBook().then();
            }
        }
    }, [params.bookId, session.accessToken]);

    async function fetchBook(): Promise<void> {
        try {
            let localBookOnly: boolean = false;
            let bookResponse: BookProps | null = null;

            if (isCurrentlyOffline()) {
                bookResponse = await tauri.getBookBasicInformation(params.bookId);
                if (bookResponse) localBookOnly = true;
            } else {
                const isOfflineBook = localOnlyBooks.find((b: SyncedBook): boolean => b.id === params.bookId);
                if (isOfflineBook) {
                    bookResponse = await tauri.getBookBasicInformation(params.bookId);
                    localBookOnly = true;
                }
                if (!bookResponse) {
                    bookResponse = await apiGet<BookProps>(
                        'book/basic-information', session.accessToken, lang, {id: params.bookId}
                    );
                }
            }

            if (!bookResponse) {
                errorMessage(t('controllerBar.bookNotFound'));
                return;
            }
            setBook({
                bookId: bookResponse.bookId,
                type: bookResponse.type,
                title: bookResponse.title,
                subTitle: bookResponse.subTitle,
                summary: bookResponse.summary,
                publicationDate: bookResponse.publicationDate,
                desiredWordCount: bookResponse.desiredWordCount,
                totalWordCount: bookResponse.totalWordCount ?? 0,
                quillsenseEnabled: bookResponse.quillsenseEnabled,
                tools: bookResponse.tools,
                seriesId: bookResponse.seriesId,
                serie: bookResponse.serie,
                coverImage: bookResponse.coverImage ? 'data:image/jpeg;base64,' + bookResponse.coverImage : '',
                localBook: localBookOnly,
            });
        } catch (e: unknown) {
            if (e instanceof Error) {
                errorMessage(e.message);
            } else {
                errorMessage(t('controllerBar.unknownBookError'));
            }
        }
    }

    return <>{children}</>;
}
