using System; using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; using System.Threading.Tasks; using FinlyticAssets.Models; using FinlyticBackend.Util; using FinlyticCore.Dtos; using FinlyticCore.Dtos.Fundamentals; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; namespace FinlyticBackend.Controllers; [ApiController] [Authorize] [Route("api/v1/calendar")] public class CalendarController : ControllerBase { private readonly WebMqttClient _mqttClient; private readonly ILogger _logger; public CalendarController(WebMqttClient mqttClient, ILogger logger) { _mqttClient = mqttClient; _logger = logger; } /// /// Retrieves corporate calendar events with optional filters. /// [HttpGet("events/{year:int?}/{month:int?}")] public async Task GetCorporateCalendar( int? year = null, int? month = null, [FromQuery] string? category = null, [FromQuery] DateTime? date = null, [FromQuery] string? symbol = null, [FromQuery] string? isin = null) { string? activeSymbol = !string.IsNullOrWhiteSpace(symbol) ? symbol.Trim() : isin?.Trim(); int targetYear = year ?? DateTime.UtcNow.Year; int targetMonth = month ?? DateTime.UtcNow.Month; try { if (_mqttClient.IsConnected) { var rawEvents = await _mqttClient.SendRpcRequestAsync, GetEventsByMonthRequest>( "events_GetByMonth", new GetEventsByMonthRequest(targetYear, targetMonth), TimeSpan.FromSeconds(4) ); if (rawEvents != null && rawEvents.Count > 0) { var allAssets = AssetsController.LoadAssetsFromIndexJson() ?? new List(); var isinLookup = allAssets .Where(a => !string.IsNullOrEmpty(a.Isin)) .GroupBy(a => a.Isin, StringComparer.OrdinalIgnoreCase) .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase); var parsedEvents = rawEvents.Select(e => { string eventIsin = e.Isin ?? string.Empty; string ticker = e.Ticker ?? string.Empty; string companyName = e.CompanyName ?? string.Empty; string eventType = e.EventType ?? string.Empty; DateTime eventDate = e.Date; string image = $"/api/v1/logo/{eventIsin}"; if (!string.IsNullOrEmpty(eventIsin) && isinLookup.TryGetValue(eventIsin, out var matchedAsset)) { if (!string.IsNullOrWhiteSpace(matchedAsset.Name)) { companyName = matchedAsset.Name; } if (!string.IsNullOrWhiteSpace(matchedAsset.Image)) { image = matchedAsset.Image; } } return new CalendarEventResponseDto( Id: $"evt-{eventIsin}-{eventDate:yyyyMMdd}-{eventType}", Symbol: string.IsNullOrWhiteSpace(ticker) ? eventIsin : ticker, CompanyName: companyName, EventType: eventType, EventDate: eventDate, Date: eventDate.ToString("o"), Isin: eventIsin, Ticker: ticker, Description: $"{eventType} - {companyName}", Details: $"Termin für {companyName} am {eventDate:dd.MM.yyyy}", Image: image ); }); // Optionales Filtern var filtered = parsedEvents; if (!string.IsNullOrWhiteSpace(category) && !string.Equals(category, "Alle", StringComparison.OrdinalIgnoreCase) && !string.Equals(category, "all", StringComparison.OrdinalIgnoreCase)) { filtered = filtered.Where(e => string.Equals(e.EventType, category, StringComparison.OrdinalIgnoreCase)); } if (date.HasValue) { filtered = filtered.Where(e => e.EventDate.Date == date.Value.Date); } if (!string.IsNullOrWhiteSpace(activeSymbol)) { filtered = filtered.Where(e => string.Equals(e.Isin, activeSymbol, StringComparison.OrdinalIgnoreCase) || string.Equals(e.Ticker, activeSymbol, StringComparison.OrdinalIgnoreCase) || string.Equals(e.Symbol, activeSymbol, StringComparison.OrdinalIgnoreCase) ); } return Ok(filtered.OrderBy(e => e.EventDate).ToList()); } } else { _logger.LogWarning("[CalendarController] MQTT client is NOT connected to broker."); } } catch (Exception ex) { _logger.LogWarning(ex, "[CalendarController] Failed to retrieve corporate events via MQTT RPC."); } return Ok(new List()); } }