import { getJson } from 'serpapi';
import db from '../db';

interface RankingResult {
    rank: number | null;
    foundUrl: string | null;
    error?: string;
}

export async function checkRanking(keyword: string, targetUrl: string): Promise<RankingResult> {
    const apiKey = process.env.SERPAPI_KEY;

    if (!apiKey) {
        console.error('SERPAPI_KEY is missing');
        return { rank: null, foundUrl: null, error: 'SERPAPI_KEY missing' };
    }

    // Domain normalization for easier matching
    // Removes protocol, www, and trailing slashes
    const normalizeUrl = (url: string) => {
        try {
            const u = new URL(url.startsWith('http') ? url : `https://${url}`);
            return u.hostname.replace('www.', '') + u.pathname.replace(/\/$/, '');
        } catch (e) {
            return url.replace('www.', '').replace(/\/$/, '');
        }
    };

    const normalizedTarget = normalizeUrl(targetUrl);

    return new Promise((resolve) => {
        try {
            getJson(
                {
                    engine: 'google',
                    q: keyword,
                    api_key: apiKey,
                    num: 100, // Check top 100 results
                },
                (json: any) => {
                    if (json.error) {
                        console.error('SerpApi error:', json.error);
                        resolve({ rank: null, foundUrl: null, error: json.error });
                        return;
                    }

                    if (!json.organic_results) {
                        resolve({ rank: null, foundUrl: null });
                        return;
                    }

                    for (const result of json.organic_results) {
                        const resultUrl = result.link;
                        const normalizedResult = normalizeUrl(resultUrl);

                        // Check if result contains our target domain
                        if (normalizedResult.includes(normalizedTarget) || normalizedTarget.includes(normalizedResult)) {
                            resolve({
                                rank: result.position,
                                foundUrl: resultUrl,
                            });
                            return;
                        }
                    }

                    resolve({ rank: null, foundUrl: null });
                }
            );
        } catch (error: any) {
            console.error('SeoService error:', error);
            resolve({ rank: null, foundUrl: null, error: error.message });
        }
    });
}

export async function processSeoChecks(monitorId: string, url: string, keywords: string[]) {
    if (!keywords || keywords.length === 0) return;

    console.log(`[SEO] Starting checks for monitor ${monitorId} (${keywords.length} keywords)`);

    for (const keyword of keywords) {
        const result = await checkRanking(keyword, url);

        if (result.rank !== null || result.foundUrl !== null) {
            console.log(`[SEO] Found rank ${result.rank} for "${keyword}"`);
        } else {
            console.log(`[SEO] Not found in top 100 for "${keyword}"`);
        }

        // Save to DB
        await db.rankings.create({
            monitorId,
            keyword,
            rank: result.rank,
            urlFound: result.foundUrl
        });
    }
}
