import { ipcMain } from 'electron';
import { createHandler } from '../database/LocalSystem.js';
import Series, { BooksOrderPost, SeriesDetailProps, SeriesListItemProps, SeriesBookProps } from '../database/models/Series.js';

interface CreateSeriesData {
    name: string;
    description?: string;
    bookIds?: string[];
}

interface UpdateSeriesData {
    seriesId: string;
    name: string;
    description?: string;
}

interface DeleteSeriesData {
    seriesId: string;
    deletedAt: number;
}

interface GetSeriesDetailData {
    seriesId: string;
}

interface AddBookToSeriesData {
    seriesId: string;
    bookId: string;
    order?: number;
}

interface RemoveBookFromSeriesData {
    seriesId: string;
    bookId: string;
    deletedAt: number;
}

interface UpdateBooksOrderData {
    seriesId: string;
    booksOrder: BooksOrderPost[];
}

interface GetSeriesForBookData {
    bookId: string;
}

interface GetSeriesBooksData {
    seriesId: string;
}

// GET /series/list - Get all series
ipcMain.handle('db:series:list', createHandler<void, SeriesListItemProps[]>(
    async function(userId: string, _body: void, lang: 'fr' | 'en'): Promise<SeriesListItemProps[]> {
        return await Series.getSeriesList(userId, lang);
    }
));

// GET /series/detail - Get series detail
ipcMain.handle('db:series:detail', createHandler<GetSeriesDetailData, SeriesDetailProps>(
    async function(userId: string, data: GetSeriesDetailData, lang: 'fr' | 'en'): Promise<SeriesDetailProps> {
        return await Series.getSeriesDetail(userId, data.seriesId, lang);
    }
));

// POST /series/add - Create new series
ipcMain.handle('db:series:create', createHandler<CreateSeriesData, string>(
    async function(userId: string, data: CreateSeriesData, lang: 'fr' | 'en'): Promise<string> {
        return await Series.createSeries(userId, data.name, data.description || '', lang, data.bookIds);
    }
));

// PUT /series/update - Update series
ipcMain.handle('db:series:update', createHandler<UpdateSeriesData, boolean>(
    async function(userId: string, data: UpdateSeriesData, lang: 'fr' | 'en'): Promise<boolean> {
        return await Series.updateSeries(userId, data.seriesId, data.name, data.description || '', lang);
    }
));

// DELETE /series/delete - Delete series
ipcMain.handle('db:series:delete', createHandler<DeleteSeriesData, boolean>(
    async function(userId: string, data: DeleteSeriesData, lang: 'fr' | 'en'): Promise<boolean> {
        return await Series.deleteSeries(userId, data.seriesId, data.deletedAt, lang);
    }
));

// GET /series/book/list - Get books in series
ipcMain.handle('db:series:books', createHandler<GetSeriesBooksData, SeriesBookProps[]>(
    async function(userId: string, data: GetSeriesBooksData, lang: 'fr' | 'en'): Promise<SeriesBookProps[]> {
        return await Series.getSeriesBooks(userId, data.seriesId, lang);
    }
));

// POST /series/book/add - Add book to series
ipcMain.handle('db:series:book:add', createHandler<AddBookToSeriesData, boolean>(
    async function(userId: string, data: AddBookToSeriesData, lang: 'fr' | 'en'): Promise<boolean> {
        return await Series.addBookToSeries(userId, data.seriesId, data.bookId, data.order ?? 1, lang);
    }
));

// DELETE /series/book/remove - Remove book from series
ipcMain.handle('db:series:book:remove', createHandler<RemoveBookFromSeriesData, boolean>(
    async function(userId: string, data: RemoveBookFromSeriesData, lang: 'fr' | 'en'): Promise<boolean> {
        return await Series.removeBookFromSeries(userId, data.seriesId, data.bookId, data.deletedAt, lang);
    }
));

// PUT /series/book/reorder - Reorder books in series
ipcMain.handle('db:series:book:reorder', createHandler<UpdateBooksOrderData, boolean>(
    async function(userId: string, data: UpdateBooksOrderData, lang: 'fr' | 'en'): Promise<boolean> {
        return await Series.updateBooksOrder(userId, data.seriesId, data.booksOrder, lang);
    }
));

// GET /series/for-book - Get series ID for a book
ipcMain.handle('db:series:forBook', createHandler<GetSeriesForBookData, string | null>(
    function(_userId: string, data: GetSeriesForBookData, _lang: 'fr' | 'en'): string | null {
        return Series.getSeriesIdForBook(data.bookId);
    }
));
