namespace CreateLabel_ML
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public class AtributosEnvioCartaPorteFedex
    {
        [JsonProperty("comment")]
        public string Comment { get; set; }

        [JsonProperty("customerCartaPorteFDX")]
        public CustomerCartaPorteFdx CustomerCartaPorteFdx { get; set; }
    }

    public partial class CustomerCartaPorteFdx
    {
        [JsonProperty("guia")]
        public string Guia { get; set; }

        [JsonProperty("ubicaciones")]
        public Ubicaciones Ubicaciones { get; set; }

        [JsonProperty("mercancias")]
        public Mercancias Mercancias { get; set; }
    }

    public partial class Mercancias
    {
        [JsonProperty("numTotalMercancias")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long NumTotalMercancias { get; set; }

        [JsonProperty("mercancia")]
        public List<Mercancia> Mercancia { get; set; }
    }

    public partial class Mercancia
    {
        [JsonProperty("bienesTransp")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long BienesTransp { get; set; }

        [JsonProperty("descripcion")]
        public string Descripcion { get; set; }

        [JsonProperty("cantidad")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long Cantidad { get; set; }

        [JsonProperty("claveUnidad")]
        public string ClaveUnidad { get; set; }

        [JsonProperty("unidad")]
        public string Unidad { get; set; }

        [JsonProperty("dimensiones")]
        public string Dimensiones { get; set; }

        [JsonProperty("materialPeligroso")]
        public string MaterialPeligroso { get; set; }

        [JsonProperty("cveMaterialPeligroso")]
        public string CveMaterialPeligroso { get; set; }

        [JsonProperty("embalaje")]
        public string Embalaje { get; set; }

        [JsonProperty("descripEmbalaje")]
        public string DescripEmbalaje { get; set; }

        [JsonProperty("pesoEnKg")]
        public string PesoEnKg { get; set; }

        [JsonProperty("valorMercancia")]
        public string ValorMercancia { get; set; }

        [JsonProperty("moneda")]
        public string Moneda { get; set; }

        [JsonProperty("fraccionArancelaria")]
        public string FraccionArancelaria { get; set; }

        [JsonProperty("uuidComercioExt")]
        public string UuidComercioExt { get; set; }
    }

    public partial class Ubicaciones
    {
        [JsonProperty("ubicacion")]
        public List<Ubicacion> Ubicacion { get; set; }
    }

    public partial class Ubicacion
    {
        [JsonProperty("origen", NullValueHandling = NullValueHandling.Ignore)]
        public Destino Origen { get; set; }

        [JsonProperty("domicilio")]
        public Domicilio Domicilio { get; set; }

        [JsonProperty("destino", NullValueHandling = NullValueHandling.Ignore)]
        public Destino Destino { get; set; }
    }

    public partial class Destino
    {
        [JsonProperty("idOrigen")]
        public string IdOrigen { get; set; }

        [JsonProperty("nombreDestinatario", NullValueHandling = NullValueHandling.Ignore)]
        public string NombreDestinatario { get; set; }

        [JsonProperty("rfcDestinatario", NullValueHandling = NullValueHandling.Ignore)]
        public string RfcDestinatario { get; set; }

        [JsonProperty("numRegIdTrib")]
        public string NumRegIdTrib { get; set; }

        [JsonProperty("residenciaFiscal")]
        public string ResidenciaFiscal { get; set; }

        [JsonProperty("numEstacion")]
        public string NumEstacion { get; set; }

        [JsonProperty("nombreEstacion")]
        public string NombreEstacion { get; set; }

        [JsonProperty("fechaHoraSalida")]
        public string FechaHoraSalida { get; set; }

        [JsonProperty("nombreRemitente", NullValueHandling = NullValueHandling.Ignore)]
        public string NombreRemitente { get; set; }

        [JsonProperty("rfcRemitente", NullValueHandling = NullValueHandling.Ignore)]
        public string RfcRemitente { get; set; }
    }

    public partial class Domicilio
    {
        [JsonProperty("calle")]
        public string Calle { get; set; }

        [JsonProperty("numeroExterior")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long NumeroExterior { get; set; }

        [JsonProperty("numeroInterior")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long NumeroInterior { get; set; }

        [JsonProperty("colonia")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long Colonia { get; set; }

        [JsonProperty("localidad")]
        public string Localidad { get; set; }

        [JsonProperty("referencia")]
        public string Referencia { get; set; }

        [JsonProperty("municipio")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long Municipio { get; set; }

        [JsonProperty("estado")]
        public string Estado { get; set; }

        [JsonProperty("pais")]
        public string Pais { get; set; }

        [JsonProperty("codigoPostal")]
        [JsonConverter(typeof(ParseStringConverter))]
        public long CodigoPostal { get; set; }
    }

    internal class ParseStringConverter : JsonConverter
    {
        public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?);

        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null) return null;
            var value = serializer.Deserialize<string>(reader);
            long l;
            if (Int64.TryParse(value, out l))
            {
                return l;
            }
            throw new Exception("Cannot unmarshal type long");
        }

        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
        {
            if (untypedValue == null)
            {
                serializer.Serialize(writer, null);
                return;
            }
            var value = (long)untypedValue;
            serializer.Serialize(writer, value.ToString());
            return;
        }

        public static readonly ParseStringConverter Singleton = new ParseStringConverter();
    }



}
