import axios from 'axios';
import pool from '../../../lib/db';
import { NextResponse } from 'next/server';

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

// Affiliate/sponsorship link patterns
const SPONSOR_PATTERNS = [
    /amzn\.to/i, /amazon\.com/i, /bit\.ly/i, /goo\.gl/i, /tinyurl/i,
    /patreon\.com/i, /merch/i, /shop\./i, /discord\.gg/i, /affiliate/i,
    /sponsored/i, /promo/i, /code:/i, /discount/i, /link in bio/i,
    /click here/i, /buy now/i, /get \d+% off/i, /use code/i,
];

function detectSponsorshipPotential(description: string): {
    hasSponsor: boolean;
    signals: string[];
} {
    const signals: string[] = [];
    for (const pattern of SPONSOR_PATTERNS) {
        const match = description.match(pattern);
        if (match) signals.push(match[0]);
    }
    return { hasSponsor: signals.length > 0, signals };
}

function estimateMonetization(subs: number, totalViews: number, videoCount: number): {
    isMonetized: boolean;
    confidence: 'High' | 'Medium' | 'Low';
    reason: string;
} {
    const hasMinSubs = subs >= 1000;
    const hasMinWatchTime = totalViews >= 4000 * 60; // rough proxy
    const avgViews = videoCount > 0 ? totalViews / videoCount : 0;

    if (hasMinSubs && hasMinWatchTime) {
        return { isMonetized: true, confidence: 'High', reason: `${(subs / 1000).toFixed(1)}K subs + high watchtime` };
    }
    if (hasMinSubs && avgViews > 1000) {
        return { isMonetized: true, confidence: 'Medium', reason: 'Meets sub threshold, moderate views' };
    }
    return { isMonetized: false, confidence: 'Low', reason: 'Below YPP thresholds' };
}

interface ChannelResult {
    id: string;
    title: string;
    description: string;
    thumbnail: string;
    publishedAt: string;
    viewCount: string;
    subscriberCount: string;
    videoCount: string;
    // Computed metrics
    multiplier: number;
    engagementProxy: number; // avg views per video as engagement proxy
    monetization: { isMonetized: boolean; confidence: string; reason: string };
    sponsorship: { hasSponsor: boolean; signals: string[] };
    isOneHitWonder: boolean;
    velocityScore: number;
    viewCount2dAgo?: number;
    subscriberCount2dAgo?: number;
    viewCount7dAgo?: number;
    subscriberCount7dAgo?: number;
}

export async function GET(request: Request) {
    const { searchParams } = new URL(request.url);
    const q = searchParams.get('q');

    if (!q) {
        return NextResponse.json({ error: 'Query parameter "q" is required.' }, { status: 400 });
    }

    try {
        // 1. Search YouTube for channels
        const searchRes = await axios.get(`${YOUTUBE_API_BASE}/search`, {
            params: { part: 'snippet', q, type: 'channel', maxResults: 50, key: YOUTUBE_API_KEY },
        });

        const items = searchRes.data.items;
        if (!items || items.length === 0) {
            return NextResponse.json({ channels: [], opportunityZone: null });
        }

        const channelIds = items.map((i: any) => i.id.channelId).join(',');

        // 2. Get full stats for all channels
        const statsRes = await axios.get(`${YOUTUBE_API_BASE}/channels`, {
            params: { part: 'snippet,statistics', id: channelIds, key: YOUTUBE_API_KEY },
        });

        const channelsData = statsRes.data.items || [];

        // Read historical growth data ONLY for channels already in the watchlist
        const watchlistIds = channelIds.split(',');
        const placeholders = watchlistIds.map(() => '?').join(',');
        const [historyRows] = await pool.query(
            `SELECT
        w.channel_id AS id,
        s.viewCount AS viewCount2dAgo, s.subscriberCount AS subscriberCount2dAgo,
        s7.viewCount AS viewCount7dAgo, s7.subscriberCount AS subscriberCount7dAgo
       FROM watchlist w
       LEFT JOIN channel_stats s ON w.channel_id = s.channel_id AND s.date = DATE_SUB(CURDATE(), INTERVAL 2 DAY)
       LEFT JOIN channel_stats s7 ON w.channel_id = s7.channel_id AND s7.date = DATE_SUB(CURDATE(), INTERVAL 7 DAY)
       WHERE w.channel_id IN (${placeholders})`,
            watchlistIds
        ) as any[][];

        const historyMap: Record<string, any> = {};
        for (const row of historyRows) {
            historyMap[row.id] = row;
        }

        // 5. Compute all metrics per channel
        const results: ChannelResult[] = channelsData.map((c: any) => {
            const views = parseInt(c.statistics.viewCount || '0', 10);
            const subs = parseInt(c.statistics.subscriberCount || '0', 10);
            const videos = parseInt(c.statistics.videoCount || '0', 10);
            const hist = historyMap[c.id];

            const mul = subs > 0 ? parseFloat((views / subs).toFixed(1)) : 0;
            const avgViewsPerVideo = videos > 0 ? views / videos : 0;

            // 1-Hit Wonder: if one video could account for most views (avg is very low but total is decent)
            // Heuristic: if average views per video << total/1 but channel has multiple videos
            const isOneHitWonder = videos >= 5 && avgViewsPerVideo < (views / videos) * 0.1 ? false :
                // Better heuristic: if channel has many videos but avg views is very low vs total views
                (videos >= 10 && avgViewsPerVideo < views * 0.05 / videos);

            // Velocity score: % growth in subs over 7 days
            const subs7dAgo = hist?.subscriberCount7dAgo || 0;
            const views7dAgo = hist?.viewCount7dAgo || 0;
            const subGrowthPct = subs7dAgo > 0 ? ((subs - subs7dAgo) / subs7dAgo) * 100 : 0;
            const viewGrowthPct = views7dAgo > 0 ? ((views - views7dAgo) / views7dAgo) * 100 : 0;
            const velocityScore = parseFloat((subGrowthPct * 0.6 + viewGrowthPct * 0.4).toFixed(2));

            const monetization = estimateMonetization(subs, views, videos);
            const sponsorship = detectSponsorshipPotential(c.snippet.description || '');

            return {
                id: c.id,
                title: c.snippet.title,
                description: c.snippet.description || '',
                thumbnail: c.snippet.thumbnails?.default?.url || '',
                publishedAt: c.snippet.publishedAt,
                viewCount: c.statistics.viewCount || '0',
                subscriberCount: c.statistics.subscriberCount || '0',
                videoCount: c.statistics.videoCount || '0',
                multiplier: mul,
                engagementProxy: parseFloat((avgViewsPerVideo / Math.max(subs, 1) * 100).toFixed(2)),
                monetization,
                sponsorship,
                isOneHitWonder,
                velocityScore: isNaN(velocityScore) ? 0 : velocityScore,
                viewCount2dAgo: hist?.viewCount2dAgo || null,
                subscriberCount2dAgo: hist?.subscriberCount2dAgo || null,
                viewCount7dAgo: hist?.viewCount7dAgo || null,
                subscriberCount7dAgo: hist?.subscriberCount7dAgo || null,
            };
        });

        // 6. Opportunity Zone: high avg views but low avg subs = underserved niche
        const top10 = results.slice(0, 10);
        const avgViews10 = top10.reduce((s, c) => s + parseInt(c.viewCount, 10), 0) / top10.length;
        const avgSubs10 = top10.reduce((s, c) => s + parseInt(c.subscriberCount, 10), 0) / top10.length;
        const demandRatio = avgSubs10 > 0 ? avgViews10 / avgSubs10 : 0;
        const opportunityZone = {
            isOpportunity: demandRatio > 50,
            demandRatio: parseFloat(demandRatio.toFixed(1)),
            avgViews: Math.round(avgViews10),
            avgSubs: Math.round(avgSubs10),
            channelCount: results.length,
        };

        // Sort by multiplier descending by default
        results.sort((a: ChannelResult, b: ChannelResult) => parseInt(b.viewCount, 10) - parseInt(a.viewCount, 10));

        return NextResponse.json({ channels: results, opportunityZone });
    } catch (error: any) {
        console.error('Search API error:', error?.response?.data || error.message);
        return NextResponse.json({ error: 'Internal server error while fetching channels.' }, { status: 500 });
    }
}
