import { ipcMain } from 'electron';
import { createHandler } from '../database/LocalSystem.js';
import Spell from '../database/models/Spell.js';
import type {
    SpellProps,
    SpellListResponse,
    SpellTagProps,
} from '../database/models/Spell.js';

// ==================== INTERFACES ====================

interface SpellPost {
    id?: string;
    name: string;
    description: string;
    appearance: string;
    tags: string[];
    powerLevel?: string | null;
    components?: string | null;
    limitations?: string | null;
    notes?: string | null;
    seriesSpellId?: string | null;
}

interface GetSpellListData {
    bookid: string;
}

interface GetSpellTagsData {
    bookid: string;
}

interface GetSpellDetailData {
    spellid: string;
}

interface CreateSpellData {
    bookId: string;
    spell: SpellPost;
}

interface UpdateSpellData {
    spellId: string;
    spell: SpellPost;
}

interface DeleteSpellData {
    spellId: string;
    bookId: string;
    deletedAt: number;
}

interface CreateTagData {
    bookId: string;
    name: string;
    color?: string | null;
}

interface UpdateTagData {
    tagId: string;
    name: string;
    color?: string | null;
}

interface DeleteTagData {
    tagId: string;
    bookId: string;
    deletedAt: number;
}

// ==================== SPELL HANDLERS ====================

// GET /spell/list
ipcMain.handle(
    'db:spell:list',
    createHandler<GetSpellListData, SpellListResponse>(
        function (userId: string, data: GetSpellListData, lang: 'fr' | 'en'): SpellListResponse {
            return Spell.getSpellList(userId, data.bookid, lang);
        },
    ),
);

// GET /spell/tags
ipcMain.handle(
    'db:spell:tags',
    createHandler<GetSpellTagsData, SpellTagProps[]>(
        function (userId: string, data: GetSpellTagsData, lang: 'fr' | 'en'): SpellTagProps[] {
            return Spell.getSpellTags(userId, data.bookid, lang);
        },
    ),
);

// GET /spell/detail
ipcMain.handle(
    'db:spell:detail',
    createHandler<GetSpellDetailData, SpellProps>(
        function (userId: string, data: GetSpellDetailData, lang: 'fr' | 'en'): SpellProps {
            return Spell.getSpellDetail(userId, data.spellid, lang);
        },
    ),
);

// POST /spell/add
ipcMain.handle(
    'db:spell:create',
    createHandler<CreateSpellData, string>(
        function (userId: string, data: CreateSpellData, lang: 'fr' | 'en'): string {
            const spell: SpellPost = data.spell;
            const result: SpellProps = Spell.addSpell(
                userId,
                data.bookId,
                spell.name,
                spell.description,
                spell.appearance,
                spell.tags || [],
                spell.powerLevel || null,
                spell.components || null,
                spell.limitations || null,
                spell.notes || null,
                spell.id,
                lang,
                spell.seriesSpellId || null,
            );
            return result.id;
        },
    ),
);

// PUT /spell/update
ipcMain.handle(
    'db:spell:update',
    createHandler<UpdateSpellData, boolean>(
        function (userId: string, data: UpdateSpellData, lang: 'fr' | 'en'): boolean {
            const spell: SpellPost = data.spell;
            return Spell.updateSpell(
                userId,
                data.spellId,
                spell.name,
                spell.description,
                spell.appearance,
                spell.tags || [],
                spell.powerLevel || null,
                spell.components || null,
                spell.limitations || null,
                spell.notes || null,
                lang,
                spell.seriesSpellId || null,
            );
        },
    ),
);

// DELETE /spell/delete
ipcMain.handle(
    'db:spell:delete',
    createHandler<DeleteSpellData, boolean>(
        function (userId: string, data: DeleteSpellData, lang: 'fr' | 'en'): boolean {
            return Spell.deleteSpell(userId, data.bookId, data.spellId, data.deletedAt, lang);
        },
    ),
);

// ==================== SPELL TAG HANDLERS ====================

// POST /spell/tag/add
ipcMain.handle(
    'db:spell:tag:create',
    createHandler<CreateTagData, string>(
        function (userId: string, data: CreateTagData, lang: 'fr' | 'en'): string {
            const result: SpellTagProps = Spell.addSpellTag(
                userId,
                data.bookId,
                data.name,
                data.color || null,
                undefined,
                lang,
            );
            return result.id;
        },
    ),
);

// PUT /spell/tag/update
ipcMain.handle(
    'db:spell:tag:update',
    createHandler<UpdateTagData, boolean>(
        function (userId: string, data: UpdateTagData, lang: 'fr' | 'en'): boolean {
            return Spell.updateSpellTag(
                userId,
                data.tagId,
                data.name,
                data.color || null,
                lang,
            );
        },
    ),
);

// DELETE /spell/tag/delete
ipcMain.handle(
    'db:spell:tag:delete',
    createHandler<DeleteTagData, boolean>(
        function (userId: string, data: DeleteTagData, lang: 'fr' | 'en'): boolean {
            return Spell.deleteSpellTag(userId, data.bookId, data.tagId, data.deletedAt, lang);
        },
    ),
);
