using Ato.CD.Inbound.Shared;
using Ato.EN.IntegrationServices.CodeGenerationPSS;
using Ato.EN.IntegrationServices.CodeGenerationTRT;
using DataContracts;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace Ato.CD.Inbound.TRT
{
    public class CrossFormValidatorPSS : ICrossFormValidator
    {
        private PSS2018 childDocument { get; set; }
        
        public List<ProcessMessageDocument> response { get; private set; }

        private TRT2026 parentDocument { get; set; }

        public CrossFormValidatorPSS(TRT2026 parent, object child)
        {
            childDocument = (PSS2018)child;
            parentDocument = parent;
            response = new List<ProcessMessageDocument>();
        }

        public List<ProcessMessageDocument> ValidateCrossFormRules()
        {
            VRATOPSS000035();
            VRATOPSS000036();

            return response;
        }

        #region Validation Rules

        #region VR.ATO.PSS.000035 

        /*  VR.ATO.PSS.000035
        Payment Type not applicable to Non-individual income tax return

        Legacy Rule Format:
        IF PARENT RETURN <> “IITR”
        AND ([PSS20] <> NULLORBLANK OR [PSS21] <> NULLORBLANK OR [PSS31] <> NULLORBLANK OR [PSS24] <> NULLORBLANK OR [PSS25] <> NULLORBLANK OR [PSS32] <> NULLORBLANK)
        RETURN VALIDATION MESSAGE
        ENDIF
            
        [PSS20] = PSS:RP.Payer.{PSSeqNum}:lrla.02.00:Remuneration.VoluntaryAgreementGross.Amount
        [PSS21] = PSS:RP.Payer.{PSSeqNum}:lrla.02.00:Remuneration.LabourHireArrangementPaymentGross.Amount
        [PSS24] = PSS:RP.Payer.{PSSeqNum}:rvctc2.02.14:IncomeTax.PayAsYouGoWithholding.CreditTaxWithheldBusinessVoluntaryAgreement.Amount
        [PSS25] = PSS:RP.Payer.{PSSeqNum}:rvctc2.02.14:IncomeTax.PayAsYouGoWithholding.CreditTaxWithheldBusinessLabourHireOrOtherPayments.Amount
        [PSS31] = PSS:RP.Payer.{PSSeqNum}:lrla.02.17:Remuneration.PersonalServicesIncome.AttributedGross.Amount
        [PSS32] = PSS:RP.Payer.{PSSeqNum}:rvctc2.02.14:IncomeTax.PayAsYouGoWithholding.CreditTaxWithheldPersonalServicesIncome.Amount

        Technical Business Rule Format:
        PARENT <> 'IITR' AND (^PSS20 <> BLANK OR ^PSS21 <> BLANK OR ^PSS31 <> BLANK OR ^PSS24 <> BLANK OR ^PSS25 <> BLANK OR ^PSS32 <> BLANK)

        Data Elements:

        RP.Payer.{PSSeqNum}:^PSS20 = lrla.02.00:Remuneration.VoluntaryAgreementGross.Amount

        RP.Payer.{PSSeqNum}:^PSS21 = lrla.02.00:Remuneration.LabourHireArrangementPaymentGross.Amount

        RP.Payer.{PSSeqNum}:^PSS24 = rvctc2.02.14:IncomeTax.PayAsYouGoWithholding.CreditTaxWithheldBusinessVoluntaryAgreement.Amount

        RP.Payer.{PSSeqNum}:^PSS25 = rvctc2.02.14:IncomeTax.PayAsYouGoWithholding.CreditTaxWithheldBusinessLabourHireOrOtherPayments.Amount

        RP.Payer.{PSSeqNum}:^PSS31 = lrla.02.17:Remuneration.PersonalServicesIncome.AttributedGross.Amount

        RP.Payer.{PSSeqNum}:^PSS32 = rvctc2.02.14:IncomeTax.PayAsYouGoWithholding.CreditTaxWithheldPersonalServicesIncome.Amount
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOPSS000035()
        {
            bool assertion = childDocument.RPPayerPSSeqNumContextCollection != null && childDocument.RPPayerPSSeqNumContextCollection.Exists(c => c.PSS20.HasValue || c.PSS21.HasValue || c.PSS31.HasValue || c.PSS24.HasValue || c.PSS25.HasValue || c.PSS32.HasValue);

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.PSS.000035",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Payment Type not applicable to Non-individual income tax return",
                    Location = "/xbrli:xbrl/tns:Remuneration.PaymentToForeignResidentGross.Amount",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.PSS.000035" },
                        new ProcessMessageParameter { Name = "PSS20", Value = childDocument.RPPayerPSSeqNumContextCollection.Find(c => c.PSS20.HasValue)?.PSS20.GetValueOrDefault().ToString() },
                        new ProcessMessageParameter { Name = "PSS21", Value = childDocument.RPPayerPSSeqNumContextCollection.Find(c => c.PSS21.HasValue)?.PSS21.GetValueOrDefault().ToString() },
                        new ProcessMessageParameter { Name = "PSS24", Value = childDocument.RPPayerPSSeqNumContextCollection.Find(c => c.PSS24.HasValue)?.PSS24.GetValueOrDefault().ToString() },
                        new ProcessMessageParameter { Name = "PSS25", Value = childDocument.RPPayerPSSeqNumContextCollection.Find(c => c.PSS25.HasValue)?.PSS25.GetValueOrDefault().ToString() },
                        new ProcessMessageParameter { Name = "PSS31", Value = childDocument.RPPayerPSSeqNumContextCollection.Find(c => c.PSS31.HasValue)?.PSS31.GetValueOrDefault().ToString() },
                        new ProcessMessageParameter { Name = "PSS32", Value = childDocument.RPPayerPSSeqNumContextCollection.Find(c => c.PSS32.HasValue)?.PSS32.GetValueOrDefault().ToString() }
                    }
                });
            }
        }

        #endregion // VR.ATO.PSS.000035 

        #region VR.ATO.PSS.000036

        /*  VR.ATO.PSS.000036
        Your supplied TFN does not match the TFN supplied on the form it was submitted with

        Legacy Rule Format:
        WHERE IN CONTEXT (RP.Payer.{PSSeqNum})
        IF (RP.Payer.{PSSeqNum}.entity.identifier.TFN <> PARENT RETURN:RP.entity.identifier.TFN)
            RETURN VALIDATION MESSAGE
        ENDIF

        Technical Business Rule Format:
        (^TFN <> PARENT:RP.^TFN2)

        Data Elements:
            
        ^TFN = RP.Payer.{PSSeqNum}
            
        ^TFN2 = TFN2
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOPSS000036()
        {
            bool assertion = childDocument.RPPayerPSSeqNumContextCollection != null && childDocument.RPPayerPSSeqNumContextCollection.Exists(c => c.IdentifierTFN != parentDocument.TRT5);

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.PSS.000036",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Your supplied TFN does not match the TFN supplied on the form it was submitted with",
                    Location = "/xbrli:xbrl/xbrli:context/xbrli:entity/xbrli:identifier",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.PSS.000036" },
                        new ProcessMessageParameter { Name = "PSS20", Value = childDocument.RPPayerPSSeqNumContextCollection.Find(c => !string.IsNullOrEmpty(c.IdentifierTFN)).IdentifierTFN },
                        new ProcessMessageParameter { Name = "TRT5", Value = parentDocument.TRT5 },
                    }
                });
            }
        }

        #endregion // VR.ATO.PSS.000036

        #endregion Validation Rules
    }
}