import axios from 'axios';
import { NextResponse } from 'next/server';

const KEY = process.env.YOUTUBE_API_KEY;
const BASE = 'https://www.googleapis.com/youtube/v3';

// Stopwords to exclude from keyword extraction
const STOPWORDS = new Set([
    'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with',
    'is', 'was', 'are', 'were', 'be', 'been', 'has', 'have', 'had', 'do', 'does', 'did',
    'this', 'that', 'these', 'those', 'it', 'its', 'my', 'your', 'our', 'their', 'i',
    'we', 'he', 'she', 'they', 'you', 'me', 'him', 'her', 'us', 'them', 'how', 'what',
    'when', 'where', 'why', 'who', 'which', 'from', 'into', 'by', 'as', 'up', 'out',
    'get', 'got', 'no', 'not', 'so', 'if', 'all', 'more', 'about', 'just', 'than',
    'then', 'now', 'new', 'can', 'will', 'would', 'could', 'should', 'one', 'two',
    'vs', 'ft', 'ep', 'full', 'video', 'shorts', 'short', 'youtube', 'channel',
]);

function extractKeywords(texts: string[]): { word: string; count: number }[] {
    const freq: Record<string, number> = {};
    for (const text of texts) {
        const words = text.toLowerCase().replace(/[^a-z0-9\s]/g, '').split(/\s+/);
        for (const w of words) {
            if (w.length > 3 && !STOPWORDS.has(w)) {
                freq[w] = (freq[w] || 0) + 1;
            }
        }
    }
    return Object.entries(freq)
        .map(([word, count]) => ({ word, count }))
        .filter(k => k.count > 1)
        .sort((a, b) => b.count - a.count)
        .slice(0, 30);
}

export async function GET(
    _req: Request,
    { params }: { params: Promise<{ id: string }> }
) {
    const { id } = await params;
    if (!id) return NextResponse.json({ error: 'Channel ID required' }, { status: 400 });

    try {
        // 1. Channel details
        const chRes = await axios.get(`${BASE}/channels`, {
            params: {
                part: 'snippet,statistics,brandingSettings,topicDetails',
                id,
                key: KEY,
            },
        });
        const channel = chRes.data.items?.[0];
        if (!channel) return NextResponse.json({ error: 'Channel not found' }, { status: 404 });

        // 2. Fetch latest 50 videos via search (ordered by date)
        const searchRes = await axios.get(`${BASE}/search`, {
            params: {
                part: 'id',
                channelId: id,
                type: 'video',
                order: 'viewCount',
                maxResults: 50,
                key: KEY,
            },
        });
        const videoIds = (searchRes.data.items || [])
            .map((i: any) => i.id.videoId)
            .filter(Boolean)
            .join(',');

        let videos: any[] = [];
        if (videoIds) {
            // 3. Get full stats for those videos
            const vidRes = await axios.get(`${BASE}/videos`, {
                params: {
                    part: 'snippet,statistics,contentDetails',
                    id: videoIds,
                    key: KEY,
                },
            });
            videos = (vidRes.data.items || []).map((v: any) => {
                const dur = v.contentDetails?.duration || '';
                // PT1M30S -> seconds
                const match = dur.match(/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/);
                const totalSeconds = match
                    ? (parseInt(match[1] || '0') * 3600 +
                        parseInt(match[2] || '0') * 60 +
                        parseInt(match[3] || '0'))
                    : 0;
                const isShort = totalSeconds > 0 && totalSeconds <= 60;
                const views = parseInt(v.statistics?.viewCount || '0', 10);
                const likes = parseInt(v.statistics?.likeCount || '0', 10);
                const comments = parseInt(v.statistics?.commentCount || '0', 10);
                const engRate = views > 0 ? parseFloat(((likes + comments) / views * 100).toFixed(2)) : 0;

                return {
                    id: v.id,
                    title: v.snippet.title,
                    thumbnail: v.snippet.thumbnails?.medium?.url || '',
                    publishedAt: v.snippet.publishedAt,
                    views,
                    likes,
                    comments,
                    engRate,
                    duration: totalSeconds,
                    isShort,
                    tags: v.snippet.tags || [],
                    description: v.snippet.description || '',
                };
            });
        }

        // 4. Keyword extraction from titles + tags
        const titles = videos.map(v => v.title);
        const allTags = videos.flatMap(v => v.tags);
        const titleKeywords = extractKeywords(titles);
        // Tag frequency
        const tagFreq: Record<string, number> = {};
        for (const tag of allTags) {
            const t = tag.toLowerCase().trim();
            if (t.length > 2) tagFreq[t] = (tagFreq[t] || 0) + 1;
        }
        const topTags = Object.entries(tagFreq)
            .sort((a, b) => b[1] - a[1])
            .slice(0, 20)
            .map(([tag, count]) => ({ tag, count }));

        // 5. Channel-level analytics
        const totalViews = parseInt(channel.statistics.viewCount || '0', 10);
        const totalSubs = parseInt(channel.statistics.subscriberCount || '0', 10);
        const totalVideos = parseInt(channel.statistics.videoCount || '0', 10);
        const avgViewsPerVideo = totalVideos > 0 ? Math.round(totalViews / totalVideos) : 0;
        const viewsPerSub = totalSubs > 0 ? parseFloat((totalViews / totalSubs).toFixed(1)) : 0;

        // Sort videos by views to find outperformers
        const sortedByViews = [...videos].sort((a, b) => b.views - a.views);
        const topVideoViews = sortedByViews[0]?.views || 0;
        const videosWithOutperformer = videos.map(v => ({
            ...v,
            isOutperformer: v.views >= avgViewsPerVideo * 3 && v.views > 1000,
            outperformRatio: avgViewsPerVideo > 0 ? parseFloat((v.views / avgViewsPerVideo).toFixed(1)) : 0,
        }));

        // Upload frequency (avg days between uploads)
        const sortedByDate = [...videos].sort((a, b) => new Date(a.publishedAt).getTime() - new Date(b.publishedAt).getTime());
        let uploadFrequencyDays = 0;
        let uploadFrequencyLabel = 'Unknown';
        if (sortedByDate.length >= 2) {
            const first = new Date(sortedByDate[0].publishedAt).getTime();
            const last = new Date(sortedByDate[sortedByDate.length - 1].publishedAt).getTime();
            const daySpan = (last - first) / (1000 * 60 * 60 * 24);
            uploadFrequencyDays = parseFloat((daySpan / (sortedByDate.length - 1)).toFixed(1));
            if (uploadFrequencyDays < 1.5) uploadFrequencyLabel = 'Daily';
            else if (uploadFrequencyDays < 4) uploadFrequencyLabel = `Every ${Math.round(uploadFrequencyDays)} days`;
            else if (uploadFrequencyDays < 9) uploadFrequencyLabel = 'Weekly';
            else if (uploadFrequencyDays < 20) uploadFrequencyLabel = 'Bi-weekly';
            else if (uploadFrequencyDays < 40) uploadFrequencyLabel = 'Monthly';
            else uploadFrequencyLabel = `Every ~${Math.round(uploadFrequencyDays)} days`;
        }

        // Geography tier based on channel country
        const TIER1 = new Set(['US', 'GB', 'CA', 'AU', 'NZ', 'IE', 'DE', 'NL', 'SE', 'NO', 'DK', 'CH', 'AT', 'BE', 'FR']);
        const channelCountry = channel.snippet.country || '';
        const geographyTier = TIER1.has(channelCountry) ? '1' : channelCountry ? '2' : 'Unknown';
        const geographyLabel = TIER1.has(channelCountry)
            ? `🟢 Tier 1 — ${channelCountry} (High RPM)`
            : channelCountry
                ? `🟡 Tier 2/3 — ${channelCountry}`
                : '⚪ Unknown';

        return NextResponse.json({
            channel: {
                id: channel.id,
                title: channel.snippet.title,
                description: channel.snippet.description,
                customUrl: channel.snippet.customUrl,
                publishedAt: channel.snippet.publishedAt,
                country: channel.snippet.country || '',
                thumbnail: channel.snippet.thumbnails?.high?.url || channel.snippet.thumbnails?.default?.url || '',
                banner: channel.brandingSettings?.image?.bannerExternalUrl || '',
                keywords: channel.brandingSettings?.channel?.keywords || '',
                totalViews,
                totalSubs,
                totalVideos,
                avgViewsPerVideo,
                viewsPerSub,
                topVideoViews,
                topics: channel.topicDetails?.topicCategories || [],
                uploadFrequencyDays,
                uploadFrequencyLabel,
                geographyTier,
                geographyLabel,
            },
            videos: videosWithOutperformer,
            titleKeywords,
            topTags,
        });
    } catch (error: any) {
        const msg = error?.response?.data?.error?.message || error.message;
        console.error('Channel detail API error:', msg);
        return NextResponse.json({ error: msg || 'Failed to fetch channel data' }, { status: 500 });
    }
}
