using Ato.EN.IntegrationServices.CodeGenerationCGTS;
using Ato.EN.IntegrationServices.CodeGenerationIDS;
using Ato.EN.IntegrationServices.CodeGenerationPSS;
using Ato.EN.IntegrationServices.CodeGenerationRS;
using Ato.EN.IntegrationServices.CodeGenerationTRTAMI;
using Ato.EN.IntegrationServices.CodeGenerationTRTAMIS;
using VaTS;
using DataContracts;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Ato.CD.Inbound.Shared;

namespace Ato.CD.Inbound.TRTAMI202502
{
    public class CrossFormValidator
    {
        private IEnumerable<CGTS2018> cgtsChildDocuments { get; set; }

        private IEnumerable<IDS2025> idsChildDocuments { get; set; }

        private IEnumerable<PSS2018> pssChildDocuments { get; set; }

        private IEnumerable<RS2018> rsChildDocuments { get; set; }

        private IEnumerable<TRTAMIS2025> trtamisChildDocuments { get; set; }

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

        private TRTAMI2025 parentDocument { get; set; }

        public CrossFormValidator(TRTAMI2025 parent, BusinessDocumentCollection childDocuments)
        {
            response = new List<ProcessMessageDocument>();

            parentDocument = parent;

            BusinessDocumentCollection ChildDocuments = childDocuments ?? new BusinessDocumentCollection();

            cgtsChildDocuments = ChildDocuments
                    .Where(s => s.DocumentName.Equals(Schedule.CGTS.ToString()))
                    .Select(p => (CGTS2018)p.ConsumedReport);

            idsChildDocuments = ChildDocuments
                    .Where(s => s.DocumentName.Equals(Schedule.IDS.ToString()))
                    .Select(p => (IDS2025)p.ConsumedReport);

            pssChildDocuments = ChildDocuments
                    .Where(s => s.DocumentName.Equals(Schedule.PSS.ToString()))
                    .Select(p => (PSS2018)p.ConsumedReport);

            rsChildDocuments = ChildDocuments
                    .Where(s => s.DocumentName.Equals(Schedule.RS.ToString()))
                    .Select(p => (RS2018)p.ConsumedReport);

            trtamisChildDocuments = ChildDocuments
                    .Where(s => s.DocumentName.Equals(Schedule.TRTAMIS.ToString()))
                    .Select(p => (TRTAMIS2025)p.ConsumedReport);
        }

        public List<ProcessMessageDocument> ValidateCrossFormRules()
        {
            VRATOTRTAMI000151();
            VRATOTRTAMI000152();
            VRATOTRTAMI000153();
            VRATOTRTAMI000154();
            VRATOTRTAMI000174();
            VRATOTRTAMI000199();
            VRATOTRTAMI000201();
            VRATOTRTAMI000203();
            VRATOTRTAMI000205();
            VRATOTRTAMI000234();
            VRATOTRTAMI000235();
            VRATOTRTAMI000236();
            VRATOTRTAMI000237();
            VRATOTRTAMI000240();
            VRATOTRTAMI000243();
            VRATOTRTAMI000244();
            VRATOTRTAMI000245();
            VRATOTRTAMI000246();
            VRATOTRTAMI000314();
            VRATOTRTAMI000315();
            VRATOTRTAMI000330();
            VRATOTRTAMI000401();
            VRATOTRTAMI000420();

            return response;
        }

        #region Validation Rules

        #region VR.ATO.TRTAMI.000151

        /*  VR.ATO.TRTAMI.000151
        Ensure an 'International dealings schedule' (IDS) is completed when an Interest expenses overseas amount greater than zero is provided

        Legacy Rule Format:
            (^TRTAMI49 > 0) AND (CountDocument('IDS') = 0)

        Technical Business Rule Format:
            (^TRTAMI49 > 0) AND (CountDocument('IDS') = 0)
        */
        public void VRATOTRTAMI000151()
        {
            bool assertion = parentDocument.TRTAMI49 > 0 && !idsChildDocuments.Any();

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000151",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"International Dealings Schedule must be attached",
                    LongDescription = @"An International Dealings Schedule (IDS) must be attached when an Interest Expenses Overseas amount above zero is provided",
                    Location = "/tns:TRTAMI/tns:RP/tns:TrustDetails/tns:ExpenseInterestA",
                    Parameters = new ProcessMessageParameters() { 
                        new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000151" },
                        new ProcessMessageParameter() { Name = "TRTAMI49", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI49) }
                    },
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000152

        /*  VR.ATO.TRTAMI.000152
        When a Royalties deduction amount is present on the International Dealings Schedule (IDS), an amount above zero must be provided for Royalty Expenses Overseas

        Legacy Rule Format:
            (InSet(^TRTAMI50, 'NULL','0')) AND (CountDocument('IDS') = 1) AND (^IDS22 > 0)

        Technical Business Rule Format:
            (InSet(^TRTAMI50, 'NULL','0')) AND (CountDocument('IDS') = 1) AND (^IDS22 > 0)
        */
        public void VRATOTRTAMI000152()
        {
            bool assertion = (parentDocument.TRTAMI50 == 0 || parentDocument.TRTAMI50 == null) &&
                idsChildDocuments.Count() == 1 &&
                idsChildDocuments.All(i => i.IDS22 > 0);

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000152",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Royalty expenses overseas required",
                    LongDescription = @"When a Royalties deduction amount above zero is present on the International Dealings Schedule (IDS), a Royalty Expenses Overseas amount above zero must also be provided",
                    Location = "/tns:TRTAMI/tns:RP/tns:TrustDetails/tns:ExpenseRoyaltiesA",
                    Parameters = new ProcessMessageParameters() {
                        new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000152" },
                        new ProcessMessageParameter() { Name = "TRTAMI50", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI50) },
                        new ProcessMessageParameter() { Name = "IDS22", Value = TRTAMI2025Validator.GetValueOrEmpty(idsChildDocuments.FirstOrDefault()?.IDS22) },
                    },
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000153

        /*  VR.ATO.TRTAMI.000153
        When a Royalties deduction amount is present on the International Dealings Schedule (IDS), it must not exceed the Royalty Expenses Overseas amount

        Legacy Rule Format:
            (^TRTAMI50 > 0) AND (CountDocument('IDS') = 1) AND (^TRTAMI50 < ^IDS22)

        Technical Business Rule Format:
            (^TRTAMI50 > 0) AND (CountDocument('IDS') = 1) AND (^TRTAMI50 < ^IDS22)
        */
        public void VRATOTRTAMI000153()
        {
            IEnumerable<decimal?> ids22 = idsChildDocuments.Where(c => c.IDS22 != null).Select(c => c.IDS22);

            bool assertion = parentDocument.TRTAMI50 > 0 &&
                idsChildDocuments.Count() == 1 &&
                parentDocument.TRTAMI50 < ids22.FirstOrDefault();

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000153",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Royalties deductions incorrect",
                    LongDescription = @"When a Royalties deduction amount is present on the International Dealings Schedule (IDS), it must not exceed the Royalty Expenses Overseas amount",
                    Location = "/tns:TRTAMI/tns:RP/tns:TrustDetails/tns:ExpenseRoyaltiesA",
                    Parameters = new ProcessMessageParameters() {
                        new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000153" },
                        new ProcessMessageParameter() { Name = "TRTAMI50", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI50) },
                        new ProcessMessageParameter() { Name = "IDS22", Value = TRTAMI2025Validator.GetValueOrEmpty(ids22.FirstOrDefault()) }
                    },
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000154

        /*  VR.ATO.TRTAMI.000154
        Ensure an 'International dealings schedule' (IDS) is completed when a Royalty expenses overseas amount greater than zero is provided

        Legacy Rule Format:
            (^TRTAMI50 > 0) AND (CountDocument('IDS') = 0)

        Technical Business Rule Format:
            (^TRTAMI50 > 0) AND (CountDocument('IDS') = 0)
        */
        public void VRATOTRTAMI000154()
        {
            bool assertion = parentDocument.TRTAMI50 > 0 && !idsChildDocuments.Any();

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000154",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"International Dealings Schedule must be attached",
                    LongDescription = @"An International Dealings Schedule (IDS) must be attached when a Royalty Expenses Overseas amount above zero is provided",
                    Location = "/tns:TRTAMI/tns:RP/tns:TrustDetails/tns:ExpenseRoyaltiesA",
                    Parameters = new ProcessMessageParameters() {
                        new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000154" },
                        new ProcessMessageParameter() { Name = "TRTAMI50", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI50) }
                    },
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000174

        /*  VR.ATO.TRTAMI.000174
        An AMIT schedule must be submitted with an AMIT return form. Some AMITs will need to submit multiple AMIT schedules with their AMIT return form.

        Legacy Rule Format:
            CountDocument('TRTAMIS') = 0

        Technical Business Rule Format:
            CountDocument('TRTAMIS') = 0
        */
        public void VRATOTRTAMI000174()
        {
            bool assertion = !trtamisChildDocuments.Any();

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.TRTAMI.000174",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"At least one Trust Attribution Managed Investments Schedule must be present",
                    Location = "/tns:TRTAMI/tns:RP",
                    Parameters = new ProcessMessageParameters { new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000174" } }
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000199

        /*  VR.ATO.TRTAMI.000199
        When the value of dealings with international related parties was not above $2 million, thin capitalisation or debt deduction creation rules did not affect you, and no amounts have been provided at Interest expenses overseas and Royalty expenses overseas, an International Dealings schedule must not be attached.

        Legacy Rule Format:
            (^TRTAMI47 = FALSE AND ^TRTAMI48 = FALSE) AND (InSet(^TRTAMI49, "NULL","0') AND InSet(^TRTAMI50,"NULL","0')) AND (CountDocument('IDS') = 1)
 
        Technical Business Rule Format:
            (^TRTAMI47 = FALSE AND ^TRTAMI48 = FALSE) AND (InSet(^TRTAMI49, "NULL","0') AND InSet(^TRTAMI50,"NULL","0')) AND (CountDocument('IDS') = 1)
        */
        public void VRATOTRTAMI000199()
        {
            bool assertion = parentDocument.TRTAMI47 == false && parentDocument.TRTAMI48 == false
                    && (parentDocument.TRTAMI49 == null || parentDocument.TRTAMI49 == 0)
                    && (parentDocument.TRTAMI50 == null || parentDocument.TRTAMI50 == 0)
                    && idsChildDocuments.Count() == 1;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.010199",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"International Dealings Schedule is not required",
                    LongDescription = @"When the value of dealings with international related parties was not above $2 million, thin capitalisation or debt deduction creation rules did not affect you, and no amounts have been provided at Interest expenses overseas and Royalty expenses overseas, an International Dealings schedule must not be attached",
                    Location = "/tns:TRTAMI/tns:RP/tns:TrustDetails/tns:InternationalDealingsRelatedPartiesTransactionsExcessAggregateValueI",
                    Parameters = new ProcessMessageParameters() {
                        new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000199" },
                        new ProcessMessageParameter() { Name = "TRTAMI47", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI47) },
                        new ProcessMessageParameter() { Name = "TRTAMI48", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI48) },
                        new ProcessMessageParameter() { Name = "TRTAMI49", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI49) },
                        new ProcessMessageParameter() { Name = "TRTAMI50", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI50) },
                    },
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000201

        /*  VR.ATO.TRTAMI.000201
        The number of International Dealings Schedules must not exceed 1

        Legacy Rule Format:
            CountDocument('IDS') > 1

        Technical Business Rule Format:
            CountDocument('IDS') > 1
        */
        public void VRATOTRTAMI000201()
        {
            bool assertion = idsChildDocuments.Count() > 1;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000201",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"The number of International Dealings Schedules must not exceed 1",
                    Location = "/tns:TRTAMI/tns:RP",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000201" } },
                });
            }
        }

        #endregion

        #region  VR.ATO.TRTAMI.000203

        /*  VR.ATO.TRTAMI.000203
        The number of PAYG Payment Summary Schedules must not exceed 1

        Legacy Rule Format:
            CountDocument('PSS') > 1

        Technical Business Rule Format:
            CountDocument('PSS') > 1
        */
        public void VRATOTRTAMI000203()
        {
            bool assertion = pssChildDocuments.Count() > 1;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.TRTAMI.000203",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"The number of PAYG Payment Summary Schedules must not exceed 1",
                    Location = "/tns:TRTAMI/tns:RP",
                    Parameters = new ProcessMessageParameters { new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000203" } }
                });
            }
        }
        #endregion

        #region VR.ATO.TRTAMI.000205

        /*  VR.ATO.TRTAMI.000205
        When the response to 'Did you have dealings with international related parties located in specified countries?' on the International Dealings Schedule (IDS) is 'True' (yes), the response at either 'Funds or property, whether directly or indirectly, have been sent to, or received from, any of the specified countries', or 'Trustee has the ability or expectation to control, whether directly or indirectly, the disposition of any funds, property, assets or investments located in, or located elsewhere but controlled or managed from any of the specified countries', must also be 'True' (yes)

        Legacy Rule Format:
            ^TRTAMI137 = FALSE AND ^TRTAMI138 = FALSE AND CountDocument('IDS') = 1 AND ^IDS9 = TRUE

        Technical Business Rule Format:
            ^TRTAMI137 = FALSE AND ^TRTAMI138 = FALSE AND CountDocument('IDS') = 1 AND ^IDS9 = TRUE
        */
        public void VRATOTRTAMI000205()
        {
            IEnumerable<bool?> ids9 = idsChildDocuments.Where(c => (c.IDS9) != null).Select(c => c.IDS9);

            bool assertion = parentDocument.TRTAMI137 == false && parentDocument.TRTAMI138 == false
                && idsChildDocuments.Count() == 1
                && ids9.FirstOrDefault() == true;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000205",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Transactions with specified countries question incorrect",
                    LongDescription = @"When the response to 'Did you have dealings with international related parties located in specified countries?' on the International Dealings Schedule (IDS) is 'True' (yes), the response at either 'Funds or property, whether directly or indirectly, have been sent to, or received from, any of the specified countries', or 'Trustee has the ability or expectation to control, whether directly or indirectly, the disposition of any funds, property, assets or investments located in, or located elsewhere but controlled or managed from any of the specified countries', must also be 'True' (yes)",
                    Location = "/tns:TRTAMI/tns:RP/tns:TrustDetails/tns:InternationalDealingsTransactionsWithTaxHavenCountriesI",
                    Parameters = new ProcessMessageParameters() {
                        new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000205" },
                        new ProcessMessageParameter() { Name = "TRTAMI137", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI137) },
                        new ProcessMessageParameter() { Name = "TRTAMI138", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI138) },
                        new ProcessMessageParameter() { Name = "IDS9", Value = TRTAMI2025Validator.GetValueOrEmpty(ids9.FirstOrDefault()) }
                    },
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000234

        /*  VR.ATO.TRTAMI.000234
        When multiple Trust Attribution Managed Investments Schedules (TRTAMIS) are provided, a unique Name of AMIT Class must be provided for each.

        Legacy Rule Format:
            (CountDocument('TRTAMIS') > 1 AND ^TRTAMIS313 <> NULL AND HasDuplicateValues(^TRTAMIS313))

        Technical Business Rule Format:
            (CountDocument('TRTAMIS') > 1 AND ^TRTAMIS313 <> NULL AND HasDuplicateValues(^TRTAMIS313))
        */
        public void VRATOTRTAMI000234()
        {
            IEnumerable<TRTAMIS2025> duplicates = trtamisChildDocuments.Where(s => !string.IsNullOrEmpty(s.TRTAMIS313))
                .GroupBy(s => s.TRTAMIS313).Where(s => s.Skip(1).Any()).SelectMany(c => c);

            response.AddRange(from duplicate in duplicates
                              select new ProcessMessageDocument
                              {
                                  Code = "CMN.ATO.TRTAMI.000234",
                                  Severity = ProcessMessageSeverity.Error,
                                  Description = @"Name of AMIT Class for TRTAMIS schedule is invalid",
                                  LongDescription = @"When multiple Trust Attribution Managed Investments Schedules (TRTAMIS) are provided, a unique Name of AMIT Class must be provided for each",
                                  Location = "/tns:TRTAMI/tns:RP",
                                  Parameters = new ProcessMessageParameters {
                                      new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000234" },
                                      new ProcessMessageParameter { Name = "TRTAMIS313", Value = TRTAMI2025Validator.GetValueOrEmpty(duplicate.TRTAMIS313) }
                                  }
                              });
        }

        #endregion

        #region VR.ATO.TRTAMI.000235

        /*  VR.ATO.TRTAMI.000235
        When multiple Capital Gains Tax (CGT) schedules are provided, a unique Name of AMIT Class must be provided for each.

        Legacy Rule Format:
            (CountDocument('CGTS') > 1 AND HasDuplicateValues(^CGTS153))

        Technical Business Rule Format:
            (CountDocument('CGTS') > 1 AND HasDuplicateValues(^CGTS153))
        */
        public void VRATOTRTAMI000235()
        {
            IEnumerable<CGTS2018> duplicates = cgtsChildDocuments.GroupBy(s => s.CGTS153).Where(s => s.Skip(1).Any()).SelectMany(c => c);

            response.AddRange(from duplicate in duplicates
                              select new ProcessMessageDocument
                              {
                                  Code = "CMN.ATO.TRTAMI.000235",
                                  Severity = ProcessMessageSeverity.Error,
                                  Description = @"Name of AMIT Class for CGT schedule is invalid",
                                  LongDescription = @"When multiple Capital Gains Tax (CGT) schedules are provided, a unique Name of AMIT Class must be provided for each",
                                  Location = "/tns:TRTAMI/tns:RP",
                                  Parameters = new ProcessMessageParameters {
                                      new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000235" },
                                      new ProcessMessageParameter { Name = "CGTS153", Value = TRTAMI2025Validator.GetValueOrEmpty(duplicate.CGTS153) }
                                  }
                              });
        }

        #endregion // VR.ATO.TRTAMI.000235

        #region VR.ATO.TRTAMI.000236

        /*  VR.ATO.TRTAMI.000236
        When multiple Trust Attribution Managed Investments Schedules (TRTAMIS) are provided, the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' must be 'True' (yes).

        Legacy Rule Format:
            ^TRTAMI102 = FALSE AND CountDocument('TRTAMIS') > 1

        Technical Business Rule Format:
            ^TRTAMI102 = FALSE AND CountDocument('TRTAMIS') > 1

        Data Elements:
    
            ^TRTAMI102 = TRTAMI:RP:MultiClassTreatment:IncomeTax.MultiClassTreatment.Indicator
        */
        public void VRATOTRTAMI000236()
        {
            bool assertion = !parentDocument.TRTAMI102.GetValueOrDefault() && trtamisChildDocuments.Count() > 1;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.TRTAMI.000236",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"'Have you chosen to treat separate classes in the trust as a separate AMIT?' response is incorrect",
                    LongDescription = @"When multiple Trust Attribution Managed Investments Schedules (TRTAMIS) are provided, the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' must be 'True' (yes)",
                    Location = "/tns:TRTAMI/tns:RP/tns:MultiClassTreatment/tns:IncomeTaxI",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000236" },
                        new ProcessMessageParameter { Name = "TRTAMI102", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI102) }
                    }
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000237

        /*  VR.ATO.TRTAMI.000237
        When the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' is 'True' (yes), the Name of AMIT Class must be provided for each Trust Attribution Managed Investments Schedule (TRTAMIS).

        Legacy Rule Format:
            ^TRTAMI102 = TRUE AND AnyOccurrence(^TRTAMIS313, ^TRTAMIS313 = NULL)

        Technical Business Rule Format:
            ^TRTAMI102 = TRUE AND AnyOccurrence(^TRTAMIS313, ^TRTAMIS313 = NULL)

        Data Elements:
    
            ^TRTAMI102 = TRTAMI:RP:MultiClassTreatment:IncomeTax.MultiClassTreatment.Indicator
    
            ^TRTAMIS313 = TRTAMIS313
         */
        public void VRATOTRTAMI000237()
        {
            bool anyTRTAMIS313NotProvided = trtamisChildDocuments != null && trtamisChildDocuments.Count() > 0 ? trtamisChildDocuments.Any(trtamis => string.IsNullOrWhiteSpace(trtamis.TRTAMIS313)) : true;

            bool assertion = parentDocument.TRTAMI102.GetValueOrDefault() && anyTRTAMIS313NotProvided;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.TRTAMI.000237",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Name of AMIT Class must be provided for each TRTAMIS schedule",
                    LongDescription = @"When the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' is 'True' (yes), the Name of AMIT Class must be provided for each Trust Attribution Managed Investments Schedule (TRTAMIS)",
                    Location = "/tns:TRTAMI/tns:RP/tns:MultiClassTreatment/tns:IncomeTaxI",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000237" },
                        new ProcessMessageParameter { Name = "TRTAMI102", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI102) },
                        new ProcessMessageParameter { Name = "TRTAMIS313 is empty", Value = TRTAMI2025Validator.GetValueOrEmpty(anyTRTAMIS313NotProvided) }
                    }
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000240

        /*  VR.ATO.TRTAMI.000240
        Name of AMIT Class provided on each Capital Gains Tax (CGT) schedule, must have a matching Trust Attribution Managed Investments Schedule (TRTAMIS).

        Legacy Rule Format:
            AnyOccurrence(CountDocument('CGTS') > 0, ^CGTS153 <> NULL AND AnyOccurrence(^TRTAMIS313, ^TRTAMIS313 <> ^CGTS153))

        Technical Business Rule Format:
            AnyOccurrence(CountDocument('CGTS') > 0, ^CGTS153 <> NULL AND AnyOccurrence(^TRTAMIS313, ^TRTAMIS313 <> ^CGTS153))
        */
        public void VRATOTRTAMI000240()
        {
            IEnumerable<string> cgts153 = cgtsChildDocuments.Where(c => !string.IsNullOrWhiteSpace(c.CGTS153)).Select(c => c.CGTS153);

            if (cgts153.Any())
            {
                IEnumerable<string> trtamis313 = trtamisChildDocuments.Select(t => t.TRTAMIS313);

                response.AddRange(cgts153.Where(c => !trtamis313.Any(c.Equals)).Select(c => new ProcessMessageDocument
                {
                    Code = "CMN.ATO.TRTAMI.000240",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Name of AMIT Class for CGT schedule is invalid",
                    LongDescription = @"Name of AMIT Class provided on each Capital Gains Tax (CGT) schedule, must have a matching Trust Attribution Managed Investments Schedule (TRTAMIS)",
                    Location = "/tns:TRTAMI/tns:RP",
                    Parameters = new ProcessMessageParameters
                    {
                        new ProcessMessageParameter {Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000240"},
                        new ProcessMessageParameter {Name = "CGTS153", Value = TRTAMI2025Validator.GetValueOrEmpty(c)}
                    }
                }));
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000243

        /*  VR.ATO.TRTAMI.000243
        When the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' is 'True' (yes), the Name of AMIT Class must be provided for each Capital Gains Tax (CGT) schedule.

        Legacy Rule Format:
            ^TRTAMI102 = TRUE AND CountDocument('CGTS') > 0 AND AnyOccurrence(^CGTS153, ^CGTS153 = NULL)

        Technical Business Rule Format:
            ^TRTAMI102 = TRUE AND CountDocument('CGTS') > 0 AND AnyOccurrence(^CGTS153, ^CGTS153 = NULL)

        Data Elements:

           ^TRTAMI102 = TRTAMI:RP:MultiClassTreatment:IncomeTax.MultiClassTreatment.Indicator

            ^CGTS153 = CGTS153
        */
        public void VRATOTRTAMI000243()
        {
            bool anyCGTS153NotProvided = cgtsChildDocuments != null && cgtsChildDocuments.Count() > 0 ? cgtsChildDocuments.Any(cgts => string.IsNullOrWhiteSpace(cgts.CGTS153)) : false;

            bool assertion = parentDocument.TRTAMI102.GetValueOrDefault() && anyCGTS153NotProvided;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {

                    Code = "CMN.ATO.TRTAMI.000243",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Name of AMIT Class must be provided for each CGT schedule",
                    LongDescription = @"When the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' is 'True' (yes), the Name of AMIT Class must be provided for each Capital Gains Tax (CGT) schedule",
                    Location = "/tns:TRTAMI/tns:RP/tns:MultiClassTreatment/tns:IncomeTaxI",
                    Parameters = new ProcessMessageParameters
                    {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000243" },
                        new ProcessMessageParameter { Name = "TRTAMI102", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI102) },
                        new ProcessMessageParameter { Name = "CGTS153 is empty", Value = TRTAMI2025Validator.GetValueOrEmpty(anyCGTS153NotProvided) }
                    }
                });
            }
        }

        #endregion // VR.ATO.TRTAMI.000243

        #region VR.ATO.TRTAMI.000244

        /*  VR.ATO.TRTAMI.000244
        When the Name of AMIT Class has been provided for any Trust Attribution Managed Investments Schedule (TRTAMIS), the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' must be 'True' (yes).

        Legacy Rule Format:
            ^TRTAMI102 = FALSE AND AnyOccurrence(^TRTAMIS313, ^TRTAMIS313 <> NULL)

        Technical Business Rule Format:
            ^TRTAMI102 = FALSE AND AnyOccurrence(^TRTAMIS313, ^TRTAMIS313 <> NULL)

        Data Elements:
    
            ^TRTAMI102 = TRTAMI:RP:MultiClassTreatment:IncomeTax.MultiClassTreatment.Indicator
    
            ^TRTAMIS313 = TRTAMIS313
        */
        public void VRATOTRTAMI000244()
        {
            bool anyTRTAMIS313Provided = trtamisChildDocuments != null && trtamisChildDocuments.Count() > 0 ? trtamisChildDocuments.Any(trtamis => !string.IsNullOrWhiteSpace(trtamis.TRTAMIS313)) : false;

            bool assertion = parentDocument.TRTAMI102.GetValueOrDefault() == false && anyTRTAMIS313Provided;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000244",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"'Have you chosen to treat separate classes in the trust as a separate AMIT?' response is incorrect",
                    LongDescription = @"When the Name of AMIT Class has been provided for any Trust Attribution Managed Investments Schedule (TRTAMIS), the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' must be 'True' (yes)",
                    Location = "/tns:TRTAMI/tns:RP/tns:MultiClassTreatment/tns:IncomeTaxI",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000244" },
                        new ProcessMessageParameter { Name = "TRTAMI102", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI102) },
                        new ProcessMessageParameter { Name = "TRTAMIS313 Provided", Value = TRTAMI2025Validator.GetValueOrEmpty(anyTRTAMIS313Provided) }
                    }
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000245

        /*  VR.ATO.TRTAMI.000245
        When the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' is 'False' (no), the Total capital gains/losses from transfers to other classes amounts for the Capital Gains Tax (CGT) schedule must not be provided.

        Legacy Rule Format:
            ^TRTAMI102 = FALSE AND CountDocument('CGTS') > 0 AND (AnyOccurrence(^CGTS154, NotInSet(^CGTS154, 'NULL','0')) OR AnyOccurrence(^CGTS155, NotInSet(^CGTS155, 'NULL','0')))

        Technical Business Rule Format:
            ^TRTAMI102 = FALSE AND CountDocument('CGTS') > 0 AND (AnyOccurrence(^CGTS154, NotInSet(^CGTS154, 'NULL','0')) OR AnyOccurrence(^CGTS155, NotInSet(^CGTS155, 'NULL','0')))

        Data Elements:
    
            ^TRTAMI102 = TRTAMI:RP:MultiClassTreatment:IncomeTax.MultiClassTreatment.Indicator
    
            ^CGTS154 = CGTS154
    
            ^CGTS155 = CGTS155
        */
        public void VRATOTRTAMI000245()
        {
            bool anyCGTS154Provided = cgtsChildDocuments != null && cgtsChildDocuments.Count() > 0 ? cgtsChildDocuments.Any(cgts => !Regex.IsMatch(cgts.CGTS154.GetValueOrDefault().ToString(), @"^(NULL|0)$", RegexOptions.IgnoreCase)) : false;
            bool anyCGTS155Provided = cgtsChildDocuments != null && cgtsChildDocuments.Count() > 0 ? cgtsChildDocuments.Any(cgts => !Regex.IsMatch(cgts.CGTS155.GetValueOrDefault().ToString(), @"^(NULL|0)$", RegexOptions.IgnoreCase)) : false;

            bool assertion = parentDocument.TRTAMI102.GetValueOrDefault() == false && (anyCGTS154Provided || anyCGTS155Provided);

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000245",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Total capital gains/losses from transfers to other classes amounts must not be provided in CGT schedule",
                    LongDescription = @"When the response to 'Have you chosen to treat separate classes in the trust as a separate AMIT?' is 'False' (no), the Total capital gains/losses from transfers to other classes amounts for the Capital Gains Tax (CGT) schedule must not be provided",
                    Location = "/tns:TRTAMI/tns:RP/tns:MultiClassTreatment/tns:IncomeTaxI",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000245" },
                        new ProcessMessageParameter { Name = "TRTAMI102", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI102) },
                        new ProcessMessageParameter { Name = "CGTS154 Provided", Value = TRTAMI2025Validator.GetValueOrEmpty(anyCGTS154Provided) },
                        new ProcessMessageParameter { Name = "CGTS155 Provided", Value = TRTAMI2025Validator.GetValueOrEmpty(anyCGTS155Provided) }
                    }
                });
            }
        }

        #endregion // VR.ATO.TRTAMI.000245

        #region VR.ATO.TRTAMI.000246

        /*  VR.ATO.TRTAMI.000246
        When the value of dealings with international related parties was above $2 million, the International Dealings Schedule (IDS) must be attached

        Legacy Rule Format:
            ^TRTAMI47 = TRUE AND CountDocument('IDS') = 0

        Technical Business Rule Format:
            ^TRTAMI47 = TRUE AND CountDocument('IDS') = 0
       */
        public void VRATOTRTAMI000246()
        {
            bool assertion = parentDocument.TRTAMI47 == true && !idsChildDocuments.Any();

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000246",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"International Dealings Schedule (IDS) must be attached",
                    LongDescription = @"When the value of dealings with international related parties was above $2 million, the International Dealings Schedule (IDS) must be attached",
                    Location = "/tns:TRTAMI/tns:RP/tns:TrustDetails/tns:InternationalDealingsRelatedPartiesTransactionsExcessAggregateValueI",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000246" },
                        new ProcessMessageParameter { Name = "TRTAMI47", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI47) }
                    }
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000314

        /*  VR.ATO.TRTAMI.000314
        Where Total Liabilities on the main AMIT tax return has a value of zero or greater and there is no occurrence (zero or greater) of the corresponding Total Liabilities labels in at least one (1) AMIT schedule, the system shall disallow lodgements.

        Legacy Rule Format:
            ^TRTAMI60 <> NULL AND CountDocument('TRTAMIS') > 0 AND AllOccurrences(^TRTAMIS334, ^TRTAMIS334 = NULL)

        Technical Business Rule Format:
            ^TRTAMI60 <> NULL AND CountDocument('TRTAMIS') > 0 AND AllOccurrences(^TRTAMIS334, ^TRTAMIS334 = NULL)

        Data Elements:
    
            ^TRTAMI60 = TRTAMI:RP:KeyFinancialInformation:Liabilities.Total.Amount
    
            ^TRTAMIS334 = TRTAMIS334
        */
        public void VRATOTRTAMI000314()
        {
            bool allTRTAMIS334NotProvided = trtamisChildDocuments != null && trtamisChildDocuments.Count() > 0 ? trtamisChildDocuments.All(t => t.TRTAMIS334 == null) : false;

            bool assertion = parentDocument.TRTAMI60 != null && allTRTAMIS334NotProvided;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.TRTAMI.000314",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"At least one occurrence of Total Liabilities should be present if the corresponding label in AMIT tax return has a value",
                    LongDescription = @"Where Total Liabilities on the main AMIT tax return has a value of zero or greater and there is no occurrence (zero or greater) of the corresponding Total Liabilities labels in at least one (1) AMIT schedule, the system shall disallow lodgements.",
                    Location = "/tns:TRTAMI/tns:RP/tns:KeyFinancialInformation/tns:LiabilitiesTotalA",
                    Parameters = new ProcessMessageParameters
                    {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000314" },
                        new ProcessMessageParameter { Name = "TRTAMI60", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI60) },
                        new ProcessMessageParameter { Name = "TRTAMIS334 is empty", Value = TRTAMI2025Validator.GetValueOrEmpty(allTRTAMIS334NotProvided) }
                    }
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000315

        /*  VR.ATO.TRTAMI.000315
        Where Total Assets on the main AMIT tax return has a value of zero or greater and there is no occurrence (zero or greater) of the corresponding Total Assets labels in at least one (1) AMIT schedule, the system shall disallow lodgements.

        Legacy Rule Format:
            ^TRTAMI58 <> NULL AND CountDocument('TRTAMIS') > 0 AND AllOccurrences(^TRTAMIS333, ^TRTAMIS333 = NULL)

        Technical Business Rule Format:
            ^TRTAMI58 <> NULL AND CountDocument('TRTAMIS') > 0 AND AllOccurrences(^TRTAMIS333, ^TRTAMIS333 = NULL)

        Data Elements:
    
            ^TRTAMI58 = TRTAMI:RP:KeyFinancialInformation:Assets.Total.Amount
    
            ^TRTAMIS333 = TRTAMIS333
        */
        public void VRATOTRTAMI000315()
        {
            bool allTRTAMIS333NotProvided = trtamisChildDocuments != null && trtamisChildDocuments.Count() > 0 ? trtamisChildDocuments.All(t => t.TRTAMIS333 == null) : false;

            bool assertion = parentDocument.TRTAMI58 != null && allTRTAMIS333NotProvided;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.TRTAMI.000315",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"At least one occurrence of Total Assets should be present if the corresponding label in AMIT tax return has a value",
                    LongDescription = @"Where Total Assets on the main AMIT tax return has a value of zero or greater and there is no occurrence (zero or greater) of the corresponding Total Assets labels in at least one (1) AMIT schedule, the system shall disallow lodgements.",
                    Location = "/tns:TRTAMI/tns:RP/tns:KeyFinancialInformation/tns:AssetsTotalA",
                    Parameters = new ProcessMessageParameters
                    {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000315" },
                        new ProcessMessageParameter { Name = "TRTAMI58", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI58) },
                        new ProcessMessageParameter { Name = "TRTAMIS333 is empty", Value = TRTAMI2025Validator.GetValueOrEmpty(allTRTAMIS333NotProvided) }
                    }
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000330

        /*  VR.ATO.TRTAMI.000330
        If the trust has self-assessed that they are a Significant Global Entity (SGE), then 'Are you a small business entity, not a significant global entity and your international related party dealings do not exceed $5 million and 50% of your current year aggregated turnover?' must not be 'TRUE' on the International Dealings Schedule (IDS) form.

        Legacy Rule Format:
            ^TRTAMI162 = TRUE AND (CountDocument('IDS') = 1 AND ^IDS425 = TRUE)

        Technical Business Rule Format:
            ^TRTAMI162 = TRUE AND (CountDocument('IDS') = 1 AND ^IDS425 = TRUE)
        */
        public void VRATOTRTAMI000330()
        {
            bool assertion = parentDocument.TRTAMI162.GetValueOrDefault() == true &&
               idsChildDocuments.Count() == 1 &&
               idsChildDocuments.FirstOrDefault().IDS425.GetValueOrDefault() == true;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.TRTAMI.000330",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Small business entity question on the International Dealings Schedule (IDS) form must not be 'TRUE'.",
                    LongDescription = @"If the trust has self-assessed that they are a Significant Global Entity (SGE), then 'Are you a small business entity, not a significant global entity and your international related party dealings do not exceed $5 million and 50% of your current year aggregated turnover?' must not be 'TRUE' on the International Dealings Schedule (IDS) form.",
                    Location = $"/tns:TRTAMI/tns:RP/tns:TrustDetails/tns:OrganisationDetailsSignificantGlobalEntityStatusI",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000330" },
                        new ProcessMessageParameter { Name = "TRTAMI162", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI162) },
                        new ProcessMessageParameter { Name = "IDS425", Value = TRTAMI2025Validator.GetValueOrEmpty(idsChildDocuments.FirstOrDefault().IDS425) },
                    }
                });
            }
        }

        #endregion

        #region VR.ATO.TRTAMI.000401

        /*  VR.ATO.TRTAMI.000401
        When Is this lodgment for an attribution CCIV sub-fund? is true, more than one Trust Attribution Managed Investments Schedules (TRTAMIS) must not be provided

        Legacy Rule Format:
            ^TRTAMI192 = TRUE AND CountDocument('TRTAMIS') > 1

        Technical Business Rule Format:
            ^TRTAMI192 = TRUE AND CountDocument('TRTAMIS') > 1

        Data Elements:
    
            ^TRTAMI192 = TRTAMI:RP:Report.CorporateCollectiveInvestmentVehicleSubFund.Indicator
        */
        public void VRATOTRTAMI000401()
        {
            bool assertion = parentDocument.TRTAMI192.GetValueOrDefault() && trtamisChildDocuments.Count() > 1;

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000401",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"More than one Trust Attribution Managed Investments Schedules (TRTAMIS) must not be provided",
                    LongDescription = @"When Is this lodgment for an attribution CCIV sub-fund? is true, more than one Trust Attribution Managed Investments Schedules (TRTAMIS) must not be provided",
                    Location = "/tns:TRTAMI/tns:RP/tns:CorporateCollectiveInvestmentVehicleSubFundI",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000401" },
                        new ProcessMessageParameter { Name = "TRTAMI192", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI192) }
                    }
                });
            }
        }
        #endregion // VR.ATO.TRTAMI.000401

        #region VR.ATO.TRTAMI.000420

        /*  VR.ATO.TRTAMI.000420
        When you were affected by the Thin capitalisation or debt deduction creation rules, the International Dealings Schedule (IDS) must be attached

        Legacy Rule Format:
            (^TRTAMI48 = TRUE) AND (CountDocument('IDS') = 0)

        Technical Business Rule Format:
            (^TRTAMI48 = TRUE) AND (CountDocument('IDS') = 0)
        */
        public void VRATOTRTAMI000420()
        {
            bool assertion = parentDocument.TRTAMI48 == true && !idsChildDocuments.Any();

            if (assertion)
            {
                response.Add(new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.TRTAMI.000420",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"International Dealings Schedule not attached",
                    LongDescription = @"If the thin capitalisation or debt deduction creation rules apply then International Dealings Schedule must be attached",
                    Location = "/tns:TRTAMI/tns:RP/tns:TrustDetails/tns:LiabilitiesThinCapitalisationProvisionsAppliedI",
                    Parameters = new ProcessMessageParameters()
                    {
                        new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.TRTAMI.000420" },
                        new ProcessMessageParameter() { Name = "TRTAMI48", Value = TRTAMI2025Validator.GetValueOrEmpty(parentDocument.TRTAMI48) }
                    },
                });
            }
        }

        #endregion

        #endregion
    }
}