using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System.Net.Http.Json; using Mercados.Core.Entities; using Mercados.Infrastructure.Persistence.Repositories; using System.Text.Json.Serialization; namespace Mercados.Infrastructure.DataFetchers { // Añadimos las clases DTO necesarias para deserializar la respuesta de Finnhub public class MarketHolidayResponse { [JsonPropertyName("data")] public List? Data { get; set; } } public class MarketHoliday { [JsonPropertyName("at")] public string? At { get; set; } [JsonIgnore] public DateOnly Date => DateOnly.FromDateTime(DateTime.Parse(At!)); } public class HolidayDataFetcher : IDataFetcher { public string SourceName => "Holidays"; private readonly string[] _marketCodes = { "US", "BA" }; private readonly IHttpClientFactory _httpClientFactory; private readonly IMercadoFeriadoRepository _feriadoRepository; private readonly IConfiguration _configuration; private readonly ILogger _logger; public HolidayDataFetcher( IHttpClientFactory httpClientFactory, IMercadoFeriadoRepository feriadoRepository, IConfiguration configuration, ILogger logger) { _httpClientFactory = httpClientFactory; _feriadoRepository = feriadoRepository; _configuration = configuration; _logger = logger; } public async Task<(bool Success, string Message)> FetchDataAsync() { _logger.LogInformation("Iniciando actualización de feriados desde Finnhub."); var apiKey = _configuration["ApiKeys:Finnhub"]; if (string.IsNullOrEmpty(apiKey)) return (false, "API Key de Finnhub no configurada."); var client = _httpClientFactory.CreateClient("FinnhubDataFetcher"); foreach (var marketCode in _marketCodes) { try { var apiUrl = $"https://finnhub.io/api/v1/stock/market-holiday?exchange={marketCode}&token={apiKey}"; // Ahora la deserialización funcionará porque la clase existe var response = await client.GetFromJsonAsync(apiUrl); if (response?.Data != null) { var nuevosFeriados = response.Data.Select(h => new MercadoFeriado { CodigoMercado = marketCode, Fecha = h.Date.ToDateTime(TimeOnly.MinValue), Nombre = "Feriado Bursátil" }).ToList(); await _feriadoRepository.ReemplazarFeriadosPorMercadoAsync(marketCode, nuevosFeriados); _logger.LogInformation("Feriados para {MarketCode} actualizados exitosamente: {Count} registros.", marketCode, nuevosFeriados.Count); } } catch (Exception ex) { _logger.LogError(ex, "Falló la obtención de feriados para {MarketCode}.", marketCode); } } return (true, "Actualización de feriados completada."); } } }