import {Database, QueryResult, RunResult, SQLiteValue} from 'node-sqlite3-wasm';
import System from "../System.js";

export interface BookQuery extends Record<string, SQLiteValue> {
    book_id: string;
    type: string;
    author_id: string;
    title: string;
    hashed_title: string;
    sub_title: string | null;
    hashed_sub_title: string | null;
    summary: string | null;
    serie_id: number | null;
    desired_release_date: string | null;
    desired_word_count: number | null;
    words_count: number | null;
    cover_image: string | null;
}

export interface EritBooksTable extends Record<string, SQLiteValue> {
    book_id: string;
    type: string;
    author_id: string;
    title: string;
    hashed_title: string;
    sub_title: string | null;
    hashed_sub_title: string | null;
    summary: string | null;
    serie_id: number | null;
    desired_release_date: string | null;
    desired_word_count: number | null;
    words_count: number | null;
    last_update: number;
    cover_image: string | null;
}

export interface BookActSummariesTable extends Record<string, SQLiteValue> {
    act_sum_id: string;
    book_id: string;
    user_id: string;
    act_index: number;
    last_update: number;
    summary: string | null;
}

export interface BookAIGuideLineTable extends Record<string, SQLiteValue> {
    user_id: string;
    book_id: string;
    global_resume: string | null;
    themes: string | null;
    verbe_tense: number | null;
    narrative_type: number | null;
    langue: number | null;
    dialogue_type: number | null;
    tone: string | null;
    atmosphere: string | null;
    current_resume: string | null;
    last_update: number;
}

export interface BookChaptersTable extends Record<string, SQLiteValue> {
    chapter_id: string;
    book_id: string;
    author_id: string;
    title: string;
    hashed_title: string;
    words_count: number | null;
    chapter_order: number;
    last_update: number;
}

export interface BookChapterContentTable extends Record<string, SQLiteValue> {
    content_id: string;
    chapter_id: string;
    author_id: string;
    version: number;
    content: string | null;
    words_count: number;
    time_on_it: number;
    last_update: number;
}

export interface BookChapterInfosTable extends Record<string, SQLiteValue> {
    chapter_info_id: string;
    chapter_id: string;
    act_id: number;
    incident_id: string | null;
    plot_point_id: string | null;
    book_id: string;
    author_id: string;
    summary: string | null;
    goal: string | null;
    last_update: number;
}

export interface BookCharactersTable extends Record<string, SQLiteValue> {
    character_id: string;
    book_id: string;
    user_id: string;
    first_name: string;
    last_name: string | null;
    category: string;
    title: string | null;
    image: string | null;
    role: string | null;
    biography: string | null;
    history: string | null;
    last_update: number;
}

export interface BookCharactersAttributesTable extends Record<string, SQLiteValue> {
    attr_id: string;
    character_id: string;
    user_id: string;
    attribute_name: string;
    attribute_value: string;
    last_update: number;
}

export interface BookGuideLineTable extends Record<string, SQLiteValue> {
    user_id: string;
    book_id: string;
    tone: string | null;
    atmosphere: string | null;
    writing_style: string | null;
    themes: string | null;
    symbolism: string | null;
    motifs: string | null;
    narrative_voice: string | null;
    pacing: string | null;
    intended_audience: string | null;
    key_messages: string | null;
    last_update: number;
}

export interface BookIncidentsTable extends Record<string, SQLiteValue> {
    incident_id: string;
    author_id: string;
    book_id: string;
    title: string;
    hashed_title: string;
    summary: string | null;
    last_update: number;
}

export interface BookIssuesTable extends Record<string, SQLiteValue> {
    issue_id: string;
    author_id: string;
    book_id: string;
    name: string;
    hashed_issue_name: string;
    last_update: number;
}

export interface BookLocationTable extends Record<string, SQLiteValue> {
    loc_id: string;
    book_id: string;
    user_id: string;
    loc_name: string;
    loc_original_name: string;
    last_update: number;
}

export interface BookPlotPointsTable extends Record<string, SQLiteValue> {
    plot_point_id: string;
    title: string;
    hashed_title: string;
    summary: string | null;
    linked_incident_id: string | null;
    author_id: string;
    book_id: string;
    last_update: number;
}

export interface BookWorldTable extends Record<string, SQLiteValue> {
    world_id: string;
    name: string;
    hashed_name: string;
    author_id: string;
    book_id: string;
    history: string | null;
    politics: string | null;
    economy: string | null;
    religion: string | null;
    languages: string | null;
    last_update: number;
}

export interface BookWorldElementsTable extends Record<string, SQLiteValue> {
    element_id: string;
    world_id: string;
    user_id: string;
    element_type: number;
    name: string;
    original_name: string;
    description: string | null;
    last_update: number;
}

export interface LocationElementTable extends Record<string, SQLiteValue> {
    element_id: string;
    location: string;
    user_id: string;
    element_name: string;
    original_name: string;
    element_description: string | null;
    last_update: number;
}

export interface LocationSubElementTable extends Record<string, SQLiteValue> {
    sub_element_id: string;
    element_id: string;
    user_id: string;
    sub_elem_name: string;
    original_name: string;
    sub_elem_description: string | null;
    last_update: number;
}

export interface SyncedBookResult extends Record<string, SQLiteValue> {
    book_id: string;
    type: string;
    title: string;
    sub_title: string | null;
    last_update: number;
}

export interface SyncedChapterResult extends Record<string, SQLiteValue> {
    chapter_id: string;
    book_id: string;
    title: string;
    last_update: number;
}

export interface SyncedChapterContentResult extends Record<string, SQLiteValue> {
    content_id: string;
    chapter_id: string;
    last_update: number;
}

export interface SyncedChapterInfoResult extends Record<string, SQLiteValue> {
    chapter_info_id: string;
    chapter_id: string | null;
    book_id: string;
    last_update: number;
}

export interface SyncedCharacterResult extends Record<string, SQLiteValue> {
    character_id: string;
    book_id: string;
    first_name: string;
    last_update: number;
}

export interface SyncedCharacterAttributeResult extends Record<string, SQLiteValue> {
    attr_id: string;
    character_id: string;
    attribute_name: string;
    last_update: number;
}

export interface SyncedLocationResult extends Record<string, SQLiteValue> {
    loc_id: string;
    book_id: string;
    loc_name: string;
    last_update: number;
}

export interface SyncedLocationElementResult extends Record<string, SQLiteValue> {
    element_id: string;
    location: string;
    element_name: string;
    last_update: number;
}

export interface SyncedLocationSubElementResult extends Record<string, SQLiteValue> {
    sub_element_id: string;
    element_id: string;
    sub_elem_name: string;
    last_update: number;
}

export interface SyncedWorldResult extends Record<string, SQLiteValue> {
    world_id: string;
    book_id: string;
    name: string;
    last_update: number;
}

export interface SyncedWorldElementResult extends Record<string, SQLiteValue> {
    element_id: string;
    world_id: string;
    name: string;
    last_update: number;
}

export interface SyncedIncidentResult extends Record<string, SQLiteValue> {
    incident_id: string;
    book_id: string;
    title: string;
    last_update: number;
}

export interface SyncedPlotPointResult extends Record<string, SQLiteValue> {
    plot_point_id: string;
    book_id: string;
    title: string;
    last_update: number;
}

export interface SyncedIssueResult extends Record<string, SQLiteValue> {
    issue_id: string;
    book_id: string;
    name: string;
    last_update: number;
}

export interface SyncedActSummaryResult extends Record<string, SQLiteValue> {
    act_sum_id: string;
    book_id: string;
    last_update: number;
}

export interface SyncedGuideLineResult extends Record<string, SQLiteValue> {
    book_id: string;
    last_update: number;
}

export interface SyncedAIGuideLineResult extends Record<string, SQLiteValue> {
    book_id: string;
    last_update: number;
}

export interface GuideLineQuery extends Record<string, SQLiteValue> {
    tone: string;
    atmosphere: string;
    writing_style: string;
    themes: string;
    symbolism: string;
    motifs: string;
    narrative_voice: string;
    pacing: string;
    intended_audience: string;
    key_messages: string;
}

export interface PlotPointQuery extends Record<string, SQLiteValue> {
    plot_point_id: string;
    title: string;
    summary: string;
    linked_incident_id: string | null;
}

export interface IncidentQuery extends Record<string, SQLiteValue> {
    incident_id: string;
    title: string;
    summary: string;
}

export interface IssueQuery extends Record<string, SQLiteValue> {
    issue_id: string;
    name: string;
}

export interface ActQuery extends Record<string, SQLiteValue> {
    act_index: number;
    summary: string;
}

export interface BookCoverQuery extends Record<string, SQLiteValue> {
    cover_image: string;
}

export interface ChapterBookResult extends Record<string, SQLiteValue> {
    title: string;
    chapter_order: number;
    content: string | null;
}

export interface WorldQuery extends Record<string, SQLiteValue> {
    world_id: string;
    world_name: string;
    history: string | null;
    politics: string | null;
    economy: string | null;
    religion: string | null;
    languages: string | null;
    element_id: string | null;
    element_name: string | null;
    element_description: string | null;
    element_type: number | null;
}

export interface WorldElementValue {
    id: string;
    name: string;
    description: string;
    type: number;
}

export interface GuideLineAIQuery extends Record<string, SQLiteValue> {
    user_id: string;
    book_id: string;
    global_resume: string | null;
    themes: string | null;
    verbe_tense: number | null;
    narrative_type: number | null;
    langue: number | null;
    dialogue_type: number | null;
    tone: string | null;
    atmosphere: string | null;
    current_resume: string | null;
    meta: string;
}

export default class BookRepo {
    public static fetchBooks(userId: string, lang: 'fr' | 'en'): BookQuery[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT book_id, type, author_id, title, sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image FROM erit_books WHERE author_id = ? ORDER BY book_id DESC', [userId]) as BookQuery[];
        } catch (error: unknown) {
            if (error instanceof Error) {
                console.error(error.message);
                throw new Error(lang === 'fr' ? 'Impossible de récupérer la liste des livres.' : 'Unable to retrieve book list.');
            } else {
                console.error(error);
                throw new Error(lang === 'fr' ? 'Une erreur inconnue est survenue.' : 'An unknown error occurred.');
            }
        }
    }
    
    public static updateBookCover(bookId:string,coverImageName:string,userId:string, lang: 'fr' | 'en'):boolean{
        try {
            const db: Database = System.getDb();
            const result:RunResult = db.run('UPDATE `erit_books` SET cover_image=?, last_update=? WHERE `book_id`=? AND author_id=?', [coverImageName, System.timeStampInSeconds(), bookId, userId]);
            return result.changes>0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour la couverture du livre.` : `Unable to update book cover.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static fetchBook(bookId: string, userId: string, lang: 'fr' | 'en'): BookQuery {
        let result: BookQuery;
        try {
            const db: Database = System.getDb();
            result = db.get('SELECT book_id, author_id, title, summary, sub_title, cover_image, desired_release_date, desired_word_count, words_count FROM erit_books WHERE book_id=? AND author_id=?', [bookId, userId]) as BookQuery;
        } catch (error: unknown) {
            if (error instanceof Error) {
                console.error(`DB Error: ${error.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les informations du livre.` : `Unable to retrieve book information.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (!result) {
            throw new Error(lang === 'fr' ? `Livre non trouvé.` : `Book not found.`);
        }
        return result;
    }
    public static verifyBookExist(hashedTitle:string,hashedSubTitle:string,userId:string, lang: 'fr' | 'en'):boolean{
        try {
            const db: Database = System.getDb();
            const result:QueryResult|null = db.get('SELECT book_id FROM erit_books WHERE hashed_title=? AND author_id=? AND erit_books.hashed_sub_title=?', [hashedTitle,userId,hashedSubTitle]);
            return result!==null;
        } catch (err: unknown) {
            if (err instanceof Error) {
                console.error(`DB Error: ${err.message}`);
                throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du livre.` : `Unable to verify book existence.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static fetchGuideLine(userId: string, bookId: string, lang: 'fr' | 'en'): GuideLineQuery[] {
        let result: GuideLineQuery[];
        try {
            const db: Database = System.getDb();
            result = db.all('SELECT * FROM book_guide_line WHERE book_id=? AND user_id=?', [bookId, userId]) as GuideLineQuery[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice.` : `Unable to retrieve guideline.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        return result;
    }
    
    public static fetchAllActs(userId: string, bookId: string, lang: 'fr' | 'en'): ActQuery[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT act_index, summary FROM book_act_summaries WHERE book_id=? AND user_id=?', [bookId, userId]) as ActQuery[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les actes.` : `Unable to retrieve acts.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    public static fetchAllIncitentIncidents(userId:string,bookId:string, lang: 'fr' | 'en'):IncidentQuery[]{
        try {
            const db: Database = System.getDb();
            return db.all('SELECT incident_id, title, summary FROM book_incidents WHERE author_id=? AND book_id=?', [userId, bookId]) as IncidentQuery[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents.` : `Unable to retrieve incidents.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    public static fetchAllPlotPoints(userId:string,bookId:string, lang: 'fr' | 'en'):PlotPointQuery[]{
        try {
            const db: Database = System.getDb();
            return db.all('SELECT plot_point_id, title, summary, linked_incident_id FROM book_plot_points WHERE author_id=? AND book_id=?', [userId, bookId]) as PlotPointQuery[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue.` : `Unable to retrieve plot points.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    public static fetchIssuesFromBook(userId:string,bookId:string, lang: 'fr' | 'en'):IssueQuery[]{
        try {
            const db: Database = System.getDb();
            return db.all('SELECT issue_id, name FROM book_issues WHERE author_id=? AND book_id=?', [userId, bookId]) as IssueQuery[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques.` : `Unable to retrieve issues.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static insertBook(bookId: string, userId: string, encryptedTitle: string, hashedTitle: string, encryptedSubTitle: string, hashedSubTitle: string, encryptedSummary: string, type: string, serie: number, publicationDate: string, desiredWordCount: number, lang: 'fr' | 'en'): string {
        let result: RunResult;
        try {
            const db: Database = System.getDb();
            result = db.run('INSERT INTO erit_books (book_id, type, author_id, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', [bookId, type, userId, encryptedTitle, hashedTitle, encryptedSubTitle, hashedSubTitle, encryptedSummary, serie, publicationDate ? publicationDate : null, desiredWordCount, System.timeStampInSeconds()]);
        } catch (err: unknown) {
            if (err instanceof Error) {
                console.error(`DB Error: ${err.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'ajouter le livre.` : `Unable to add book.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (!result || result.changes === 0) {
            throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du livre.` : `Error adding book.`);
        }
        return bookId;
    }
    public static fetchBookCover(userId:string,bookId:string, lang: 'fr' | 'en'):BookCoverQuery{
        try {
            const db: Database = System.getDb();
            return db.get('SELECT cover_image FROM erit_books WHERE author_id=? AND book_id=?', [userId, bookId]) as BookCoverQuery;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer la couverture du livre.` : `Unable to retrieve book cover.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    static updateBookBasicInformation(userId: string, title: string, hashedTitle: string, subTitle: string, hashedSubTitle: string, summary: string, publicationDate: string, wordCount: number, bookId: string, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('UPDATE erit_books SET title=?, hashed_title=?, sub_title=?, hashed_sub_title=?, summary=?, serie_id=?, desired_release_date=?, desired_word_count=?, last_update=? WHERE author_id=? AND book_id=?',
                [title, hashedTitle, subTitle, hashedSubTitle, summary, 0, publicationDate ? System.dateToMySqlDate(publicationDate) : null, wordCount, System.timeStampInSeconds(), userId, bookId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour les informations du livre.` : `Unable to update book information.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    static updateGuideLine(userId: string, bookId: string, encryptedTone: string, encryptedAtmosphere: string, encryptedWritingStyle: string, encryptedThemes: string, encryptedSymbolism: string, encryptedMotifs: string, encryptedNarrativeVoice: string, encryptedPacing: string, encryptedKeyMessages: string, encryptedIntendedAudience: string, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('UPDATE book_guide_line SET tone=?, atmosphere=?, writing_style=?, themes=?, symbolism=?, motifs=?, narrative_voice=?, pacing=?, key_messages=?, last_update=? WHERE user_id=? AND book_id=?', [encryptedTone, encryptedAtmosphere, encryptedWritingStyle, encryptedThemes, encryptedSymbolism, encryptedMotifs, encryptedNarrativeVoice, encryptedPacing, encryptedKeyMessages, System.timeStampInSeconds(), userId, bookId]);
            if (result.changes > 0) {
                return true;
            } else {
                const insert:RunResult = db.run('INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)', [userId, bookId, encryptedTone, encryptedAtmosphere, encryptedWritingStyle, encryptedThemes, encryptedSymbolism, encryptedMotifs, encryptedNarrativeVoice, encryptedPacing, encryptedIntendedAudience, encryptedKeyMessages, System.timeStampInSeconds()]);
                return insert.changes > 0;
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour la ligne directrice.` : `Unable to update guideline.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static updateActSummary(userId: string, bookId: string, actId: number, summary: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('UPDATE book_act_summaries SET summary=?, last_update=? WHERE user_id=? AND book_id=? AND act_sum_id=?', [summary, lastUpdate, userId, bookId, actId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour le résumé de l'acte.` : `Unable to update act summary.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static insertNewIncident(incidentId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
        let result: RunResult;
        try {
            const db: Database = System.getDb();
            result = db.run('INSERT INTO book_incidents (incident_id,author_id, book_id, title, hashed_title, last_update) VALUES (?,?,?,?,?,?)', [incidentId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()]);
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément déclencheur.` : `Unable to add incident.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (!result || result.changes === 0) {
            throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout de l'élément déclencheur.` : `Error adding incident.`);
        }
        return incidentId;
    }
    
    public static deleteIncident(userId: string, bookId: string, incidentId: string, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('DELETE FROM book_incidents WHERE author_id=? AND book_id=? AND incident_id=?', [userId, bookId, incidentId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément déclencheur.` : `Unable to delete incident.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    static insertNewPlotPoint(plotPointId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, incidentId: string, lang: 'fr' | 'en'): string {
        let existingResult: QueryResult | null;
        let insertResult: RunResult;
        try {
            const db: Database = System.getDb();
            existingResult = db.get('SELECT plot_point_id FROM book_plot_points WHERE author_id=? AND book_id=? AND hashed_title=?', [userId, bookId, hashedName]);
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du point d'intrigue.` : `Unable to verify plot point existence.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (existingResult !== null) {
            throw new Error(lang === 'fr' ? `Ce point de l'intrigue existe déjà.` : `This plot point already exists.`);
        }
        try {
            const db: Database = System.getDb();
            insertResult = db.run('INSERT INTO book_plot_points (plot_point_id,title,hashed_title,author_id,book_id,linked_incident_id,last_update) VALUES (?,?,?,?,?,?,?)', [plotPointId, encryptedName, hashedName, userId, bookId, incidentId, System.timeStampInSeconds()]);
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'ajouter le point d'intrigue.` : `Unable to add plot point.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (!insertResult || insertResult.changes === 0) {
            throw new Error(lang === 'fr' ? `Une erreur s'est produite lors de l'ajout du point d'intrigue.` : `Error adding plot point.`);
        }
        return plotPointId;
    }
    
    static deletePlotPoint(userId: string, plotNumId: string, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('DELETE FROM book_plot_points WHERE author_id=? AND plot_point_id=?', [userId, plotNumId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de supprimer le point d'intrigue.` : `Unable to delete plot point.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static insertNewIssue(issueId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
        let existingResult: QueryResult | null;
        let insertResult: RunResult;
        try {
            const db: Database = System.getDb();
            existingResult = db.get('SELECT issue_id FROM book_issues WHERE hashed_issue_name=? AND book_id=? AND author_id=?', [hashedName, bookId, userId]);
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de la problématique.` : `Unable to verify issue existence.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (existingResult !== null) {
            throw new Error(lang === 'fr' ? `La problématique existe déjà.` : `This issue already exists.`);
        }
        try {
            const db: Database = System.getDb();
            insertResult = db.run('INSERT INTO book_issues (issue_id,author_id, book_id, name, hashed_issue_name, last_update) VALUES (?,?,?,?,?,?)', [issueId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()]);
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'ajouter la problématique.` : `Unable to add issue.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (!insertResult || insertResult.changes === 0) {
            throw new Error(lang === 'fr' ? `Erreur pendant l'ajout de la problématique.` : `Error adding issue.`);
        }
        return issueId;
    }
    
    public static deleteIssue(userId: string, issueId: string, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('DELETE FROM book_issues WHERE author_id=? AND issue_id=?', [userId, issueId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de supprimer la problématique.` : `Unable to delete issue.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    public static updateIncident(userId: string, bookId: string, incidentId: string, encryptedIncidentName: string, incidentHashedName: string, incidentSummary: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('UPDATE book_incidents SET title=?, hashed_title=?, summary=?, last_update=? WHERE author_id=? AND book_id=? AND incident_id=?', [encryptedIncidentName, incidentHashedName, incidentSummary, lastUpdate, userId, bookId, incidentId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'incident.` : `Unable to update incident.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    public static updatePlotPoint(userId: string, bookId: string, plotPointId: string, encryptedPlotPointName: string, plotPointHashedName: string, plotPointSummary: string, lastUpdate:number, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('UPDATE book_plot_points SET title=?, hashed_title=?, summary=?, last_update=? WHERE author_id=? AND book_id=? AND plot_point_id=?', [encryptedPlotPointName, plotPointHashedName, plotPointSummary, lastUpdate, userId, bookId, plotPointId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour le point d'intrigue.` : `Unable to update plot point.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    public static checkWorldExist(userId:string,bookId:string,worldName:string, lang: 'fr' | 'en'):boolean{
        try {
            const db: Database = System.getDb();
            const result = db.get('SELECT world_id FROM book_world WHERE author_id=? AND book_id=? AND hashed_name=?', [userId,bookId,worldName]);
            return result !== null;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence du monde.` : `Unable to verify world existence.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static insertNewWorld(worldId: string, userId: string, bookId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
        let result: RunResult;
        try {
            const db: Database = System.getDb();
            result = db.run('INSERT INTO book_world (world_id,author_id, book_id, name, hashed_name, last_update) VALUES (?,?,?,?,?,?)', [worldId, userId, bookId, encryptedName, hashedName, System.timeStampInSeconds()]);
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'ajouter le monde.` : `Unable to add world.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (!result || result.changes === 0) {
            throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du monde.` : `Error adding world.`);
        }
        return worldId;
    }
    public static fetchWorlds(userId: string, bookId: string, lang: 'fr' | 'en'):WorldQuery[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT world.world_id AS world_id, world.name AS world_name, world.history, world.politics, world.economy, world.religion, world.languages, element.element_id AS element_id, element.name AS element_name, element.description AS element_description, element.element_type FROM book_world AS world LEFT JOIN book_world_elements AS element ON world.world_id=element.world_id WHERE world.author_id=? AND world.book_id=?', [userId, bookId]) as WorldQuery[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les mondes.` : `Unable to retrieve worlds.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static updateWorld(userId: string, worldId: string, encryptName: string, hashedName: string, encryptHistory: string, encryptPolitics: string, encryptEconomy: string, encryptReligion: string, encryptLanguages: string, lastUpdate: number, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('UPDATE book_world SET name=?, hashed_name=?, history=?, politics=?, economy=?, religion=?, languages=?, last_update=? WHERE author_id=? AND world_id=?', [encryptName, hashedName, encryptHistory, encryptPolitics, encryptEconomy, encryptReligion, encryptLanguages, lastUpdate, userId, worldId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour le monde.` : `Unable to update world.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    public static updateWorldElements(userId: string, elements: WorldElementValue[], lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            for (const element of elements) {
                const result: RunResult = db.run('UPDATE book_world_elements SET name=?, description=?, element_type=?, last_update=? WHERE user_id=? AND element_id=?', [element.name, element.description, element.type, System.timeStampInSeconds(), userId, element.id]);
                if (result.changes <= 0) {
                    return false;
                }
            }
            return true;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour les éléments du monde.` : `Unable to update world elements.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static checkElementExist(worldNumId: string, hashedName: string, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result = db.get('SELECT element_id FROM book_world_elements WHERE world_id=? AND original_name=?', [worldNumId, hashedName]);
            return result !== null;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de vérifier l'existence de l'élément.` : `Unable to verify element existence.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    public static insertNewElement(userId: string, elementId: string, elementType: number, worldId: string, encryptedName: string, hashedName: string, lang: 'fr' | 'en'): string {
        let result: RunResult;
        try {
            const db: Database = System.getDb();
            result = db.run('INSERT INTO book_world_elements (element_id,world_id,user_id, name, original_name, element_type, last_update) VALUES (?,?,?,?,?,?,?)', [elementId, worldId, userId, encryptedName, hashedName, elementType, System.timeStampInSeconds()]);
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'ajouter l'élément.` : `Unable to add element.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (!result || result.changes === 0) {
            throw new Error(lang === 'fr' ? `Erreur lors de l'ajout de l'élément.` : `Error adding element.`);
        }
        return elementId;
    }

    public static deleteElement(userId: string, elementId: string, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('DELETE FROM book_world_elements WHERE user_id=? AND element_id=?', [userId, elementId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de supprimer l'élément.` : `Unable to delete element.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    public static deleteBook(userId: string, bookId: string, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run('DELETE FROM erit_books WHERE author_id=? AND book_id=?', [userId,bookId]);
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de supprimer le livre.` : `Unable to delete book.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    static insertAIGuideLine(userId: string, bookId: string, narrativeType: number, dialogueType: number, encryptedPlotSummary: string, encryptedToneAtmosphere: string, verbTense: number, language: number, encryptedThemes: string, lang: 'fr' | 'en'): boolean {
        try {
            const db: Database = System.getDb();
            let result: RunResult = db.run('UPDATE book_ai_guide_line SET narrative_type=?, dialogue_type=?, global_resume=?, atmosphere=?, verbe_tense=?, langue=?, themes=?, last_update=? WHERE user_id=? AND book_id=?', [narrativeType ? narrativeType : null, dialogueType ? dialogueType : null, encryptedPlotSummary, encryptedToneAtmosphere, verbTense ? verbTense : null, language ? language : null, encryptedThemes, System.timeStampInSeconds(), userId, bookId]);
            if (result.changes > 0) {
                return true;
            } else {
                result = db.run('INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)', [userId, bookId, encryptedPlotSummary, encryptedThemes, verbTense ? verbTense : null, narrativeType ? narrativeType : null, language ? language : null, dialogueType ? dialogueType : null, encryptedToneAtmosphere, encryptedToneAtmosphere, encryptedPlotSummary, System.timeStampInSeconds()]);
                return result.changes > 0;
            }
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice IA.` : `Unable to insert AI guideline.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    static fetchGuideLineAI(userId: string, bookId: string, lang: 'fr' | 'en'): GuideLineAIQuery {
        let result: GuideLineAIQuery | null;
        try {
            const db: Database = System.getDb();
            result = db.get('SELECT narrative_type, dialogue_type, global_resume, atmosphere, verbe_tense, langue, themes, current_resume FROM book_ai_guide_line WHERE user_id=? AND book_id=?', [userId, bookId]) as GuideLineAIQuery | null;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer la ligne directrice IA.` : `Unable to retrieve AI guideline.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (!result) {
            throw new Error(lang === 'fr' ? `Ligne directrice IA non trouvée.` : `AI guideline not found.`);
        }
        return result;
    }
    
    static insertActSummary(actSummaryId: string, userId: string, bookId: string, actId: number, actSummary: string, lang: 'fr' | 'en'): string {
        let result:RunResult
        try {
            const db: Database = System.getDb();
            result = db.run('INSERT INTO book_act_summaries (act_sum_id, book_id, user_id, act_index, summary, last_update) VALUES (?,?,?,?,?,?)', [actSummaryId, bookId, userId, actId, actSummary, System.timeStampInSeconds()]);
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'ajouter le résumé de l'acte.` : `Unable to add act summary.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (!result) {
            throw new Error(lang === 'fr' ? `Erreur lors de l'ajout du résumé de l'acte.` : `Error adding act summary.`);
        }
        return actSummaryId;
    }
    
    static fetchCompleteBookChapters(id: string, lang: 'fr' | 'en'): ChapterBookResult[] {
        let result: ChapterBookResult[];
        try {
            const db: Database = System.getDb();
            result = db.all('SELECT title, chapter_order, content.content FROM book_chapters AS chapter LEFT JOIN book_chapter_content AS content ON chapter.chapter_id = content.chapter_id AND content.version = (SELECT MAX(version) FROM book_chapter_content WHERE chapter_id = chapter.chapter_id AND version > 1) WHERE chapter.book_id = ? ORDER BY chapter.chapter_order', [id]) as ChapterBookResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les chapitres.` : `Unable to retrieve chapters.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
        if (result.length === 0) {
            throw new Error(lang === 'fr' ? `Aucun chapitre trouvé.` : `No chapters found.`);
        }
        return result;
    }
    static fetchSyncedBooks(userId: string, lang: 'fr' | 'en'): SyncedBookResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT book_id, type, title, sub_title, last_update FROM erit_books WHERE author_id = ?', [userId]) as SyncedBookResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les livres synchronisés.` : `Unable to retrieve synced books.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedChapters(userId: string, lang: 'fr' | 'en'): SyncedChapterResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT chapter_id, book_id, title, last_update FROM book_chapters WHERE author_id = ?', [userId]) as SyncedChapterResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les chapitres synchronisés.` : `Unable to retrieve synced chapters.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedChapterContents(userId: string, lang: 'fr' | 'en'): SyncedChapterContentResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT content_id, chapter_id, last_update FROM book_chapter_content WHERE author_id = ?', [userId]) as SyncedChapterContentResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu des chapitres synchronisés.` : `Unable to retrieve synced chapter contents.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedChapterInfos(userId: string, lang: 'fr' | 'en'): SyncedChapterInfoResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT chapter_info_id, chapter_id, book_id, last_update FROM book_chapter_infos WHERE author_id = ?', [userId]) as SyncedChapterInfoResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les infos des chapitres synchronisés.` : `Unable to retrieve synced chapter infos.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedCharacters(userId: string, lang: 'fr' | 'en'): SyncedCharacterResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT character_id, book_id, first_name, last_update FROM book_characters WHERE user_id = ?', [userId]) as SyncedCharacterResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les personnages synchronisés.` : `Unable to retrieve synced characters.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedCharacterAttributes(userId: string, lang: 'fr' | 'en'): SyncedCharacterAttributeResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT attr_id, character_id, attribute_name, last_update FROM book_characters_attributes WHERE user_id = ?', [userId]) as SyncedCharacterAttributeResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les attributs des personnages synchronisés.` : `Unable to retrieve synced character attributes.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedLocations(userId: string, lang: 'fr' | 'en'): SyncedLocationResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT loc_id, book_id, loc_name, last_update FROM book_location WHERE user_id = ?', [userId]) as SyncedLocationResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les lieux synchronisés.` : `Unable to retrieve synced locations.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedLocationElements(userId: string, lang: 'fr' | 'en'): SyncedLocationElementResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT element_id, location, element_name, last_update FROM location_element WHERE user_id = ?', [userId]) as SyncedLocationElementResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de lieu synchronisés.` : `Unable to retrieve synced location elements.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedLocationSubElements(userId: string, lang: 'fr' | 'en'): SyncedLocationSubElementResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT sub_element_id, element_id, sub_elem_name, last_update FROM location_sub_element WHERE user_id = ?', [userId]) as SyncedLocationSubElementResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les sous-éléments de lieu synchronisés.` : `Unable to retrieve synced location sub-elements.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedWorlds(userId: string, lang: 'fr' | 'en'): SyncedWorldResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT world_id, book_id, name, last_update FROM book_world WHERE author_id = ?', [userId]) as SyncedWorldResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les mondes synchronisés.` : `Unable to retrieve synced worlds.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedWorldElements(userId: string, lang: 'fr' | 'en'): SyncedWorldElementResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT element_id, world_id, name, last_update FROM book_world_elements WHERE user_id = ?', [userId]) as SyncedWorldElementResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les éléments de monde synchronisés.` : `Unable to retrieve synced world elements.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedIncidents(userId: string, lang: 'fr' | 'en'): SyncedIncidentResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT incident_id, book_id, title, last_update FROM book_incidents WHERE author_id = ?', [userId]) as SyncedIncidentResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les incidents synchronisés.` : `Unable to retrieve synced incidents.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedPlotPoints(userId: string, lang: 'fr' | 'en'): SyncedPlotPointResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT plot_point_id, book_id, title, last_update FROM book_plot_points WHERE author_id = ?', [userId]) as SyncedPlotPointResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les points d'intrigue synchronisés.` : `Unable to retrieve synced plot points.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedIssues(userId: string, lang: 'fr' | 'en'): SyncedIssueResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT issue_id, book_id, name, last_update FROM book_issues WHERE author_id = ?', [userId]) as SyncedIssueResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les problématiques synchronisées.` : `Unable to retrieve synced issues.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedActSummaries(userId: string, lang: 'fr' | 'en'): SyncedActSummaryResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT act_sum_id, book_id, last_update FROM book_act_summaries WHERE user_id = ?', [userId]) as SyncedActSummaryResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les résumés d'actes synchronisés.` : `Unable to retrieve synced act summaries.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedGuideLine(userId: string, lang: 'fr' | 'en'): SyncedGuideLineResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT book_id, last_update FROM book_guide_line WHERE user_id = ?', [userId]) as SyncedGuideLineResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les lignes directrices synchronisées.` : `Unable to retrieve synced guidelines.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static fetchSyncedAIGuideLine(userId: string, lang: 'fr' | 'en'): SyncedAIGuideLineResult[] {
        try {
            const db: Database = System.getDb();
            return db.all('SELECT book_id, last_update FROM book_ai_guide_line WHERE user_id = ?', [userId]) as SyncedAIGuideLineResult[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de récupérer les lignes directrices IA synchronisées.` : `Unable to retrieve synced AI guidelines.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    // ===================== SYNC INSERT METHODS =====================

    static insertSyncBook(
        bookId: string,
        userId: string,
        type: string,
        title: string,
        hashedTitle: string,
        subTitle: string | null,
        hashedSubTitle: string | null,
        summary: string | null,
        serieId: number | null,
        desiredReleaseDate: string | null,
        desiredWordCount: number | null,
        wordsCount: number | null,
        coverImage: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO erit_books (book_id, author_id, type, title, hashed_title, sub_title, hashed_sub_title, summary, serie_id, desired_release_date, desired_word_count, words_count, cover_image, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
                [bookId, userId, type, title, hashedTitle, subTitle, hashedSubTitle, summary, serieId, desiredReleaseDate, desiredWordCount, wordsCount, coverImage, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer le livre synchronisé.` : `Unable to insert synced book.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncActSummary(
        actSumId: string,
        bookId: string,
        userId: string,
        actIndex: number,
        summary: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_act_summaries (act_sum_id, book_id, user_id, act_index, summary, last_update) VALUES (?, ?, ?, ?, ?, ?)`,
                [actSumId, bookId, userId, actIndex, summary, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer le résumé d'acte.` : `Unable to insert act summary.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncAIGuideLine(
        userId: string,
        bookId: string,
        globalResume: string | null,
        themes: string | null,
        verbeTense: number | null,
        narrativeType: number | null,
        langue: number | null,
        dialogueType: number | null,
        tone: string | null,
        atmosphere: string | null,
        currentResume: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_ai_guide_line (user_id, book_id, global_resume, themes, verbe_tense, narrative_type, langue, dialogue_type, tone, atmosphere, current_resume, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
                [userId, bookId, globalResume, themes, verbeTense, narrativeType, langue, dialogueType, tone, atmosphere, currentResume, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice IA.` : `Unable to insert AI guideline.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncChapter(
        chapterId: string,
        bookId: string,
        authorId: string,
        title: string,
        hashedTitle: string | null,
        wordsCount: number | null,
        chapterOrder: number | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_chapters (chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
                [chapterId, bookId, authorId, title, hashedTitle, wordsCount, chapterOrder, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer le chapitre.` : `Unable to insert chapter.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncChapterContent(
        contentId: string,
        chapterId: string,
        authorId: string,
        version: number,
        content: string | null,
        wordsCount: number,
        timeOnIt: number,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_chapter_content (content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
                [contentId, chapterId, authorId, version, content, wordsCount, timeOnIt, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer le contenu du chapitre.` : `Unable to insert chapter content.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncChapterInfo(
        chapterInfoId: string,
        chapterId: string,
        actId: number | null,
        incidentId: string | null,
        plotPointId: string | null,
        bookId: string,
        authorId: string,
        summary: string | null,
        goal: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_chapter_infos (chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
                [chapterInfoId, chapterId, actId, incidentId, plotPointId, bookId, authorId, summary, goal, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer les infos du chapitre.` : `Unable to insert chapter info.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncCharacter(
        characterId: string,
        bookId: string,
        userId: string,
        firstName: string,
        lastName: string | null,
        category: string,
        title: string | null,
        image: string | null,
        role: string | null,
        biography: string | null,
        history: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_characters (character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
                [characterId, bookId, userId, firstName, lastName, category, title, image, role, biography, history, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer le personnage.` : `Unable to insert character.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncCharacterAttribute(
        attrId: string,
        characterId: string,
        userId: string,
        attributeName: string,
        attributeValue: string,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_characters_attributes (attr_id, character_id, user_id, attribute_name, attribute_value, last_update)
                 VALUES (?, ?, ?, ?, ?, ?)`,
                [attrId, characterId, userId, attributeName, attributeValue, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer l'attribut du personnage.` : `Unable to insert character attribute.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncGuideLine(
        userId: string,
        bookId: string,
        tone: string | null,
        atmosphere: string | null,
        writingStyle: string | null,
        themes: string | null,
        symbolism: string | null,
        motifs: string | null,
        narrativeVoice: string | null,
        pacing: string | null,
        intendedAudience: string | null,
        keyMessages: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_guide_line (user_id, book_id, tone, atmosphere, writing_style, themes, symbolism, motifs, narrative_voice, pacing, intended_audience, key_messages, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
                [userId, bookId, tone, atmosphere, writingStyle, themes, symbolism, motifs, narrativeVoice, pacing, intendedAudience, keyMessages, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer la ligne directrice.` : `Unable to insert guideline.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncIncident(
        incidentId: string,
        authorId: string,
        bookId: string,
        title: string,
        hashedTitle: string,
        summary: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_incidents (incident_id, author_id, book_id, title, hashed_title, summary, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?)`,
                [incidentId, authorId, bookId, title, hashedTitle, summary, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer l'incident.` : `Unable to insert incident.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncIssue(
        issueId: string,
        authorId: string,
        bookId: string,
        name: string,
        hashedIssueName: string,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_issues (issue_id, author_id, book_id, name, hashed_issue_name, last_update)
                 VALUES (?, ?, ?, ?, ?, ?)`,
                [issueId, authorId, bookId, name, hashedIssueName, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer la problématique.` : `Unable to insert issue.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncLocation(
        locId: string,
        bookId: string,
        userId: string,
        locName: string,
        locOriginalName: string,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_location (loc_id, book_id, user_id, loc_name, loc_original_name, last_update)
                 VALUES (?, ?, ?, ?, ?, ?)`,
                [locId, bookId, userId, locName, locOriginalName, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer le lieu.` : `Unable to insert location.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncPlotPoint(
        plotPointId: string,
        title: string,
        hashedTitle: string,
        summary: string | null,
        linkedIncidentId: string | null,
        authorId: string,
        bookId: string,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_plot_points (plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
                [plotPointId, title, hashedTitle, summary, linkedIncidentId, authorId, bookId, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer le point d'intrigue.` : `Unable to insert plot point.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncWorld(
        worldId: string,
        name: string,
        hashedName: string,
        authorId: string,
        bookId: string,
        history: string | null,
        politics: string | null,
        economy: string | null,
        religion: string | null,
        languages: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_world (world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
                [worldId, name, hashedName, authorId, bookId, history, politics, economy, religion, languages, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer le monde.` : `Unable to insert world.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncWorldElement(
        elementId: string,
        worldId: string,
        userId: string,
        elementType: number,
        name: string,
        originalName: string,
        description: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO book_world_elements (element_id, world_id, user_id, element_type, name, original_name, description, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
                [elementId, worldId, userId, elementType, name, originalName, description, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer l'élément du monde.` : `Unable to insert world element.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncLocationElement(
        elementId: string,
        location: string,
        userId: string,
        elementName: string,
        originalName: string,
        elementDescription: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO location_element (element_id, location, user_id, element_name, original_name, element_description, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?)`,
                [elementId, location, userId, elementName, originalName, elementDescription, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer l'élément du lieu.` : `Unable to insert location element.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static insertSyncLocationSubElement(
        subElementId: string,
        elementId: string,
        userId: string,
        subElemName: string,
        originalName: string,
        subElemDescription: string | null,
        lastUpdate: number,
        lang: 'fr' | 'en'
    ): boolean {
        try {
            const db: Database = System.getDb();
            const result: RunResult = db.run(
                `INSERT INTO location_sub_element (sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update)
                 VALUES (?, ?, ?, ?, ?, ?, ?)`,
                [subElementId, elementId, userId, subElemName, originalName, subElemDescription, lastUpdate]
            );
            return result.changes > 0;
        } catch (e: unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible d'insérer le sous-élément du lieu.` : `Unable to insert location sub-element.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    static async fetchCompleteActSummaryById(id: string, lang: "fr" | "en"):Promise<BookActSummariesTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT act_sum_id, book_id, user_id, act_index, summary, last_update
                 FROM book_act_summaries
                 WHERE act_sum_id = ?`,
                [id]
            ) as BookActSummariesTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le résumé d'acte complet.` : `Unable to retrieve complete act summary.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteChapterById(id: string, lang: "fr" | "en"):Promise<BookChaptersTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT chapter_id, book_id, author_id, title, hashed_title, words_count, chapter_order, last_update
                 FROM book_chapters
                 WHERE chapter_id = ?`,
                [id]
            ) as BookChaptersTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le chapitre complet.` : `Unable to retrieve complete chapter.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompletePlotPointById(id: string, lang: "fr" | "en"):Promise<BookPlotPointsTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT plot_point_id, title, hashed_title, summary, linked_incident_id, author_id, book_id, last_update
                 FROM book_plot_points
                 WHERE plot_point_id = ?`,
                [id]
            ) as BookPlotPointsTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le point d'intrigue complet.` : `Unable to retrieve complete plot point.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteIncidentById(id: string, lang: "fr" | "en"):Promise<BookIncidentsTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT incident_id, author_id, book_id, title, hashed_title, summary, last_update
                 FROM book_incidents
                 WHERE incident_id = ?`,
                [id]
            ) as BookIncidentsTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer l'incident complet.` : `Unable to retrieve complete incident.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteChapterContentById(id: string, lang: "fr" | "en"):Promise<BookChapterContentTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT content_id, chapter_id, author_id, version, content, words_count, time_on_it, last_update
                 FROM book_chapter_content
                 WHERE content_id = ?`,
                [id]
            ) as BookChapterContentTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le contenu de chapitre complet.` : `Unable to retrieve complete chapter content.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteChapterInfoById(id: string, lang: "fr" | "en"):Promise<BookChapterInfosTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT chapter_info_id, chapter_id, act_id, incident_id, plot_point_id, book_id, author_id, summary, goal, last_update
                 FROM book_chapter_infos
                 WHERE chapter_info_id = ?`,
                [id]
            ) as BookChapterInfosTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer les informations de chapitre complètes.` : `Unable to retrieve complete chapter info.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteCharacterById(id: string, lang: "fr" | "en"):Promise<BookCharactersTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT character_id, book_id, user_id, first_name, last_name, category, title, image, role, biography, history, last_update
                 FROM book_characters
                 WHERE character_id = ?`,
                [id]
            ) as BookCharactersTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le personnage complet.` : `Unable to retrieve complete character.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteCharacterAttributeById(id: string, lang: "fr" | "en"):Promise<BookCharactersAttributesTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT attr_id, character_id, user_id, attribute_name, attribute_value, last_update
                 FROM book_characters_attributes
                 WHERE attr_id = ?`,
                [id]
            ) as BookCharactersAttributesTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer l'attribut de personnage complet.` : `Unable to retrieve complete character attribute.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteLocationById(id: string, lang: "fr" | "en"):Promise<BookLocationTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT loc_id, book_id, user_id, loc_name, loc_original_name, last_update
                 FROM book_location
                 WHERE loc_id = ?`,
                [id]
            ) as BookLocationTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le lieu complet.` : `Unable to retrieve complete location.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteLocationElementById(id: string, lang: "fr" | "en"):Promise<LocationElementTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT element_id, location, user_id, element_name, original_name, element_description, last_update
                 FROM location_element
                 WHERE element_id = ?`,
                [id]
            ) as LocationElementTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer l'élément de lieu complet.` : `Unable to retrieve complete location element.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteLocationSubElementById(id: string, lang: "fr" | "en"):Promise<LocationSubElementTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT sub_element_id, element_id, user_id, sub_elem_name, original_name, sub_elem_description, last_update
                 FROM location_sub_element
                 WHERE sub_element_id = ?`,
                [id]
            ) as LocationSubElementTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le sous-élément de lieu complet.` : `Unable to retrieve complete location sub-element.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteWorldById(id: string, lang: "fr" | "en"):Promise<BookWorldTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT world_id, name, hashed_name, author_id, book_id, history, politics, economy, religion, languages, last_update
                 FROM book_world
                 WHERE world_id = ?`,
                [id]
            ) as BookWorldTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le monde complet.` : `Unable to retrieve complete world.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteWorldElementById(id: string, lang: "fr" | "en"):Promise<BookWorldElementsTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT element_id, world_id, user_id, element_type, name, original_name, description, last_update
                 FROM book_world_elements
                 WHERE element_id = ?`,
                [id]
            ) as BookWorldElementsTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer l'élément de monde complet.` : `Unable to retrieve complete world element.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }

    static async fetchCompleteIssueById(id: string, lang: "fr" | "en"):Promise<BookIssuesTable[]> {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT issue_id, author_id, book_id, name, hashed_issue_name, last_update
                 FROM book_issues
                 WHERE issue_id = ?`,
                [id]
            ) as BookIssuesTable[];
        } catch (e:unknown){
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le problème complet.` : `Unable to retrieve complete issue.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    static async fetchCompleteBookById(bookId: string, lang: "fr" | "en") {
        try {
            const db: Database = System.getDb();
            return db.all(
                `SELECT * FROM erit_books
                 WHERE book_id = ?`,
                [bookId]
            ) as EritBooksTable[];
        } catch (e: unknown) {
            if (e instanceof Error) {
                throw new Error(lang === 'fr' ? `Impossible de récupérer le livre complet.` : `Unable to retrieve complete book.`);
            } else {
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    static updateWorldElement(userId: string, elementId: string, name: string, description: string, lastUpdate: number,lang: "fr" | "en"):boolean {
        try {
            const db: Database = System.getDb();
            const query:string = `UPDATE book_world_elements SET name = ?, description = ?, last_update = FROM_UNIXTIME(?) WHERE element_id = UUID_TO_BIN(?) AND user_id = UUID_TO_BIN(?)`;
            const params:(string|number)[] = [name, description, lastUpdate, elementId, userId];
            const result:RunResult = db.run(query, params);
            return result.changes > 0;
        } catch (e:unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour l'élément du monde.` : `Unable to update world element.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
    
    static updateIssue(userId: string, bookId: string, issueId: string, name: string, hashedName: string, lastUpdate: number, lang: "fr" | "en"):boolean {
        try {
            const db: Database = System.getDb();
            const query:string = `UPDATE book_issues SET name = ?, hashed_issue_name = ?, last_update = FROM_UNIXTIME(?) WHERE issue_id = UUID_TO_BIN(?) AND author_id = UUID_TO_BIN(?) AND book_id = UUID_TO_BIN(?)`;
            const params:(string|number)[] = [name, hashedName, lastUpdate, issueId, userId, bookId];
            const result:RunResult = db.run(query, params);
            return result.changes > 0;
        } catch (e:unknown) {
            if (e instanceof Error) {
                console.error(`DB Error: ${e.message}`);
                throw new Error(lang === 'fr' ? `Impossible de mettre à jour la problématique.` : `Unable to update issue.`);
            } else {
                console.error("An unknown error occurred.");
                throw new Error(lang === 'fr' ? "Une erreur inconnue s'est produite." : "An unknown error occurred.");
            }
        }
    }
}
