import fs from 'fs/promises';
import path from 'path';
import { Prompt, PromptCache } from '@/lib/types';
import { JimmyLvCrawler, YouMindCrawler, ZeroLuCrawler } from '@/lib/crawler';

const DATA_FILE = path.join(process.cwd(), 'data', 'prompts.json');

export async function getPrompts(): Promise<PromptCache> {
    try {
        const fileContent = await fs.readFile(DATA_FILE, 'utf-8');
        return JSON.parse(fileContent);
    } catch (e) {
        return { prompts: [], last_updated: null, categories: {}, total_count: 0, sources: [] };
    }
}

export async function syncPromptsService(): Promise<{ success: boolean, count: number, added: number }> {
    console.log("[SyncService] Starting sync...");

    // 1. Crawl all sources
    const jimmyCrawler = new JimmyLvCrawler();
    const youMindCrawler = new YouMindCrawler();
    const zeroLuCrawler = new ZeroLuCrawler();

    const [jimmyPrompts, youMindPrompts, zeroLuPrompts] = await Promise.all([
        jimmyCrawler.crawl(),
        youMindCrawler.crawl(),
        zeroLuCrawler.crawl()
    ]);

    const crawledPrompts = [...jimmyPrompts, ...youMindPrompts, ...zeroLuPrompts];
    console.log(`[SyncService] Total crawled ${crawledPrompts.length} prompts (Jimmy: ${jimmyPrompts.length}, YouMind: ${youMindPrompts.length}, ZeroLu: ${zeroLuPrompts.length}).`);

    // 2. Read existing
    const cache = await getPrompts();
    const existingPrompts = cache.prompts || [];

    // 3. Merge
    let addedCount = 0;
    const now = Date.now();
    const finalPrompts: Prompt[] = [];
    const existingMap = new Map<string, Prompt>();

    existingPrompts.forEach(p => {
        if (p.source_url) {
            existingMap.set(p.source_url, p);
        } else {
            finalPrompts.push(p);
        }
    });

    crawledPrompts.forEach(newP => {
        const existing = existingMap.get(newP.source_url);
        if (existing) {
            finalPrompts.push({
                ...newP,
                id: existing.id,
                images: existing.images,
                createdAt: existing.createdAt || (existing.published ? new Date(existing.published).getTime() : undefined),
                useCount: existing.useCount,
                lastUsedAt: existing.lastUsedAt
            });
            existingMap.delete(newP.source_url);
        } else {
            addedCount++;
            finalPrompts.push({
                ...newP,
                createdAt: now,
                useCount: 0
            });
        }
    });

    // Add remaining existing
    existingMap.forEach(p => finalPrompts.push(p));

    // Re-ID
    finalPrompts.forEach((p, i) => p.id = i + 1);

    // Meta
    const categories: Record<string, string[]> = {
        "style": Array.from(new Set(finalPrompts.map(p => p.category)))
    };

    const newCache: PromptCache = {
        last_updated: new Date(now).toISOString(),
        lastSync: now,
        categories,
        total_count: finalPrompts.length,
        sources: Array.from(new Set(finalPrompts.map(p => p.source))),
        prompts: finalPrompts
    };

    await fs.writeFile(DATA_FILE, JSON.stringify(newCache, null, 2), 'utf-8');

    return { success: true, count: finalPrompts.length, added: addedCount };
}
