import { getAllExtensions, getExtension } from '../../shared/extensions';
import { GallerySearchResult, GalleryInfo, Favorite, FavoriteResult } from '../types';
import { getDatabase } from '../../shared/database';

export async function getGalleryInfo(id: string, providerName?: string): Promise<any> {
    const extensions = getAllExtensions();

    if (providerName) {
        const ext = extensions.get(providerName);
        if (ext && ext.type === 'image-board' && ext.getInfo) {
            try {
                console.log(`[Gallery] Getting info from ${providerName} for: ${id}`);
                const info = await ext.getInfo(id);
                return {
                    id: info.id ?? id,
                    provider: providerName,
                    image: info.image,
                    tags: info.tags,
                    title: info.title,
                    headers: info.headers
                };
            } catch (e) {
                const error = e as Error;
                console.error(`[Gallery] Failed to get info from ${providerName}:`, error.message);
                throw new Error(`Failed to get gallery info from ${providerName}`);
            }
        }
        throw new Error("Provider not found or doesn't support getInfo");
    }

    for (const [name, ext] of extensions) {
        if (ext.type === 'gallery' && ext.getInfo) {
            try {
                console.log(`[Gallery] Trying to get info from ${name} for: ${id}`);
                const info = await ext.getInfo(id);
                return {
                    ...info,
                    provider: name
                };
            } catch {
                continue;
            }
        }
    }

    throw new Error("Gallery item not found in any extension");
}

export async function searchInExtension(providerName: string, query: string, page: number = 1, perPage: number = 48): Promise<any> {
    const ext = getExtension(providerName);

    try {
        console.log(`[Gallery] Searching ONLY in ${providerName} for: ${query}`);
        const results = await ext.search(query, page, perPage);

        const normalizedResults = (results?.results ?? []).map((r: any) => ({
            id: r.id,
            image: r.image,
            tags: r.tags,
            title: r.title,
            headers: r.headers,
            provider: providerName
        }));

        return {
            page: results.page ?? page,
            hasNextPage: !!results.hasNextPage,
            results: normalizedResults
        };

    } catch (e) {
        const error = e as Error;
        console.error(`[Gallery] Search failed in ${providerName}:`, error.message);

        return {
            total: 0,
            next: 0,
            previous: 0,
            pages: 0,
            page,
            hasNextPage: false,
            results: []
        };
    }
}

export async function getFavorites(userId: number): Promise<Favorite[]> {
    const db = getDatabase("favorites");

    return new Promise((resolve) => {
        db.all(
            'SELECT * FROM favorites WHERE user_id = ?',
            [userId],
            (err: Error | null, rows: Favorite[]) => {
                if (err) {
                    console.error('Error getting favorites:', err.message);
                    resolve([]);
                } else {
                    resolve(rows);
                }
            }
        );
    });
}

export async function getFavoriteById(id: string, userId: number): Promise<Favorite | null> {
    const db = getDatabase("favorites");

    return new Promise((resolve) => {
        db.get(
            'SELECT * FROM favorites WHERE id = ? AND user_id = ?',
            [id, userId],
            (err: Error | null, row: Favorite | undefined) => {
                if (err) {
                    console.error('Error getting favorite by id:', err.message);
                    resolve(null);
                } else {
                    resolve(row || null);
                }
            }
        );
    });
}

export async function addFavorite(fav: Favorite & { user_id: number }): Promise<FavoriteResult> {
    const db = getDatabase("favorites");

    return new Promise((resolve) => {
        const stmt = `
            INSERT INTO favorites (id, user_id, title, image_url, thumbnail_url, tags, headers, provider)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)
        `;

        db.run(
            stmt,
            [
                fav.id,
                fav.user_id,
                fav.title,
                fav.image_url,
                fav.thumbnail_url,
                fav.tags || "",
                fav.headers || "",
                fav.provider || ""
            ],
            function (err: any) {
                if (err) {
                    if (err.code && err.code.includes('SQLITE_CONSTRAINT')) {
                        resolve({ success: false, error: 'Item is already a favorite.' });
                    } else {
                        console.error('Error adding favorite:', err.message);
                        resolve({ success: false, error: err.message });
                    }
                } else {
                    resolve({ success: true, id: fav.id });
                }
            }
        );
    });
}

export async function removeFavorite(id: string, userId: number): Promise<FavoriteResult> {
    const db = getDatabase("favorites");

    return new Promise((resolve) => {
        const stmt = 'DELETE FROM favorites WHERE id = ? AND user_id = ?';

        db.run(stmt, [id, userId], function (err: Error | null) {
            if (err) {
                console.error('Error removing favorite:', err.message);
                resolve({ success: false, error: err.message });
            } else {
                // @ts-ignore
                resolve({ success: this.changes > 0 });
            }
        });
    });
}