using System.Diagnostics;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace DM.MovieApi.ApiRequest;

/// <summary>
/// Extends the native Newtonsoft IsoDateTimeConverter to allow deserializing partial dates.
/// </summary>
public class IsoDateTimeConverterEx : IsoDateTimeConverter
{
    /// <summary>
    /// Reads the JSON representation of the object.
    /// </summary>
    /// <param name="reader">The Newtonsoft.Json.JsonReader to read from.</param>
    /// <param name="objectType">Type of the object.</param>
    /// <param name="existingValue">The existing value of object being read.</param>
    /// <param name="serializer">The calling serializer.</param>
    /// <returns>The object value.</returns>
    public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer )
    {
        ConditionalTraceReaderValue( reader );

        try
        {
            return base.ReadJson( reader, objectType, existingValue, serializer );
        }
        catch( Exception ex ) when( ex is FormatException
                                    || ex is JsonSerializationException jse
                                    && jse.Message.Contains( "System.DateTime" ) )
        {
            string val = reader.Value?.ToString();

            if( val?.Length == 4 && int.TryParse( val, out int year ) )
            {
                return new DateTime( year, 1, 1 );
            }

            return DateTime.UnixEpoch;
        }
    }

    [Conditional( "DEBUG" )]
    private void ConditionalTraceReaderValue( JsonReader reader )
    {
        string val = reader.Value?.ToString();
        if( string.IsNullOrWhiteSpace( val ) )
        {
            val = "<empty>";
        }

        Trace.WriteLine( val, "IsoDateTimeConverterEx" );
    }
}
