import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { firstValueFrom } from 'rxjs';
import { TrendItem, CollectorResult } from '../../common/interfaces/trend-item.interface';

@Injectable()
export class NewsApiService {
    private readonly logger = new Logger(NewsApiService.name);
    private readonly baseUrl = 'https://newsapi.org/v2';
    private readonly apiKey: string;

    // Track daily usage (free = 100 req/day)
    private dailyRequestCount = 0;
    private lastResetDate = new Date().toDateString();
    private readonly DAILY_LIMIT = 90; // Buffer 10 cho safety

    constructor(
        private readonly httpService: HttpService,
        private readonly configService: ConfigService,
    ) {
        this.apiKey = this.configService.get<string>('newsapi.key', '');
    }

    async collect(): Promise<CollectorResult> {
        const start = Date.now();

        if (!this.apiKey) {
            return {
                source: 'newsapi',
                items: [],
                collectedAt: new Date(),
                durationMs: 0,
                error: 'NEWSAPI_KEY not configured — skipping',
            };
        }

        if (!this.canMakeRequest()) {
            return {
                source: 'newsapi',
                items: [],
                collectedAt: new Date(),
                durationMs: 0,
                error: `Daily limit reached (${this.dailyRequestCount}/${this.DAILY_LIMIT})`,
            };
        }

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

        // 1. Top headlines (1 request)
        try {
            const headlines = await this.getTopHeadlines();
            items.push(...headlines);
        } catch (e) {
            errors.push(`headlines: ${e.message}`);
        }

        // 2. Top headlines cho VN (1 request)
        try {
            const vnHeadlines = await this.getTopHeadlines('vn');
            items.push(...vnHeadlines);
        } catch (e) {
            errors.push(`headlines-vn: ${e.message}`);
        }

        this.logger.log(
            `NewsAPI collected: ${items.length} items (${this.dailyRequestCount}/${this.DAILY_LIMIT} daily requests used)`,
        );

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

    /**
     * Top Headlines — 1 request mỗi lần gọi
     * Free tier: 100 requests/day
     */
    private async getTopHeadlines(country?: string): Promise<TrendItem[]> {
        this.incrementRequestCount();

        const params: Record<string, any> = {
            apiKey: this.apiKey,
            pageSize: 20,
        };

        if (country) {
            params.country = country;
        } else {
            // Nếu không chỉ định country, lấy theo category
            params.language = 'en';
            params.category = 'technology';
        }

        const { data } = await firstValueFrom(
            this.httpService.get(`${this.baseUrl}/top-headlines`, { params }),
        );

        if (data.status !== 'ok') {
            throw new Error(`NewsAPI error: ${data.message}`);
        }

        return (data.articles || []).map((article: any, index: number) => ({
            source: `newsapi${country ? `:${country}` : ''}`,
            title: article.title || '',
            description: article.description || '',
            url: article.url || '',
            score: this.calculateScore(index, article),
            timestamp: article.publishedAt
                ? new Date(article.publishedAt)
                : new Date(),
            category: country === 'vn' ? 'vietnam' : 'tech',
            tags: [article.source?.name].filter(Boolean),
            engagement: {},
            raw: {
                sourceName: article.source?.name,
                sourceId: article.source?.id,
                author: article.author,
                urlToImage: article.urlToImage,
            },
        }));
    }

    private calculateScore(index: number, article: any): number {
        const positionScore = Math.max(70 - index * 3, 10);
        // Boost nếu từ nguồn uy tín
        const topSources = [
            'bbc-news', 'cnn', 'reuters', 'the-verge',
            'techcrunch', 'bloomberg', 'associated-press',
        ];
        const sourceBonus = topSources.includes(article.source?.id) ? 15 : 0;

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

    private canMakeRequest(): boolean {
        this.resetDailyCountIfNeeded();
        return this.dailyRequestCount < this.DAILY_LIMIT;
    }

    private incrementRequestCount(): void {
        this.resetDailyCountIfNeeded();
        this.dailyRequestCount++;
    }

    private resetDailyCountIfNeeded(): void {
        const today = new Date().toDateString();
        if (today !== this.lastResetDate) {
            this.dailyRequestCount = 0;
            this.lastResetDate = today;
            this.logger.log('NewsAPI daily request counter reset');
        }
    }

    getRemainingRequests(): number {
        this.resetDailyCountIfNeeded();
        return Math.max(this.DAILY_LIMIT - this.dailyRequestCount, 0);
    }
}
