using System;
using System.Xml.Serialization;

namespace ConverterDTE.Model.Dtos.Response
{
    [XmlRoot("DTE")]
    public class DTE_MediPiel
    {
        [XmlAttribute("version")]
        public required string Version { get; set; }

        [XmlElement("Documento")]
        public required DocumentoMP Documento { get; set; }

        [XmlElement("Personalizados")]
        public required PersonalizadosMP Personalizados { get; set; }


        public class DocumentoMP
        {
            [XmlAttribute("ID")]
            public required string ID { get; set; }

            [XmlElement("Encabezado")]
            public required Encabezado Encabezado { get; set; }

            [XmlElement("DscRcgGlobal")]
            public DscRcgGlobal? DscRcgGlobal { get; set; }

            [XmlElement("Detalle")]
            public Detalle[]? Detalle { get; set; }

            [XmlElement("CAE")]
            public required CAE CAE { get; set; }
        }

        public class Encabezado
        {
            [XmlElement("IdDoc")]
            public required IdDoc IdDoc { get; set; }

            [XmlElement("Emisor")]
            public required Emisor Emisor { get; set; }

            [XmlElement("Receptor")]
            public required Receptor Receptor { get; set; }

            [XmlElement("Totales")]
            public required Totales Totales { get; set; }

            [XmlElement("Impuestos")]
            public Impuestos[]? Impuestos { get; set; }

            [XmlElement("Retenciones")]
            public Retencion[]? Retenciones { get; set; }
        }

        public class IdDoc
        {
            public required string Ambiente { get; set; }
            public required string TipoServicio { get; set; }
            public required string Tipo { get; set; }
            public required string Serie { get; set; } //! En ambiente de pruebas es obligatorio
            public required string Numero { get; set; }
            public string? NumeroInterno { get; set; }
            public required string FechaEmis { get; set; } //! REVISAR FORMATO (yyy-mm-ddTHH:mm:ssZ)

            public string? Establecimiento { get; set; }
            public string? PtoEmis { get; set; }
            public string? FechaVenc { get; set; } //! Condicional, Si TipoNegociacion es Credito en nuestro caso NO APLICA
            public string? IndServicio { get; set; }

            //TODO Revisar estos campos
            // Ya que puede ser un array de pagos
            public required Pagos[] Pagos { get; set; }
            // public required string TipoPago { get; set; }
            // public string? DescPago { get; set; }
            // public string? FechaPago { get; set; }
            // public required string CondPago { get; set; }

        }

        public class Pagos
        {
            public required string TipoPago { get; set; }
            public string? DescPago { get; set; }
            public string? FechaPago { get; set; }
            public required string CondPago { get; set; }
        }

        public class Emisor
        {
            public required string TipoContribuyente { get; set; }
            public string? RegimenContable { get; set; }
            public string? CdgSucursal { get; set; }
            public string? CdgGLNEmisor { get; set; }
            public required string IDEmisor { get; set; }
            public required string NmbEmisor { get; set; }
            public required Nombre NombreEmisor { get; set; }
            public required CodigoEmisor CodigoEmisor { get; set; }
            public required Direccion DomFiscal { get; set; }
            public required Direccion LugarExped { get; set; }
            public required Contacto ContactoEmisor { get; set; }
        }

        public class Nombre
        {
            public required string PrimerNombre { get; set; }
            public string? Apellido { get; set; }

        }

        public class CodigoEmisor
        {
            public required string TpoCdgIntEmisor { get; set; }
            public required string CdgIntEmisor { get; set; }
        }

        public class Direccion
        {
            public required string Calle { get; set; }
            public required string Departamento { get; set; }
            public required string Ciudad { get; set; }
            public required string Pais { get; set; }
            public string? CodigoPostal { get; set; }
        }

        public class Contacto
        {
            public string? Nombre { get; set; }

            public string? Descripcion { get; set; }
            public required string eMail { get; set; }
            public string? Telefono { get; set; }
            public string? Fax { get; set; }
        }

        public class Receptor
        {
            public required string TipoContribuyenteR { get; set; }
            public string? RegimenContableR { get; set; } //? Factura Soporte
            public string? CdgGNLReceptor { get; set; }
            public string? CdgSucursal { get; set; }
            public required DocRecep DocRecep { get; set; }
            public required Nombre NombreRecep { get; set; }
            public CodigoReceptor? CodigoReceptor { get; set; }
            public Direccion? DomFiscalRcp { get; set; }
            public Direccion? LugarRecep { get; set; } //En caso de no enviar se toma la direccion de la factura
            public required Contacto ContactoReceptor { get; set; }
            public Persona? Persona { get; set; }
        }

        public class DocRecep
        {
            public required string TipoDocRecep { get; set; }
            public required string NroDocRecep { get; set; }
            public required string NmbRecep { get; set; }
        }

        public class CodigoReceptor
        {
            public string? TpoCdgIntRecep { get; set; }
            public string? CdgIntRecep { get; set; }
        }

        public class Persona
        {
            public DocPersona? DocPersona { get; set; }
            public Nombre? NombrePersona { get; set; }
            public Direccion? DomPersona { get; set; }
        }

        public class DocPersona
        {
            public string? TipoDocPers { get; set; }
            public string? DescTipoDoc { get; set; }
            public string? NroDocPers { get; set; }
            public string? NmbPersona { get; set; }
        }

        public class Totales
        {
            public required string Moneda { get; set; }
            public string? FctConv { get; set; }
            public string? FechaTCambio { get; set; }
            public required string SubTotal { get; set; }
            public string? MntDcto { get; set; }
            public string? MntRcgo { get; set; }
            public required string MntBase { get; set; }
            public string? MntImp { get; set; }
            public string? SaldoAnterior { get; set; }
            public required string VlrPagar { get; set; }
        }

        public class Impuestos
        {
            public string? TipoImp { get; set; }
            public string? TasaImp { get; set; }
            public string? PrecioPorUnidad { get; set; }
            public string? UnidadMedida { get; set; }
            public string? MontoBaseImp { get; set; }
            public string? MontoImp { get; set; }
        }

        public class Retencion
        {
            public string? TipoRet { get; set; }
            public string? TasaRet { get; set; }
            public string? MontoBaseRet { get; set; }
            public string? MontoRet { get; set; }
        }

        public class Detalle
        {
            public required string NroLinDet { get; set; }
            public required CdgItem CdgItem { get; set; }
            public string? TpoListaItem { get; set; }
            public string? DscLang { get; set; }
            public required string DscItem { get; set; }
            public required string QtyItem { get; set; }
            public required string UnmdItem { get; set; }
            public required string PrcBrutoItem { get; set; }

            public SubDscto[]? SubDscto { get; set; }
            public SubRecargo? SubRecargo { get; set; }
            public Impuestos[]? ImpuestosDet { get; set; }
            public Retencion[]? RetencionesDet { get; set; }
            public SubMonto? SubMonto { get; set; }
            public required string MontoTotalItem { get; set; }
        }

        public class CdgItem
        {
            public required string TpoCodigo { get; set; }
            public required string VlrCodigo { get; set; }

        }

        public class SubDscto
        {
            public string? TipoDscto { get; set; }
            public string? GlosaDscto { get; set; }
            public string? PctDscto { get; set; }
            public string? MntDscto { get; set; }
        }

        public class SubRecargo
        {
            public string? TipoRecargo { get; set; }
            public string? GlosaRecargo { get; set; }
            public string? PctRecargo { get; set; }
            public string? MntRecargo { get; set; }
        }

        public class SubMonto
        {
            public string? Tipo { get; set; }
            public string? CodTipoMonto { get; set; }
            public string? MontoConcepto { get; set; }
        }

        public class CAE
        {
            public required string Tipo { get; set; }
            public string? Serie { get; set; }
            public required string NumeroInicial { get; set; }
            public required string NumeroFinal { get; set; }
            public required string NroResolucion { get; set; }
            public required string FechaResolucion { get; set; }
            public required string ClaveTC { get; set; }
            public required string Plazo { get; set; }
        }

        public class DscRcgGlobal
        {
            public string? TpoMov { get; set; }
            public string? CodigoDR { get; set; }
            public string? GlosaDR { get; set; }
            public string? PctDR { get; set; }
            public string? ValorDR { get; set; }
        }

        public class PersonalizadosMP
        {
            [XmlElement("DocPersonalizado")]
            public required DocPersonalizado DocPersonalizado { get; set; }
        }

        public class DocPersonalizado
        {
            [XmlElement("campoString")]
            public required CampoString[] CampoStrings { get; set; }
        }
        public class CampoString
        {
            [XmlAttribute("name")]
            public required string Name { get; set; }

            [XmlText]
            public required string Value { get; set; }
        }
    }
}