using System; using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; using System.Threading.Tasks; using FinlyticCore.Models.Assets; 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?.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: e.Id.ToString(), 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)) { string catKey = category.ToLowerInvariant(); filtered = filtered.Where(e => { string t = (e.EventType ?? string.Empty).ToLowerInvariant(); if (catKey.Contains("earn") || catKey.Contains("quartal") || catKey.Contains("ergebnis")) { return t.Contains("earn") || t.Contains("quart") || t.Contains("ergebnis") || t.Contains("finan") || t.Contains("report") || t.Contains("bilanz") || string.Equals(t, "event", StringComparison.OrdinalIgnoreCase); } if (catKey.Contains("ex") || catKey.Contains("div")) { return (t.Contains("ex") || t.Contains("div") || t.Contains("ausschütt")) && !t.Contains("pay") && !t.Contains("zahl"); } if (catKey.Contains("pay") || catKey.Contains("zahl")) { return t.Contains("pay") || t.Contains("zahl") || t.Contains("auszahl"); } if (catKey.Contains("split")) { return t.Contains("split"); } return t.Contains(catKey) || 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)); } 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()); } }