import * as fs from 'fs';
import * as path from 'path';
import { getUserEncryptionKey } from "../keyManager.js";
import System from "../System.js";
import BookRepo, { BookCoverQuery } from "../repositories/book.repository.js";

/**
 * Cover model class for managing book cover images.
 * Provides methods to retrieve, decrypt, and delete cover pictures.
 */
export default class Cover {
    /**
     * Retrieves and decrypts the cover picture for a specific book.
     * @param userId - The unique identifier of the user
     * @param bookId - The unique identifier of the book
     * @param lang - The language for error messages ('fr' or 'en')
     * @returns The decrypted cover image data, or an empty string if not found
     */
    public static async getCoverPicture(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): Promise<string> {
        const coverQuery: BookCoverQuery = BookRepo.fetchBookCover(userId, bookId, lang);
        if (coverQuery) {
            const userEncryptionKey: string = getUserEncryptionKey(userId);
            return System.decryptDataWithUserKey(coverQuery.cover_image, userEncryptionKey);
        } else {
            return '';
        }
    }

    /**
     * Deletes the cover picture association for a specific book.
     * Clears the cover image reference in the database.
     * @param userId - The unique identifier of the user
     * @param bookId - The unique identifier of the book
     * @param lang - The language for error messages ('fr' or 'en')
     * @returns True if the cover was successfully deleted, false otherwise
     */
    public static async deleteCoverPicture(userId: string, bookId: string, lang: 'fr' | 'en' = 'fr'): Promise<boolean> {
        const existingCoverName: string = await Cover.getCoverPicture(userId, bookId, lang);
        return BookRepo.updateBookCover(bookId, '', userId, lang);
    }

    /**
     * Retrieves and decrypts a picture file, returning it as a base64-encoded string.
     * @param userId - The unique identifier of the user
     * @param userKey - The user's encryption key for decrypting the image path
     * @param image - The encrypted image file path
     * @param lang - The language for error messages ('fr' or 'en')
     * @returns The base64-encoded image data, or an empty string if the image cannot be read
     */
    public static getPicture(userId: string, userKey: string, image: string, lang: 'fr' | 'en' = 'fr'): string {
        if (!image) return '';
        try {
            const decryptedFileName: string = System.decryptDataWithUserKey(image, userKey);
            const userDirectory: string = path.join('');
            fs.accessSync(userDirectory, fs.constants.R_OK);
            const fileData: Buffer = fs.readFileSync(userDirectory);
            return fileData.toString('base64');
        } catch (error: unknown) {
            return '';
        }
    }
}
