using System;

namespace CalculationBackend.Model.ImportExport
{
    public class SiaRecordG : SiaRecord
    {
        public SiaRecordG(string line) : base(line)
        {
            var kapitelnummer              = PaddedLine.Substring( Positions.Kapitelnummer.S              , Positions.Kapitelnummer.L              ).TrimEnd();
            var ausgabejahr                = PaddedLine.Substring( Positions.Ausgabejahr.S                , Positions.Ausgabejahr.L                ).TrimEnd();
            var leistungsposition          = PaddedLine.Substring( Positions.Leistungsposition.S          , Positions.Leistungsposition.L          ).TrimEnd();
            var variablennummer            = PaddedLine.Substring( Positions.Variablennummer.S            , Positions.Variablennummer.L            ).TrimEnd();
            var zeilennummer               = PaddedLine.Substring( Positions.Zeilennummer.S               , Positions.Zeilennummer.L               ).TrimEnd();
            var objektgliederung           = PaddedLine.Substring( Positions.Objektgliederung.S           , Positions.Objektgliederung.L           ).TrimEnd();
            var positionslage              = PaddedLine.Substring( Positions.Positionslage.S              , Positions.Positionslage.L              ).TrimEnd();
            var variantengruppe            = PaddedLine.Substring( Positions.Variantengruppe.S            , Positions.Variantengruppe.L            ).TrimEnd();
            var varianteInnerhalbDerGruppe = PaddedLine.Substring( Positions.VarianteInnerhalbDerGruppe.S , Positions.VarianteInnerhalbDerGruppe.L ).TrimEnd();
            var verbandskalkulation        = PaddedLine.Substring( Positions.Verbandskalkulation.S        , Positions.Verbandskalkulation.L        ).TrimEnd();
            var recordtyp                  = PaddedLine.Substring( Positions.Recordtyp.S                  , Positions.Recordtyp.L                  ).TrimEnd();
            var mengenart                  = PaddedLine.Substring( Positions.Mengenart.S                  , Positions.Mengenart.L                  ).TrimEnd();
            var vorzeichenMenge            = PaddedLine.Substring( Positions.VorzeichenMenge.S            , Positions.VorzeichenMenge.L            ).TrimEnd();
            var menge                      = PaddedLine.Substring( Positions.Menge.S                      , Positions.Menge.L                      ).TrimEnd();
            var mengeneinheit              = PaddedLine.Substring( Positions.Mengeneinheit.S              , Positions.Mengeneinheit.L              ).TrimEnd();
            var preisart                   = PaddedLine.Substring( Positions.Preisart.S                   , Positions.Preisart.L                   ).TrimEnd();
            var vorzeichenPreis            = PaddedLine.Substring( Positions.VorzeichenPreis.S            , Positions.VorzeichenPreis.L            ).TrimEnd();
            var preis                      = PaddedLine.Substring( Positions.Preis.S                      , Positions.Preis.L                      ).TrimEnd();
            var laufnummer                 = PaddedLine.Substring( Positions.Laufnummer.S                 , Positions.Laufnummer.L                 ).TrimEnd();
            var kagCode                    = PaddedLine.Substring( Positions.KagCode.S                    , Positions.KagCode.L                    ).TrimEnd();
            var elementcode                = PaddedLine.Substring( Positions.Elementcode.S                , Positions.Elementcode.L                ).TrimEnd();
            var positionstext              = PaddedLine.Substring( Positions.Positionstext.S              , Positions.Positionstext.L              ).TrimEnd();
            var spezielleCodierungen       = PaddedLine.Substring( Positions.SpezielleCodierungen.S       , Positions.SpezielleCodierungen.L       ).TrimEnd();

            this.Kapitelnummer              = (kapitelnummer              == string.Empty) ? null : kapitelnummer;
            this.Ausgabejahr                = (ausgabejahr                == string.Empty) ? null : ausgabejahr;
            this.Leistungsposition          = (leistungsposition          == string.Empty) ? null : leistungsposition;
            this.Variablennummer            = (variablennummer            == string.Empty) ? null : variablennummer;
            this.Zeilennummer               = (zeilennummer               == string.Empty) ? null : zeilennummer;
            this.Objektgliederung           = (objektgliederung           == string.Empty) ? null : objektgliederung;
            this.Positionslage              = (positionslage              == string.Empty) ? null : positionslage;
            this.Variantengruppe            = (variantengruppe            == string.Empty) ? null : variantengruppe;
            this.VarianteInnerhalbDerGruppe = (varianteInnerhalbDerGruppe == string.Empty) ? null : varianteInnerhalbDerGruppe;
            this.Verbandskalkulation        = (verbandskalkulation        == string.Empty) ? null : verbandskalkulation;
            this.Recordtyp                  = (recordtyp                  == string.Empty) ? null : recordtyp;
            this.Mengenart                  = (mengenart                  == string.Empty) ? null : mengenart;
            this.VorzeichenMenge            = (vorzeichenMenge            == string.Empty) ? null : vorzeichenMenge;
            this.Menge                      = (menge                      == string.Empty) ? null : menge;
            this.Mengeneinheit              = (mengeneinheit              == string.Empty) ? null : mengeneinheit;
            this.Preisart                   = (preisart                   == string.Empty) ? null : preisart;
            this.VorzeichenPreis            = (vorzeichenPreis            == string.Empty) ? null : vorzeichenPreis;
            this.Preis                      = (preis                      == string.Empty) ? null : preis;
            this.Laufnummer                 = (laufnummer                 == string.Empty) ? null : laufnummer;
            this.KagCode                    = (kagCode                    == string.Empty) ? null : kagCode;
            this.Elementcode                = (elementcode                == string.Empty) ? null : elementcode;
            this.Positionstext              = (positionstext              == string.Empty) ? null : positionstext;
            this.SpezielleCodierungen       = (spezielleCodierungen       == string.Empty) ? null : spezielleCodierungen;
        }

        public string Kapitelnummer { get; set; }
        //public string? (leer) { get; set; }
        public string? Ausgabejahr { get; set; }
        public string? Leistungsposition { get; set; }
        public string? Variablennummer { get; set; }
        public string? Zeilennummer { get; set; }
        public string? Objektgliederung { get; set; }
        public string? Positionslage { get; set; }
        public string? Variantengruppe { get; set; }
        public string? VarianteInnerhalbDerGruppe { get; set; }
        public string? Verbandskalkulation { get; set; }
        public string? Recordtyp { get; set; }
        //public string? (leer) { get; set; }
        public string? Mengenart { get; set; }
        public string? VorzeichenMenge { get; private set; }
        public string? Menge { get; private set; }
        public void setMenge(decimal? d)
        {
            (string? vorzeichen, string? menge) = setNumericalValue(d, 1000, 13);
            VorzeichenMenge = vorzeichen;
            Menge = menge;
        }
        public decimal? getMenge()
        {
            return getNumericalValue(VorzeichenMenge, Menge, 1000);
        }
        public string? Mengeneinheit { get; set; }
        public string? Preisart { get; set; }
        public string? VorzeichenPreis { get; private set; }
        public string? Preis { get; private set; }
        public void setPreis(decimal? d)
        {
            (string? vorzeichen , string? preis) = setNumericalValue(d, 100, 12);
            VorzeichenPreis = vorzeichen;
            Preis = preis;
        }
        public decimal? getPreis()
        {
            return getNumericalValue(VorzeichenPreis, Preis, 100);
        }

        private decimal? getNumericalValue(string? vorzeichen, string? wert, int verschiebungsFaktor)
        {
            if (wert == string.Empty || wert is null)
            {
                return null;
            }

            return (vorzeichen == "-" ? -1 : 1) * decimal.Parse(wert) / verschiebungsFaktor;
        }

        private (string?, string?) setNumericalValue(decimal? d, int verschiebungsFaktor, int padding)
        {
            string? vorzeichen = "+";
            string? wert = "";

            if (!d.HasValue) return (vorzeichen, wert);

            if (Math.Sign(d.Value) == -1)
            {
                vorzeichen = "-";
            }

            var absolutWert = Math.Abs(d.Value);
            wert = Decimal.Truncate(absolutWert * verschiebungsFaktor).ToString().PadLeft(padding, '0');
            return (vorzeichen, wert);
        }

        public string? Laufnummer { get; set; }
        public string? KagCode { get; set; }
        public string? Elementcode { get; set; }
        public string? Positionstext { get; set; }
        public string? SpezielleCodierungen { get; set; }

        public string Serialize()
        {
            string[] arr = new[] {
                "G",
                (Kapitelnummer              != null ? Kapitelnummer              : string.Empty ).ToString().PadRight(Positions.Kapitelnummer.L),
                " ",
                (Ausgabejahr                != null ? Ausgabejahr                : string.Empty ).ToString().PadRight(Positions.Ausgabejahr.L),
                (Leistungsposition          != null ? Leistungsposition          : string.Empty ).ToString().PadRight(Positions.Leistungsposition.L),
                (Variablennummer            != null ? Variablennummer            : string.Empty ).ToString().PadRight(Positions.Variablennummer.L),
                (Zeilennummer               != null ? Zeilennummer               : string.Empty ).ToString().PadRight(Positions.Zeilennummer.L),
                (Objektgliederung           != null ? Objektgliederung           : string.Empty ).ToString().PadRight(Positions.Objektgliederung.L),
                (Positionslage              != null ? Positionslage              : string.Empty ).ToString().PadRight(Positions.Positionslage.L),
                (Variantengruppe            != null ? Variantengruppe            : string.Empty ).ToString().PadRight(Positions.Variantengruppe.L),
                (VarianteInnerhalbDerGruppe != null ? VarianteInnerhalbDerGruppe : string.Empty ).ToString().PadRight(Positions.VarianteInnerhalbDerGruppe.L),
                (Verbandskalkulation        != null ? Verbandskalkulation        : string.Empty ).ToString().PadRight(Positions.Verbandskalkulation.L),
                (Recordtyp                  != null ? Recordtyp                  : string.Empty ).ToString().PadRight(Positions.Recordtyp.L),
                " ",
                (Mengenart                  != null ? Mengenart                  : string.Empty ).ToString().PadRight(Positions.Mengenart.L),
                (VorzeichenMenge            != null ? VorzeichenMenge            : string.Empty ).ToString().PadRight(Positions.VorzeichenMenge.L),
                (Menge                      != null ? Menge                      : string.Empty ).ToString().PadRight(Positions.Menge.L),
                (Mengeneinheit              != null ? Mengeneinheit              : string.Empty ).ToString().PadRight(Positions.Mengeneinheit.L),
                (Preisart                   != null ? Preisart                   : string.Empty ).ToString().PadRight(Positions.Preisart.L),
                (VorzeichenPreis            != null ? VorzeichenPreis            : string.Empty ).ToString().PadRight(Positions.VorzeichenPreis.L),
                (Preis                      != null ? Preis                      : string.Empty ).ToString().PadRight(Positions.Preis.L),
                (Laufnummer                 != null ? Laufnummer                 : string.Empty ).ToString().PadRight(Positions.Laufnummer.L),
                (KagCode                    != null ? KagCode                    : string.Empty ).ToString().PadRight(Positions.KagCode.L),
                (Elementcode                != null ? Elementcode                : string.Empty ).ToString().PadRight(Positions.Elementcode.L),
                (Positionstext              != null ? Positionstext              : string.Empty ).ToString().PadRight(Positions.Positionstext.L),
                (SpezielleCodierungen       != null ? SpezielleCodierungen       : string.Empty ).ToString().PadRight(Positions.SpezielleCodierungen.L),
            };
            
            return String.Join(string.Empty, arr).TrimEnd();
        }
    }
}
