using Ato.CD.Inbound.Shared;
using Ato.EN.IntegrationServices.CodeGenerationDISTBENTRT;
using Ato.EN.IntegrationServices.CodeGenerationFITR;
using DataContracts;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using VaTS;
using System.Linq;
using static Ato.CD.Inbound.Shared.ValidatorHelpers;

namespace Ato.CD.Inbound.FITR202602
{
    public class CrossFormValidatorDISTBENTRT : ICrossFormValidator
    {
        private FITR2026 ParentDocument { get; }
        private DISTBENTRT2024 ChildDocument { get; }
        public List<ProcessMessageDocument> Response { get; private set; }

        public CrossFormValidatorDISTBENTRT(FITR2026 report, BusinessDocument childDocument)
        {
            ParentDocument = report;
            ChildDocument = (DISTBENTRT2024)childDocument.ConsumedReport;
            Response = new List<ProcessMessageDocument>();
        }

        public List<ProcessMessageDocument> ValidateCrossFormRules()
        {
            //Parent form cross form rules
            VRATOFITR434611();
            VRATOFITR434612();
            VRATOFITR434613();
            VRATOFITR434627();
            VRATOFITRW00002();

            return Response;
        }

        #region VR.ATO.FITR.434611

        /*  VR.ATO.FITR.434611
        Reporting period start date for the Distributions to Beneficiaries of Trust schedule must be the same as the Reporting period start date of the parent form

        Technical Business Rule:
        CountDocument('DISTBENTRT') = 1 AND ^FITR300 <> ^DISTBENTRT1

        Data Elements:
        ^FITR300 = FITR:RP:Period.Start.Date
        ^DISTBENTRT1 = DISTBENTRT:RP:Period.Start.Date
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOFITR434611()
        {
            bool assertion = ParentDocument.FITR300 != ChildDocument.DISTBENTRT1;

            if (assertion)
            {
                ProcessMessageDocument processMessage = new ProcessMessageDocument
                {
                    Code = "CMN.ATO.FITR.434611",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Reporting period start date for the Distributions to Beneficiaries of Trust schedule is invalid",
                    LongDescription = @"Reporting period start date for the Distributions to Beneficiaries of Trust schedule must be the same as the Reporting period start date of the parent form",
                    Location = "/tns:FITR/tns:RP/tns:PeriodStartD",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.FITR.434611" },
                        new ProcessMessageParameter { Name = "FITR300", Value = FITR2026Validator.GetValueOrEmptyDate(ParentDocument.FITR300) },
                        new ProcessMessageParameter { Name = "DISTBENTRT1", Value = FITR2026Validator.GetValueOrEmptyDate(ChildDocument.DISTBENTRT1) }
                    },
                    DocumentSequence = "parent_doc"
                };

                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.FITR.434611

        #region VR.ATO.FITR.434612

        /*  VR.ATO.FITR.434612
        Reporting period end date for the Distributions to Beneficiaries of Trust schedule must be the same as the Reporting period end date of the parent form

        Technical Business Rule:
        CountDocument('DISTBENTRT') = 1 AND ^FITR301 <> ^DISTBENTRT2
        
        Data Elements:
        ^FITR301 = FITR:RP:Period.End.Date
        ^DISTBENTRT2 = DISTBENTRT:RP:Period.End.Date
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOFITR434612()
        {
            bool assertion = ParentDocument.FITR301 != ChildDocument.DISTBENTRT2;

            if (assertion)
            {
                ProcessMessageDocument processMessage = new ProcessMessageDocument
                {
                    Code = "CMN.ATO.FITR.434612",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Reporting period end date for the Distributions to Beneficiaries of Trust schedule is invalid",
                    LongDescription = @"Reporting period end date for the Distributions to Beneficiaries of Trust schedule must be the same as the Reporting period end date of the parent form",
                    Location = "/tns:FITR/tns:RP/tns:PeriodEndD",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.FITR.434612" },
                        new ProcessMessageParameter { Name = "FITR301", Value = FITR2026Validator.GetValueOrEmptyDate(ParentDocument.FITR301) },
                        new ProcessMessageParameter { Name = "DISTBENTRT2", Value = FITR2026Validator.GetValueOrEmptyDate(ChildDocument.DISTBENTRT2) }
                    },
                    DocumentSequence = "parent_doc"
                };

                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.FITR.434612

        #region VR.ATO.FITR.434613

        /*  VR.ATO.FITR.434613
        The Tax File Number (TFN) provided for the Distributions to Beneficiaries of Trust schedule must be the same as the TFN of the parent form

        Technical Business Rule:
        CountDocument('DISTBENTRT') = 1 AND ^FITR5 <> ^DISTBENTRT3

        Data Elements:
        ^FITR5 = FITR:RP:Identifiers.TaxFileNumber.Identifier
        ^DISTBENTRT3 = DISTBENTRT:Identifiers.TaxFileNumber.Identifier
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOFITR434613()
        {
            bool assertion = ParentDocument.FITR5 != ChildDocument.DISTBENTRT3;

            if (assertion)
            {
                ProcessMessageDocument processMessage = new ProcessMessageDocument
                {
                    Code = "CMN.ATO.FITR.434613",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Tax File Number for the Distributions to Beneficiaries of Trust schedule is invalid",
                    LongDescription = @"The Tax File Number (TFN) provided for the Distributions to Beneficiaries of Trust schedule must be the same as the TFN of the parent form",
                    Location = "/tns:FITR/tns:RP/tns:TaxFileNumberId",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.FITR.434613" },
                        new ProcessMessageParameter { Name = "FITR5", Value = ParentDocument.FITR5 },
                        new ProcessMessageParameter { Name = "DISTBENTRT3", Value = ChildDocument.DISTBENTRT3 }
                    },
                    DocumentSequence = "parent_doc"
                };

                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.FITR.434613

        #region VR.ATO.FITR.434627

        /*  VR.ATO.FITR.434627
        Junior minerals exploration incentive (JMEI) law is no longer operative. For information about claiming the junior minerals exploration incentive, see ato.gov.au.

        Technical Business Rule:
        CountDocument('DISTBENTRT') = 1 AND AnyOccurrence(^DISTBENTRT1002, ^DISTBENTRT27 <> NULL)

        Data Elements:
        ^DISTBENTRT27 = DISTBENTRT:RP:StatementOfDistributionToBeneficiaryCollection:StatementOfDistributionToBeneficiary:Information:IncomeTaxExplorationCreditsDistributedA
        */

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOFITR434627()
        {
            IEnumerable<ProcessMessageDocument> processMessages = ChildDocument.RP_StatementOfDistributionToBeneficiaryCollection?
                                                    .Where(item => item?.DISTBENTRT27 != null)
                                                    .Select(item => new ProcessMessageDocument
                                                    {
                                                        Code = "CMN.ATO.FITR.434627",
                                                        Severity = ProcessMessageSeverity.Error,
                                                        Description = @"Exploration credits distributed for the Distributions to Beneficiaries of Trust schedule must not be provided",
                                                        LongDescription = @"Junior minerals exploration incentive (JMEI) law is no longer operative. For information about claiming the junior minerals exploration incentive, see ato.gov.au.",
                                                        Location = "/tns:DISTBENTRT/tns:RP/tns:StatementOfDistributionToBeneficiaryCollection/tns:StatementOfDistributionToBeneficiary" + OccurrenceIndex(item.OccurrenceIndex) + "/tns:Information/tns:IncomeTaxExplorationCreditsDistributedA",
                                                        Parameters = new ProcessMessageParameters
                                                        {
                                                            new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.FITR.434627" },
                                                            new ProcessMessageParameter { Name = "DISTBENTRT27", Value = FITR2026Validator.GetValueOrEmpty(item.DISTBENTRT27) }
                                                        },
                                                        DocumentSequence = "parent_doc"
                                                    });

            if (processMessages?.Count() > 0)
            {
                Response.AddRange(processMessages);
            }
        }

        #endregion // VR.ATO.FITR.434613

        #region VR.ATO.FITR.W00002

        /*  VR.ATO.FITR.W00002
        Distributions to Beneficiaries of Trust schedule is provided but Trust distributions - Income amounts or credits are not declared

        Technical Business Rule:
        CountDocument('DISTBENTRT') = 1 AND ^FITR14 = '022' AND ^FITR37 = NULL AND ^FITR38 = NULL AND ^FITR39 = NULL AND ^FITR40 = NULL

        Data Elements:
        ^FITR14 = FITR:RP:Party.Type.Code
        ^FITR37 = FITR:RP:Income.TrustDistributionUnfranked.Amount
        ^FITR38 = FITR:RP:Income.TrustDistributionFranked.Amount
        ^FITR39 = FITR:RP:IncomeTax.FrankingCredits.FrankingCreditShareReceivedIndirectly.Amount
        ^FITR40 = FITR:RP: Income.TrustDistributionOther.Amount
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOFITRW00002()
        {
            bool assertion = ParentDocument.FITR14.Equals("022") && !ParentDocument.FITR37.HasValue && !ParentDocument.FITR38.HasValue && !ParentDocument.FITR39.HasValue && !ParentDocument.FITR40.HasValue;

            if (assertion)
            {
                ProcessMessageDocument processMessage = new ProcessMessageDocument
                {
                    Code = "CMN.ATO.FITR.W00002",
                    Severity = ProcessMessageSeverity.Warning,
                    Description = @"Ensure Trust distributions - Income amounts or credits are declared",
                    LongDescription = @"Distributions to Beneficiaries of Trust schedule must be present when the type of fund or trust is a Small APRA fund and Trust distributions - Income amounts or credits are provided",
                    Location = "/tns:FITR/tns:RP/tns:StatusOfFundOrTrust/tns:PartyTypeC",
                    Parameters = new ProcessMessageParameters {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.FITR.W00002" },
                        new ProcessMessageParameter { Name = "FITR14", Value = ParentDocument.FITR14 },
                        new ProcessMessageParameter { Name = "FITR37", Value = FITR2026Validator.GetValueOrEmpty(ParentDocument.FITR37) },
                        new ProcessMessageParameter { Name = "FITR38", Value = FITR2026Validator.GetValueOrEmpty(ParentDocument.FITR38)},
                        new ProcessMessageParameter { Name = "FITR39", Value = FITR2026Validator.GetValueOrEmpty(ParentDocument.FITR39) },
                        new ProcessMessageParameter { Name = "FITR40", Value = FITR2026Validator.GetValueOrEmpty(ParentDocument.FITR40)}
                    },
                    DocumentSequence = "parent_doc"
                };

                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.FITR.W00002
    }
}