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

namespace Ato.CD.Inbound.TRT202502
{
    public class CrossFormValidatorTRTAMIS : ICrossFormValidator
    {
        private TRTAMIS2025 childDocument { get; set; }

        private List<Context> contexts { get; set; }

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

        private TRT2025 parentDocument { get; set; }

        public CrossFormValidatorTRTAMIS(TRT2025 parent, object child)
        {
            childDocument = (TRTAMIS2025)child;
            contexts = childDocument.GetContexts();
            parentDocument = parent;
            response = new List<ProcessMessageDocument>();
        }

        public List<ProcessMessageDocument> ValidateCrossFormRules()
        {
            VRATOGEN402009();
            VRATOGEN402010();
            VRATOGEN438000();
            VRATOGEN438001();
            VRATOTRTAMIS000001();

            return response;
        }

        #region Validation Rules

        #region VR.ATO.GEN.402009

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

        Legacy Rule Format:
        IF (RP:entity.identifier.TFN <> PARENT RETURN:RP:entity.identifier.TFN)
          RETURN VALIDATION MESSAGE
        ENDIF

        Technical Business Rule Format:
        IF (RP:entity.identifier.TFN <> PARENT RETURN:RP:entity.identifier.TFN)
          RETURN VALIDATION MESSAGE
        ENDIF

        Data Elements:
            
        ^TRT5 = TRT:RP:Identifiers.TaxFileNumber.Identifier
            
        ^TRTAMIS TFN = TRTAMIS:RP:Identifiers.TaxFileNumber.Identifier
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOGEN402009()
        {
            bool assertion = childDocument.RPExists && !childDocument.RPIdentifierTFN.Equals(parentDocument.TRT5);

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.GEN.402009",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Your supplied TFN does not match the TFN supplied on the form it was submitted with",
                    LongDescription = @"Your supplied TFN does not match the TFN supplied on the parent form it was submitted with",
                    Location = "/xbrli:xbrl/xbrli:context",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.GEN.402009" },
                        new ProcessMessageParameter { Name = "TRT5", Value = parentDocument.TRT5 },
                        new ProcessMessageParameter { Name = "TRTAMIS TFN", Value = childDocument.RPIdentifierTFN }
                    }
                });
            }
        }

        #endregion // VR.ATO.GEN.402009

        #region VR.ATO.GEN.402010

        /*  VR.ATO.GEN.402010
        Your supplied ABN does not match the ABN supplied on the form it was submitted with

        Legacy Rule Format:
        IF (RP:pyid.xx.xx:Identifiers.AustralianBusinessNumber.Identifier <> NULLORBLANK) AND (PARENT RETURN:RP:pyid.xx.xx:Identifiers.AustralianBusinessNumber.Identifier <> NULLORBLANK) AND (RP:pyid.xx.xx:Identifiers.AustralianBusinessNumber.Identifier <> PARENT RETURN:RP:pyid.xx.xx:Identifiers.AustralianBusinessNumber.Identifier)
        RETURN VALIDATION MESSAGE
        ENDIF

        Technical Business Rule Format:
        (^TRTAMIS5 <> BLANK) AND (^ParentABN <> BLANK) AND (^TRTAMIS5 <> ^ParentABN)

        Data Elements:
            
        RP:^TRTAMIS5 = tns:Identifiers.AustralianBusinessNumber.Identifier
            
        RP:^ParentABN = ParentABN
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOGEN402010()
        {
            bool assertion = !string.IsNullOrWhiteSpace(childDocument.TRTAMIS5) && !string.IsNullOrWhiteSpace(parentDocument.TRT7) && !childDocument.TRTAMIS5.Equals(parentDocument.TRT7);

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.GEN.402010",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Your supplied ABN does not match the ABN supplied on the form it was submitted with",
                    LongDescription = @"Your supplied ABN does not match the ABN supplied on the parent form it was submitted with",
                    Location = "/xbrli:xbrl/tns:Identifiers.AustralianBusinessNumber.Identifier",
                    Parameters = new ProcessMessageParameters
                    {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.GEN.402010" },
                        new ProcessMessageParameter { Name = "TRT7", Value = parentDocument.TRT7 },
                        new ProcessMessageParameter { Name = "TRTAMIS5", Value = childDocument.TRTAMIS5 }
                    }
                });
            }
        }

        #endregion // VR.ATO.GEN.402010

        #region VR.ATO.GEN.438000

        /*  VR.ATO.GEN.438000
        Period start date within context on schedule doesn't match start date within PARENT RETURN:reporting party context

        Legacy Rule Format:
        IF (period.startDate WHERE CONTEXT(ALL)) <> PARENT RETURN:RP:period.startDate
            RETURN VALIDATION MESSAGE
        ENDIF

        Technical Business Rule Format:
        ^StartDate <> ^ParentStartDate

        Data Elements:
            
        ^ParentStartDate = ParentStartDate
            
        ^StartDate = StartDate
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOGEN438000()
        {
            response.AddRange(from context in contexts
                              where context.StartDate.GetValueOrDefault() != parentDocument.TRT573.GetValueOrDefault()
                              select new ProcessMessageDocument
                              {
                                  Code = "CMN.ATO.GEN.438000",
                                  Severity = ProcessMessageSeverity.Error,
                                  Description = @"The context period start date is incorrect.",
                                  LongDescription = @"Period start date within context on the schedule must match period start date within the parent return reporting party context",
                                  Location = $"/xbrli:xbrl/xbrli:context[{context.Index}]/xbrli:period/xbrli:startDate",
                                  Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.GEN.438000" },
                        new ProcessMessageParameter { Name = "ContextStartDate", Value = TRT2025Validator.GetValueOrEmptyDate(context.StartDate) },
                        new ProcessMessageParameter { Name = "TRT573", Value = TRT2025Validator.GetValueOrEmptyDate(parentDocument.TRT573) }
                    }
                              }
            );
        }

        #endregion // VR.ATO.GEN.438000

        #region VR.ATO.GEN.438001

        /*  VR.ATO.GEN.438001
        Period end date within context on schedule doesn't match end date within PARENT RETURN:reporting party context

        Legacy Rule Format:
        IF (period.endDate WHERE CONTEXT(ALL)) <> PARENT RETURN:RP:period.endDate
        RETURN VALIDATION MESSAGE
        ENDIF

        Technical Business Rule Format:
        ^EndDate <> ^ParentEndDate

        Data Elements:
            
        ^ParentEndDate = ParentEndDate
            
        ^EndDate = RP:RP.NetExemptionIncome
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOGEN438001()
        {
            response.AddRange(from context in contexts
                              where context.EndDate.GetValueOrDefault() != parentDocument.TRT574.GetValueOrDefault()
                              select new ProcessMessageDocument
                              {
                                  Code = "CMN.ATO.GEN.438001",
                                  Severity = ProcessMessageSeverity.Error,
                                  Description = @"The context period end date is incorrect.",
                                  LongDescription = @"Period end date within context on the schedule must match period end date within the parent return reporting party context",
                                  Location = $"/xbrli:xbrl/xbrli:context[{context.Index}]/xbrli:period/xbrli:endDate",
                                  Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.GEN.438001" },
                        new ProcessMessageParameter { Name = "ContextEndDate", Value = TRT2025Validator.GetValueOrEmptyDate(context.EndDate) },
                        new ProcessMessageParameter { Name = "TRT574", Value = TRT2025Validator.GetValueOrEmptyDate(parentDocument.TRT574) }
                    }
                              }
            );
        }

        #endregion // VR.ATO.GEN.438001 

        #region VR.ATO.TRTAMIS.000001

        /*  VR.ATO.TRTAMIS.000001
        Invalid context. Target Financial Year must match the target year of the parent form.

        Legacy Rule Format:
        IF [TRTAMIS4] <> NULL AND [TRTAMIS4] <> PARENT RETURN:pyin.xx.xx:Report.TargetFinancial.Year
            RETURN VALIDATION MESSAGE
        ENDIF
                    
        [TRTAMIS4] = TRTAMIS:RP:pyin.02.37:Report.TargetFinancial.Year

        Technical Business Rule Format:
        ^TRTAMIS4 <> NULL AND ^TRTAMIS4 <> ^ParentTargetFinancialYear

        Data Elements:
            
        RP:^TRTAMIS4 = tns:Report.TargetFinancial.Year
            
        RP:^ParentTargetFinancialYear = ParentTargetFinancialYear
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOTRTAMIS000001()
        {
            bool assertion = childDocument.TRTAMIS4 != null && !childDocument.TRTAMIS4.GetValueOrDefault().Equals(parentDocument.TRT1.GetValueOrDefault());

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.TRTAMIS.000001",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"The Target Financial Year must match the Year shown on the parent form",
                    LongDescription = @"The date present in the Target Financial Year must match the date that is shown in the same field in the parent form",
                    Location = "/xbrli:xbrl/tns:Report.TargetFinancial.Year",
                    Parameters = new ProcessMessageParameters
                    {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMIS.000001" },
                        new ProcessMessageParameter { Name = "TRT1", Value = parentDocument.TRT1.GetValueOrDefault().ToString() },
                        new ProcessMessageParameter { Name = "TRTAMIS4", Value = childDocument.TRTAMIS4.GetValueOrDefault().ToString() }
                    }
                });
            }
        }

        #endregion // VR.ATO.TRTAMIS.000001

        #endregion Validation Rules
    }
}