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

namespace Ato.CD.Inbound.TRTAMI202602
{
    public class CrossFormValidatorPSS : ICrossFormValidator
    {
        private PSS2018 ChildDocument { get; set; }

        public List<ProcessMessageDocument> Response { get; private set; }

        private TRTAMI2026 ParentDocument { get; set; }

        public CrossFormValidatorPSS(TRTAMI2026 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

        Data Elements:

        ^PSS20 = PSS:RP.Payer.{PSSeqNum}:tns:Remuneration.VoluntaryAgreementGross.Amount

        ^PSS21 = PSS:RP.Payer.{PSSeqNum}:tns:Remuneration.LabourHireArrangementPaymentGross.Amount

        ^PSS24 = PSS:RP.Payer.{PSSeqNum}:tns:IncomeTax.PayAsYouGoWithholding.CreditTaxWithheldBusinessVoluntaryAgreement.Amount

        ^PSS25 = PSS:RP.Payer.{PSSeqNum}:tns:IncomeTax.PayAsYouGoWithholding.CreditTaxWithheldBusinessLabourHireOrOtherPayments.Amount

        ^PSS31 = PSS:RP.Payer.{PSSeqNum}:tns:Remuneration.PersonalServicesIncome.AttributedGross.Amount

        ^PSS32 = PSS:RP.Payer.{PSSeqNum}:tns:IncomeTax.PayAsYouGoWithholding.CreditTaxWithheldPersonalServicesIncome.Amount  
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOPSS000035()
        {
            if (ChildDocument.RPPayerPSSeqNumContextCollection != null)
            {
                IEnumerable<PSS2018.RPPayerPSSeqNumContext> rpPayerPSSeqNumContexts = ChildDocument.RPPayerPSSeqNumContextCollection.Where(
                    context => context.PSS20.HasValue || context.PSS21.HasValue || context.PSS24.HasValue || context.PSS25.HasValue || context.PSS31.HasValue || context.PSS32.HasValue );

                IEnumerable<ProcessMessageDocument> processMessages = rpPayerPSSeqNumContexts.Select(context =>
                    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[contextRef=\"{context.Id}\"]",
                        Parameters = new ProcessMessageParameters {
                            new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.PSS.000035" },
                            new ProcessMessageParameter { Name = "PSS20", Value = TRTAMI2026Validator.GetValueOrEmpty(context.PSS20)},
                            new ProcessMessageParameter { Name = "PSS21", Value = TRTAMI2026Validator.GetValueOrEmpty(context.PSS21)},
                            new ProcessMessageParameter { Name = "PSS24", Value = TRTAMI2026Validator.GetValueOrEmpty(context.PSS24)},
                            new ProcessMessageParameter { Name = "PSS25", Value = TRTAMI2026Validator.GetValueOrEmpty(context.PSS25)},
                            new ProcessMessageParameter { Name = "PSS31", Value = TRTAMI2026Validator.GetValueOrEmpty(context.PSS31)},
                            new ProcessMessageParameter { Name = "PSS32", Value = TRTAMI2026Validator.GetValueOrEmpty(context.PSS32)}
                        }
                    }
                );

                Response.AddRange(processMessages);
            }
        }

        #endregion

        #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
     
        Data Elements:

        ^TRTAMI4 = TRTAMI:RP:Identifiers.TaxFileNumber.Identifier

        ^PSS TFN = PSS TFN
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOPSS000036()
        {
            if (ChildDocument.RPPayerPSSeqNumContextCollection != null)
            {
                IEnumerable<PSS2018.RPPayerPSSeqNumContext> rpPayerPSSeqNumContexts = ChildDocument.RPPayerPSSeqNumContextCollection.Where(context => context.IdentifierTFN != ParentDocument.TRTAMI4);

                IEnumerable<ProcessMessageDocument> processMessages = rpPayerPSSeqNumContexts.Select(context =>
                    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[{ context.Id }]/xbrli:entity/xbrli:identifier",
                        Parameters = new ProcessMessageParameters {
                            new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.PSS.000036" },
                            new ProcessMessageParameter { Name = "TRTAMI4", Value = TRTAMI2026Validator.GetValueOrEmpty(ParentDocument.TRTAMI4) },
                            new ProcessMessageParameter { Name = "PSS TFN", Value =  TRTAMI2026Validator.GetValueOrEmpty(context.IdentifierTFN) }
                        }
                    }
                );

                Response.AddRange(processMessages);
            }
        }

        #endregion

        #endregion
    }
}
