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

namespace Ato.CD.Inbound.CTR202602
{
    internal class CrossFormValidatorPSS : ICrossFormValidator
    {
        private CTR2026 ParentDocument { get; }
        private PSS2018 ChildDocument { get; }
        public List<ProcessMessageDocument> Response { get; private set; }

        internal CrossFormValidatorPSS(CTR2026 report, BusinessDocument childDocument)
        {
            ParentDocument = report;
            ChildDocument = (PSS2018)childDocument.ConsumedReport;
            Response = new List<ProcessMessageDocument>();
        }

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

            return Response;
        }

        #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> contexts = ChildDocument.RPPayerPSSeqNumContextCollection.Where(
                     p => p.PSS20.HasValue || p.PSS21.HasValue || p.PSS24.HasValue || p.PSS25.HasValue || p.PSS31.HasValue || p.PSS32.HasValue);

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

                Response.AddRange(processMessages);
            }
        }

        #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

        Technical Business 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:

        ^CTR TFN = CTR:RP:entity.identifier.TFN
        ^PSS TFN = PSS:RP:entity.identifier.TFN
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOPSS000036()
        {
            if (ChildDocument.RPPayerPSSeqNumContextCollection != null)
                Response.AddRange(ChildDocument.RPPayerPSSeqNumContextCollection.Select((s, i) => new { RPPayer = s, Index = i })
                .Where(c => c.RPPayer.Identifier != ParentDocument.RPIdentifierTFN).Select(c =>
                 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 = c.Index == 0 ? "xbrli:xbrl/xbrli:context/xbrli:entity/xbrli:identifier" : $"xbrli:xbrl/xbrli:context[{c.Index + 1}]/xbrli:entity/xbrli:identifier",
                     Parameters = new ProcessMessageParameters 
                     { 
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.PSS.000036" },
                        new ProcessMessageParameter { Name = "PSS TFN", Value = c.RPPayer.Identifier},
                        new ProcessMessageParameter { Name = "CTR TFN", Value = ParentDocument.RPIdentifierTFN}
                     }
                 }
              ));
        }

        #endregion // VR.ATO.PSS.000036
    }
}
