using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using NewsAnalysis.Data;
using NewsAnalysis.Models;

namespace NewsAnalysis.Services;

public class NewsService : INewsService
{
    private readonly HttpClient _httpClient;
    private readonly ApplicationDbContext _db;
    private readonly IConfiguration _config;

    public NewsService(HttpClient httpClient, ApplicationDbContext db, IConfiguration config)
    {
        _httpClient = httpClient;
        _db = db;
        _config = config;
    }

    public async Task FetchAndSaveNewsAsync(int maxPages = 2, int startPage = 0)
    {
        var country = _config["CollectApi:Country"];
        var tag = _config["CollectApi:Tag"];

        var existingUrls = (await _db.News.Select(n => n.Url).ToListAsync()).ToHashSet();
        var fetchedAt = DateTime.UtcNow;
        var page = startPage;

        while (page < startPage + maxPages)
        {
            var response = await _httpClient.GetAsync(
                $"news/getNews?country={country}&tag={tag}&paging={page}");

            if (!response.IsSuccessStatusCode)
            {
                var errorBody = await response.Content.ReadAsStringAsync();
                throw new HttpRequestException($"API {(int)response.StatusCode} hatası: {errorBody}");
            }

            var json = await response.Content.ReadAsStringAsync();
            var apiResponse = JsonSerializer.Deserialize<NewsApiResponse>(json);

            if (apiResponse is null || !apiResponse.Success || apiResponse.Result.Count == 0)
                break;

            var newItems = apiResponse.Result
                .Where(item => !existingUrls.Contains(item.Url))
                .Select(item => new News
                {
                    Url = item.Url,
                    Description = item.Description,
                    Image = item.Image,
                    Name = item.Name,
                    Source = item.Source
                })
                .ToList();

            if (newItems.Any())
            {
                _db.News.AddRange(newItems);
                await _db.SaveChangesAsync(); // Parçalı kayıt: her sayfadan sonra db'ye yazar
                
                // Tracklemeyi temizle ki RAM şişmesin
                _db.ChangeTracker.Clear(); 
                
                newItems.ForEach(n => existingUrls.Add(n.Url));
            }

            page++;
            await Task.Delay(1500);
        }
    }
}
