// /api/discover/faceless
// Discovers faceless & AI-generated video niches using the YouTube API.
// Uses ytGet() for automatic key rotation on 403/quota errors.
// One search call per niche group (was 3) = 12 calls total (was 36).

import { NextResponse } from 'next/server';
import { ytGet } from '../../../../lib/youtubeApi';

function fmt(n: number): string {
    if (n >= 1_000_000) return (n / 1_000_000).toFixed(1) + 'M';
    if (n >= 1_000) return (n / 1_000).toFixed(1) + 'K';
    return n.toLocaleString();
}

const NICHE_GROUPS = [
    { name: 'AI Art & Image Generation', query: 'AI art generation midjourney shorts', icon: '🎨' },
    { name: 'AI Music Shorts', query: 'AI generated music suno shorts', icon: '🎵' },
    { name: 'Faceless Motivation / Quotes', query: 'motivational quotes faceless shorts', icon: '💬' },
    { name: 'Stock Footage + Narration', query: 'facts narrated stock footage shorts', icon: '📽️' },
    { name: 'Lo-fi / Chill / Study Music', query: 'lofi study music animated shorts', icon: '🎧' },
    { name: 'Whiteboard / Animation Explainer', query: 'whiteboard animation explained shorts', icon: '✏️' },
    { name: 'AI Voice / Text-to-Speech', query: 'AI voiceover TTS reddit stories shorts', icon: '🔊' },
    { name: 'Nature & Relaxation (B-roll)', query: 'relaxing nature ambient sounds shorts no talking', icon: '🌿' },
    { name: 'Satisfying / ASMR Visual', query: 'satisfying ASMR visual no face shorts', icon: '✨' },
    { name: 'AI Tools & Tutorial Shorts', query: 'AI tools chatgpt tutorial shorts', icon: '🤖' },
    { name: 'Animated Trivia / Quiz', query: 'trivia quiz animated shorts no face', icon: '🧠' },
    { name: 'Dark Ambient / Horror Visuals', query: 'dark ambient horror atmospheric shorts', icon: '🌑' },
];

const WHY_FACELESS: Record<string, string> = {
    'AI Art & Image Generation': 'Pure AI output — no camera or voice needed. Generate with Midjourney/DALL-E + screen record.',
    'AI Music Shorts': 'Generate with Suno/Udio, add visualizer. Fully automated pipeline possible.',
    'Faceless Motivation / Quotes': 'Text overlay + stock footage + AI voice. Dozens of channels hit 100K+ this way.',
    'Stock Footage + Narration': 'Royalty-free footage + ElevenLabs voice. No camera, no editing face.',
    'Lo-fi / Chill / Study Music': 'Animated GIF loop + AI music. Some channels earn from YouTube Music payouts.',
    'Whiteboard / Animation Explainer': 'Use Canva or VideoScribe. Script → AI voice → animate.',
    'AI Voice / Text-to-Speech': 'Copy Reddit thread → ElevenLabs → add background. Millions of views per week on this format.',
    'Nature & Relaxation (B-roll)': 'Film once, repurpose forever. Or use stock. Pure passive income play.',
    'Satisfying / ASMR Visual': 'Film objects, not people. Simple setup, strong algorithm push.',
    'AI Tools & Tutorial Shorts': 'Screen record tutorials + AI voiceover. High CPM ($15-30) and strong watch time.',
    'Animated Trivia / Quiz': 'PowerPoint-style animations + AI voice. Very low effort to produce.',
    'Dark Ambient / Horror Visuals': 'AI image + AI music + no face. Viral potential on Shorts.',
};

export async function GET() {
    const results = await Promise.all(
        NICHE_GROUPS.map(async (group) => {
            try {
                // ONE search per group (100 quota units), rotated
                const searchData = await ytGet('/search', {
                    q: group.query, type: 'video', videoDuration: 'short',
                    order: 'viewCount', part: 'snippet', maxResults: 8,
                });

                const items: any[] = searchData.items || [];
                const channelIds = [...new Set(items.map((i: any) => i.snippet?.channelId).filter(Boolean))] as string[];

                let avgSubs = 0, avgViews = 0;
                let channelDetails: any[] = [];

                if (channelIds.length) {
                    // channels.list = 1 quota unit
                    const chData = await ytGet('/channels', {
                        id: channelIds.join(','), part: 'snippet,statistics',
                    });
                    channelDetails = chData.items || [];
                    const subs = channelDetails.map((c: any) => parseInt(c.statistics?.subscriberCount || '0'));
                    const views = channelDetails.map((c: any) => parseInt(c.statistics?.viewCount || '0'));
                    avgSubs = subs.length ? Math.round(subs.reduce((a: number, b: number) => a + b, 0) / subs.length) : 0;
                    avgViews = views.length ? Math.round(views.reduce((a: number, b: number) => a + b, 0) / views.length) : 0;
                }

                // Score based on views/subs ratio and channel count
                const ratio = avgSubs > 0 ? avgViews / avgSubs : 0;
                const score = Math.round(Math.min(
                    10 + Math.min(channelDetails.length * 4, 30) + Math.min(avgViews / 1_000_000, 30) + Math.min(ratio / 5, 30),
                    100
                ));

                return {
                    name: `${group.icon} ${group.name}`,
                    score,
                    channelCount: channelDetails.length,
                    avgViews,
                    avgSubs,
                    channels: channelDetails.slice(0, 6).map((c: any) => ({
                        channelId: c.id,
                        channelTitle: c.snippet?.title || '',
                        thumbnail: c.snippet?.thumbnails?.medium?.url || c.snippet?.thumbnails?.default?.url || '',
                        subs: parseInt(c.statistics?.subscriberCount || '0'),
                    })),
                    viabilityLabel: score >= 65 ? '🔥 High Demand' : score >= 50 ? '✅ Solid' : score >= 35 ? '⚠️ Moderate' : '💤 Niche',
                    whyFaceless: WHY_FACELESS[group.name] || 'No face required — content is the star.',
                };
            } catch (err: any) {
                if (err?.quotaExhausted) throw err; // bubble up to abort all
                console.warn(`[Faceless] "${group.name}" failed:`, err?.message);
                return {
                    name: `${group.icon} ${group.name}`, score: 0,
                    channelCount: 0, avgViews: 0, avgSubs: 0, channels: [],
                    viabilityLabel: '⚠️ Data unavailable',
                    whyFaceless: WHY_FACELESS[group.name] || '',
                };
            }
        })
    );

    results.sort((a, b) => b.score - a.score);
    return NextResponse.json({ niches: results, fetchedAt: new Date().toISOString() });
}
