using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace ManagerService.DTOs
{
///
/// Lenient settings for deserializing online agenda JSON from PHP APIs.
/// Any field with an unexpected type (e.g. false instead of string/object) is silently set to null.
///
public static class RemoteAgendaJsonSettings
{
public static readonly JsonSerializerSettings Lenient = new JsonSerializerSettings
{
Error = (_, args) => { args.ErrorContext.Handled = true; }
};
}
///
/// Converts boolean false (PHP "no value" pattern) or null to null for object-typed fields.
///
public class FalseToNullConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override bool CanWrite => false;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Boolean || reader.TokenType == JsonToken.Null)
{
reader.Skip();
return null;
}
var jObject = Newtonsoft.Json.Linq.JObject.Load(reader);
var target = Activator.CreateInstance(objectType)!;
serializer.Populate(jObject.CreateReader(), target);
return target;
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
=> throw new NotImplementedException();
}
///
/// Specialized DTO for parsing the simplified, localized JSON used by online agendas.
/// Matches the structure used in the tablet-app (snake_case).
///
public class RemoteEventAgendaDTO
{
public string? name { get; set; }
public string? description { get; set; }
public string? type { get; set; }
public string? date_added { get; set; }
public string? date_from { get; set; }
public string? date_to { get; set; }
public string? date_hour { get; set; }
public string? website { get; set; }
public string? phone { get; set; }
public string? email { get; set; }
public string? id_video_youtube { get; set; }
public string? image { get; set; }
[JsonConverter(typeof(FalseToNullConverter))]
public RemoteEventAddressDTO? address { get; set; }
public DateTime? GetDateFrom() => ParseDate(date_from);
public DateTime? GetDateTo() => ParseDate(date_to);
private DateTime? ParseDate(string? dateStr)
{
if (string.IsNullOrEmpty(dateStr)) return null;
// Handle YYYYMMDD format (e.g. "20260327")
if (dateStr.Length == 8 && long.TryParse(dateStr, out _))
if (DateTime.TryParseExact(dateStr, "yyyyMMdd", null, System.Globalization.DateTimeStyles.None, out var dt8))
return dt8;
if (DateTime.TryParse(dateStr, out var dt)) return dt;
return null;
}
}
public class RemoteEventAddressDTO
{
public string? address { get; set; }
public object? lat { get; set; }
public object? lng { get; set; }
public int? zoom { get; set; }
public string? place_id { get; set; }
public string? name { get; set; }
public string? street_number { get; set; }
public string? street_name { get; set; }
public string? city { get; set; }
public string? state { get; set; }
public string? post_code { get; set; }
public string? country { get; set; }
}
}