import Book from "../models/Book.js";
import Borrow from "../models/BorrowRecord.js";
import User from "../models/User.js";
import { ApiError } from "../utils/helpers.js";

class LibraryService {
    // Book Services
    async addBook(title, author, description) {
        const doesExist = await Book.findOne({ title });
        if (doesExist) {
            throw new ApiError(400, "Book already exists");
        }
        const book = new Book({ title, author, description });
        await book.save();
        return book;
    }

    async updateBook(bookId, title, author, description) {
        const book = await Book.findById(bookId);
        if (!book) {
            throw new ApiError(404, "Book not found");
        }
        book.title = title;
        book.author = author;
        book.description = description;
        await book.save();
        return book;
    }

    async deleteBook(bookId) {
        const book = await Book.findById(bookId);
        if (!book) {
            throw new ApiError(404, "Book not found");
        }
        await book.deleteOne();
        await Borrow.deleteMany({ bookId });
        return { message: "Book deleted successfully" };
    }

    async getAllBooks() {
        return await Book.find();
    }

    // Borrow Services
    async addBorrow(bookId, clientId, dueDate) {
        const book = await Book.findById(bookId);
        if (!book) {
            throw new ApiError(404, "Book not found");
        }

        const client = await User.findById(clientId);
        if (!client) {
            throw new ApiError(404, "Client not found");
        }

        const borrow = new Borrow({ bookId, clientId, dueDate });
        await borrow.save();
        return await Borrow.findById(borrow._id)
            .populate("bookId", "title author description")
            .populate("clientId", "username role age");
    }

    async getAllBorrows() {
        return await Borrow.find()
            .populate("bookId", "title author description")
            .populate("clientId", "username role age");
    }

    async updateBorrow(borrowId, bookId, clientId, dueDate) {
        const borrow = await Borrow.findById(borrowId);
        if (!borrow) {
            throw new ApiError(404, "Borrow not found");
        }

        const book = await Book.findById(bookId);
        if (!book) {
            throw new ApiError(404, "Book not found");
        }

        const client = await User.findById(clientId);
        if (!client) {
            throw new ApiError(404, "Client not found");
        }

        borrow.bookId = bookId;
        borrow.clientId = clientId;
        borrow.dueDate = dueDate;
        await borrow.save();
        return borrow;
    }

    async deleteBorrow(borrowId) {
        const borrow = await Borrow.findById(borrowId);
        if (!borrow) {
            throw new ApiError(404, "Borrow not found");
        }
        await borrow.deleteOne();
        return { message: "Borrow deleted successfully" };
    }
}

export default new LibraryService();