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

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

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

        public List<ProcessMessageDocument> ValidateCrossFormRules()
        {
            //Parent Cross From Validation Rules
            VRATOCTR428234();
            VRATOCTR428240();

            //Child Cross From Validation Rules
            VRATOIEE410051();
            VRATOIEE410324();
            VRATOIEE410396();
            VRATOIEE410410();

            return Response;
        }

        #region VR.ATO.CTR.428234

        /*  VR.ATO.CTR.428234
        Main entity cannot interpose itself

        Legacy Rule Format:
        IF (RP:entity.identifier.TFN <> NULLORBLANK) AND (COUNT(SCHEDULE = "IEE") > 0) AND (RP:entity.identifier.TFN = ANY OCCURRENCE OF ([IEE50]))
           RETURN VALIDATION MESSAGE
        ENDIF
        
        Data Elements:

        ^CTR TFN = CTR:RP:Identifiers.TaxFileNumber.Identifier
        ^IEE50 = IEE:RP:Identifiers.TaxFileNumber.Identifier
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOCTR428234()
        {
            ProcessMessageDocument processMessage;
            bool assertion = !string.IsNullOrWhiteSpace(ParentDocument.RPIdentifierTFN) && ParentDocument.RPIdentifierTFN == ChildDocument.IEE50;

            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.CTR.428234",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Main entity cannot interpose itself",
                    LongDescription = @"An Entity cannot interpose itself, therefore the family trust tax file number quoted in Interposed Entity Election cannot be the same as the entity making the election",
                    Location = ParentDocument.RPOccurrenceIndex > 1 ? "/xbrli:xbrl/xbrli:context[" + ParentDocument.RPOccurrenceIndex.ToString() + "]/xbrli:entity/xbrli:identifier" : $"/xbrli:xbrl/xbrli:context/xbrli:entity/xbrli:identifier",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.CTR.428234" } },
                    DocumentSequence = "parent_doc"
                };

                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "CTR TFN", Value = ParentDocument.RPIdentifierTFN });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE50", Value = ChildDocument.IEE50 });
                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.CTR.428234 

        #region VR.ATO.CTR.428240

        /*  VR.ATO.CTR.428240
        Revocation date of the Interposed Entity Election is invalid

        Legacy Rule Format:
        IF (CTR:RP:pyin.xx.xx:Report.TargetFinancial.Year <> NULL) AND (COUNT(SCHEDULE = "IEE") > 0) AND (ANY OCCURRENCE OF ([IEE116] = "R") AND ([IEE82] <> CTR:RP:pyin.xx.xx:Report.TargetFinancial.Year))
            RETURN VALIDATION MESSAGE
        ENDIF

        Data Elements:
    
        ^CTR2 = RP:Report.TargetFinancial.Year
        ^IEE82 = IEE:RP:Elections.Revocation.Year
        ^IEE116 = IEE:RP:Elections.InterposedEntityElectionOrRevocation.Code
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOCTR428240()
        {
            ProcessMessageDocument processMessage;
            bool assertion = (ParentDocument.CTR2.HasValue && !string.IsNullOrWhiteSpace(ChildDocument.IEE116) && ChildDocument.IEE116.ToUpper() == "R" && ChildDocument.IEE82.HasValue && ChildDocument.IEE82.GetValueOrDefault() != ParentDocument.CTR2.GetValueOrDefault());
           
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.430176",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Year of revocation must be the same as the year of the return",
                    LongDescription = @"The income year for which the details of the Interposed Entity Election are being revoked must equal the income year of the main return being lodged.",
                    Location = "/xbrli:xbrl/tns:Report.TargetFinancial.Year",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.CTR.428240" } },
                    DocumentSequence = "parent_doc"
                };

                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "CTR2", Value = CTR2026Validator.GetValueOrEmpty(ParentDocument.CTR2) });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE82", Value = CTR2026Validator.GetValueOrEmpty(ChildDocument.IEE82) });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE116", Value = ChildDocument.IEE116 });
                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.CTR.428240

        #region VR.ATO.IEE.410051

        /*  VR.ATO.IEE.410051
        Election Commencement Time must not be entered if Income Year Specified is different to the parent return.

        Legacy Rule Format:
        WHERE PARENT RETURN EXISTS
        (^IEE45 <> ^ParentTargetFinancialYear) AND (^IEE49 <> NULL)

        Data Elements:

        ^IEE49 = IEE:RP:InterposedEntityElectionRevocationDetails:Elections.Commencement.Date
        ^IEE45 = IEE:RP:InterposedEntityElectionRevocationDetails:ElectionDetails:Elections.InterposedEntityElectionStatus.Year
        ^CTR2 = CTR:RP:Report.TargetFinancial.Year
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOIEE410051()
        {
            ProcessMessageDocument processMessage;
            bool assertion = ChildDocument.IEE49.HasValue && ChildDocument.IEE45 != ParentDocument.CTR2;

            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.IEE.410235",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Election Commencement Time must not be present if Income Year Specified is different to the parent return target financial year",
                    Location = "/tns:IEE/tns:RP/tns:InterposedEntityElectionRevocationDetails/tns:ElectionsCommencementD",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.IEE.410051" } },
                };

                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE49", Value = CTR2026Validator.GetValueOrEmptyDate(ChildDocument.IEE49) });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE45", Value = CTR2026Validator.GetValueOrEmpty(ChildDocument.IEE45) });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "CTR2", Value = CTR2026Validator.GetValueOrEmpty(ParentDocument.CTR2) });
                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.IEE.410051

        #region VR.ATO.IEE.410324

        /*  VR.ATO.IEE.410324
        Reporting period on Schedule must match reporting period on main form

        Legacy Rule Format:
        WHERE PARENT RETURN EXISTS
        ^IEE201 <> ParentPeriodStartDate OR ^IEE202 <> ParentPeriodEndDateParentPeriodEndDate

        Data Elements:
    
        ^IEE201 = IEE:RP:Period.Start.Date
        ^CTR Start Date = CTR:RPStartDate
        ^IEE202 = IEE:RP:Period.End.Date
        ^CTR End Date = CTR:RPEndDate
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOIEE410324()
        {
            ProcessMessageDocument processMessage;
            bool assertion = ((ChildDocument.IEE201.HasValue && ChildDocument.IEE201 != ParentDocument.RPStartDate) || ChildDocument.IEE202.HasValue && ChildDocument.IEE202 != ParentDocument.RPEndDate);

            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.IEE.410324",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Reporting period does not match the reporting period supplied on the form it was submitted with",
                    Location = "/tns:IEE/tns:RP/tns:PeriodStartD",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.IEE.410324" } },
                };

                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE201", Value = CTR2026Validator.GetValueOrEmptyDate(ChildDocument.IEE201) });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "CTR Start Date", Value = CTR2026Validator.GetValueOrEmptyDate(ParentDocument.RPStartDate) });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE202", Value = CTR2026Validator.GetValueOrEmptyDate(ChildDocument.IEE202) });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "CTR End Date", Value = CTR2026Validator.GetValueOrEmptyDate(ParentDocument.RPEndDate) });
                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.IEE.410324

        #region VR.ATO.IEE.410396

        /*  VR.ATO.IEE.410396
        ABN on Schedule must match ABN on main form

        Legacy Rule Format:
        WHERE PARENT RETURN EXISTS
        (^IEE162 <> BLANK) AND (^ParentABN <> BLANK) AND (^IEE162 <> ^ParentABN)

        Data Elements:
    
        ^IEE162 = IEE:RP:Identifiers.AustralianBusinessNumber.Identifier
        ^ParentABN = ParentABN
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOIEE410396()
        {
            ProcessMessageDocument processMessage;
            bool assertion = !string.IsNullOrWhiteSpace(ChildDocument.IEE162) &&
                             !ChildDocument.IEE162.Equals(ParentDocument.CTR11);

            if (assertion)
            {
                processMessage = 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 = "/tns:IEE/tns:RP/tns:AustralianBusinessNumberId",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.IEE.410396" } },
                };

                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE162", Value = ChildDocument.IEE162 });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "CTR11", Value = ParentDocument.CTR11 });
                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.IEE.410396

        #region VR.ATO.IEE.410410

        /*  VR.ATO.IEE.410410
        TFN on Schedule must match TFN on main form

        Legacy Rule Format:
        WHERE PARENT RETURN EXISTS
        ^IEE3 <> ^ParentTFN

        Data Elements:
    
        ^IEE3 = IEE:RP:Identifiers.TaxFileNumber.Identifier
        ^CTR TFN = CTR TFN
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATOIEE410410()
        {
            ProcessMessageDocument processMessage;
            bool assertion = !string.IsNullOrWhiteSpace(ChildDocument.IEE3) &&
                              ChildDocument.IEE3 != ParentDocument.RPIdentifierTFN;

            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.GEN.410115",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"TFN on Schedule must match TFN on main form",
                    Location = "/tns:IEE/tns:RP/tns:TaxFileNumberId",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.IEE.410410" } },
                };

                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE3", Value = ChildDocument.IEE3 });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "CTR TFN", Value = ParentDocument.RPIdentifierTFN });
                Response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.IEE.410410
    }
}
