import {Injectable, Logger} from '@nestjs/common';
import Parser from 'rss-parser';
import {TrendItem, CollectorResult} from '../../common/interfaces/trend-item.interface';

interface FeedConfig {
    url: string;
    category: string;
    name: string;
    language: string;
    priority: number; // 1=high, 5=low
}

// =========================================
// 🆓 TẤT CẢ ĐỀU FREE — chỉ cần HTTP GET
// =========================================
const RSS_FEEDS: FeedConfig[] = [
    //japan
    {
        url: 'https://newsonjapan.com/rss/top.xml',
        category: 'japan',
        language: 'jp',
        priority: 1,
        name: 'newsonjapan'
    },
    {
        url: 'https://www.nytimes.com/svc/collections/v1/publish/http://www.nytimes.com/topic/destination/japan/rss.xml',
        category: 'japan',
        language: 'jp',
        priority: 1,
        name: 'nytimes_japan'
    },
    {
        url: 'https://www3.nhk.or.jp/rss/news/cat0.xml',
        category: 'japan',
        language: 'jp',
        priority: 1,
        name: 'nhk',
    },
    {
        url: 'https://news.yahoo.co.jp/rss/topics/top-picks.xml',
        category: 'japan',
        language: 'jp',
        priority: 1,
        name: 'yahoo',
    },
    // // ── Vietnam ──
    // {
    //     url: 'https://vnexpress.net/rss/tin-moi-nhat.rss',
    //     category: 'vietnam',
    //     name: 'VnExpress',
    //     language: 'vi',
    //     priority: 1,
    // },
    // {
    //     url: 'https://tuoitre.vn/rss/tin-moi-nhat.rss',
    //     category: 'vietnam',
    //     name: 'Tuổi Trẻ',
    //     language: 'vi',
    //     priority: 1,
    // },
    // {
    //     url: 'https://thanhnien.vn/rss/home.rss',
    //     category: 'vietnam',
    //     name: 'Thanh Niên',
    //     language: 'vi',
    //     priority: 2,
    // },
    // ── Tech ──
    {
        url: 'https://techcrunch.com/feed/',
        category: 'tech',
        name: 'TechCrunch',
        language: 'en',
        priority: 1,
    },
    {
        url: 'https://www.theverge.com/rss/index.xml',
        category: 'tech',
        name: 'The Verge',
        language: 'en',
        priority: 1,
    },
    {
        url: 'https://feeds.arstechnica.com/arstechnica/index',
        category: 'tech',
        name: 'Ars Technica',
        language: 'en',
        priority: 2,
    },
    {
        url: 'https://www.wired.com/feed/rss',
        category: 'tech',
        name: 'Wired',
        language: 'en',
        priority: 2,
    },
    // ── World News ──
    {
        url: 'https://feeds.bbci.co.uk/news/rss.xml',
        category: 'world',
        name: 'BBC News',
        language: 'en',
        priority: 1,
    },
    {
        url: 'https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml',
        category: 'world',
        name: 'NY Times',
        language: 'en',
        priority: 1,
    },
    {
        url: 'https://www.reuters.com/rssFeed/topNews',
        category: 'world',
        name: 'Reuters',
        language: 'en',
        priority: 1,
    },
    // ── Science ──
    {
        url: 'https://www.sciencedaily.com/rss/all.xml',
        category: 'science',
        name: 'ScienceDaily',
        language: 'en',
        priority: 2,
    },
    // ── Business ──
    {
        url: 'https://feeds.bloomberg.com/markets/news.rss',
        category: 'business',
        name: 'Bloomberg',
        language: 'en',
        priority: 1,
    },
    // ── AI / Dev ──
    {
        url: 'https://blog.google/innovation-and-ai/technology/ai/rss/',
        category: 'tech',
        name: 'Google AI Blog',
        language: 'en',
        priority: 2,
    },
    {
        url: 'https://openai.com/news/rss.xml',
        category: 'tech',
        name: 'OpenAI Blog',
        language: 'en',
        priority: 2,
    },
    //google trend rss https://trends.google.com/trending/rss?geo=JP
    // {
    //     url: 'https://trends.google.com/trending/rss?geo=JP',
    //     category: 'news',
    //     name: 'google_trends',
    //     language: 'japan',
    //     priority: 1,
    // },
    // {
    //     url: 'https://trends.google.com/trending/rss?geo=US',
    //     category: 'us',
    //     name: 'google_trends',
    //     language: 'en',
    //     priority: 1,
    // },
    // {
    //     url: 'https://trends.google.com/trending/rss?geo=KR',
    //     category: 'korean',
    //     name: 'google_trends',
    //     language: 'en',
    //     priority: 1,
    // },
];
// const RSS_FEEDS_2: FeedConfig[] = [
//
//     {
//         url: 'https://trends.google.com/trending/rss?geo=US',
//         category: 'us',
//         name: 'google_trends',
//         language: 'en',
//         priority: 1,
//     },
// ];

@Injectable()
export class RssService {
    private readonly logger = new Logger(RssService.name);
    private readonly parser: Parser;

    constructor() {
        this.parser = new Parser({
            timeout: 10000,
            headers: {
                'User-Agent': 'TrendHunter RSS Reader/1.0',
                Accept: 'application/rss+xml, application/xml, text/xml',
            },
            customFields: {
                item: [
                    ['media:content', 'mediaContent'],
                    ['media:thumbnail', 'mediaThumbnail'],
                ],
            },
        });
    }

    async collect(categories?: string[]): Promise<CollectorResult> {
        const start = Date.now();

        // Filter feeds theo category nếu có
        const feeds = categories
            ? RSS_FEEDS.filter((f) => categories.includes(f.category))
            : RSS_FEEDS;

        // Parse tất cả feeds song song
        const results = await Promise.allSettled(
            feeds.map((feed) => this.parseFeed(feed)),
        );

        const items: TrendItem[] = [];
        const errors: string[] = [];

        results.forEach((result, index) => {
            if (result.status === 'fulfilled') {
                items.push(...result.value);
            } else {
                errors.push(`${feeds[index].name}: ${result.reason?.message}`);
                this.logger.warn(
                    `RSS failed for ${feeds[index].name}: ${result.reason?.message}`,
                );
            }
        });

        const successCount = results.filter((r) => r.status === 'fulfilled').length;
        this.logger.log(
            `RSS collected: ${items.length} items from ${successCount}/${feeds.length} feeds`,
        );

        return {
            source: 'rss',
            items,
            collectedAt: new Date(),
            durationMs: Date.now() - start,
            error: errors.length > 0 ? errors.join('; ') : undefined,
        };
    }

    private async parseFeed(feedConfig: FeedConfig): Promise<TrendItem[]> {
        const feed = await this.parser.parseURL(feedConfig.url);
        const feedItems = feed.items || [];
        // console.log('feedItems', feedItems);
        //check name='google_trends'

        return feedItems.slice(0, 15).map((item, index) => {
            const pubDate = item.pubDate ? new Date(item.pubDate) : new Date();
            const recencyHours =
                (Date.now() - pubDate.getTime()) / (1000 * 60 * 60);

            return {
                source: `rss:${feedConfig.name}`,
                title: (item.title || '').trim(),
                description: this.cleanHtml(
                    item.contentSnippet || item.content || '',
                ).substring(0, 500),
                url: item.link || '',
                score: this.calculateScore(index, feedConfig.priority, recencyHours),
                timestamp: pubDate,
                category: feedConfig.category,
                tags: [
                    feedConfig.name,
                    feedConfig.language,
                    ...(item.categories || []).slice(0, 3),
                ].filter(Boolean),
                engagement: {},
                raw: {
                    feedName: feedConfig.name,
                    feedUrl: feedConfig.url,
                    creator: item.creator || item['dc:creator'],
                    guid: item.guid,
                    categories: item.categories,
                    language: feedConfig.language,
                },
            } as TrendItem;
        });
    }

    private calculateScore(
        position: number,
        priority: number,
        recencyHours: number,
    ): number {
        // RSS không có engagement data → dùng position + recency + source priority
        const positionScore = Math.max(50 - position * 4, 5);
        const priorityBonus = (6 - priority) * 5; // priority 1 → +25, priority 5 → +5
        const recencyBonus = recencyHours < 2 ? 20 : recencyHours < 6 ? 10 : 0;

        return Math.min(positionScore + priorityBonus + recencyBonus, 100);
    }

    private cleanHtml(html: string): string {
        return html
            .replace(/<[^>]*>/g, '')
            .replace(/&nbsp;/g, ' ')
            .replace(/&amp;/g, '&')
            .replace(/&lt;/g, '<')
            .replace(/&gt;/g, '>')
            .replace(/&quot;/g, '"')
            .replace(/\s+/g, ' ')
            .trim();
    }
}
