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

namespace Ato.CD.Inbound.CTR202502
{
    internal class CrossFormValidatorIEE : ICrossFormValidator
    {
        private CTR2025 ParentDocument { get; }

        private IEE2021 ChildDocument { get; }

        internal CrossFormValidatorIEE(CTR2025 report, BusinessDocument childDocument)
        {
            ParentDocument = report;
            IEE2021XmlConsumer consumer = new IEE2021XmlConsumer();
            childDocument.DocumentStream.Position = 0;
            ChildDocument = consumer.Consume(childDocument.DocumentStream, true);
        }

        public List<ProcessMessageDocument> ValidateCrossFormRules()
        {
            var response = new List<ProcessMessageDocument>();
            // CTR - IEE
            VRATOCTR428234(response);
            VRATOCTR428240(response);
            // IEE - CTR
            VRATOIEE410410(response);
            VRATOIEE410396(response);
            VRATOIEE410324(response);

            return response;
        }

        #region  CTR-IEE

        #region VR.ATO.CTR.428234

        /*           
                   IF (RP:entity.identifier.TFN <> NULLORBLANK) AND (COUNT(SCHEDULE = "IEE") > 0) AND (RP:entity.identifier.TFN = ANY OCCURRENCE OF ([IEE50]))
                      RETURN VALIDATION MESSAGE
                   ENDIF                    
                   [IEE50] = IEE:RP:pyid.xx.xx:Identifiers.TaxFileNumber.Identifier IN TUPLE(iee.0003.lodge.req.xx.xx:FamilyTrust)
       */

        protected void VRATOCTR428234(List<ProcessMessageDocument> response)
        {
            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" } },
                };

                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE50", Value = ChildDocument.IEE50.ToString() });
                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
                    
                    [IEE82] = IEE:RP:rvctc3.02.00:Elections.Revocation.Year
                    [IEE116] = IEE:RP:rvctc3.02.02:Elections.InterposedEntityElectionOrRevocation.Code

            Technical Business Rule Format:
                    (^CTR2 <> NULL) AND (CountDocument('IEE') > 0) AND ((AnyOccurrence(^IEE116, ^IEE116 = 'R')) AND (^IEE82 <> ^CTR2))

        Data Elements:
    
            ^CTR2 = RP:Report.TargetFinancial.Year
    
            ^IEE82 = IEE:RP:rvctc3.02.00:Elections.Revocation.Year
    
            ^IEE116 = IEE:RP:rvctc3.02.02:Elections.InterposedEntityElectionOrRevocation.Code
            */
        protected void VRATOCTR428240(List<ProcessMessageDocument> response)

        {
            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" } },
                };
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "CTR2", Value = ParentDocument.CTR2.GetValueOrDefault().ToString() });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE116", Value = ChildDocument.IEE116.ToString() });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE82", Value = ChildDocument.IEE82.ToString() });
                response.Add(processMessage);

            }
        }

        #endregion // VR.ATO.CTR.428240

        #endregion

        #region  IEE-CTR

        #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

            Technical Business Rule Format:
                    ^IEE3 <> ^ParentTFN

        Data Elements:
    
            ^IEE3 = IEE:RP:Identifiers.TaxFileNumber.Identifier
    
            ^ParentTFN = ParentTFN
            */
        protected void VRATOIEE410410(List<ProcessMessageDocument> response)
        {
            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 });
                response.Add(processMessage);
            }
        }
        #endregion // VR.ATO.GEN.410115 

        #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)

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

        Data Elements:
    
            ^IEE162 = IEE:RP:Identifiers.AustralianBusinessNumber.Identifier
    
            ^ParentABN = ParentABN
            */
        protected void VRATOIEE410396(List<ProcessMessageDocument> response)
        {
            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 });

                response.Add(processMessage);
            }
        }
        #endregion // VR.ATO.GEN.402010

        #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)

           Technical Business Rule Format:
                   (^IEE45 <> ^ParentTargetFinancialYear) AND (^IEE49 <> NULL)

       Data Elements:

           ^IEE49 = IEE:RP:InterposedEntityElectionRevocationDetails:Elections.Commencement.Date

           ^IEE45 = IEE:RP:InterposedEntityElectionRevocationDetails:ElectionDetails:Elections.InterposedEntityElectionStatus.Year

           ^ParentTargetFinancialYear = ParentTargetFinancialYear
           */
        protected void VRATOIEE410051(List<ProcessMessageDocument> response)
        {
            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 = "IEE45", Value = ChildDocument.IEE45.ToString() });
                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

            Technical Business Rule Format:
                    ^IEE201 <> ParentPeriodStartDate OR ^IEE202 <> ParentPeriodEndDate

        Data Elements:
    
            ^IEE201 = IEE:RP:Period.Start.Date
    
            ^IEE202 = IEE:RP:Period.End.Date
            */
        protected void VRATOIEE410324(List<ProcessMessageDocument> response)
        {
            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 = ChildDocument.IEE201.ToString() });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "IEE202", Value = ChildDocument.IEE202.ToString() });
                response.Add(processMessage);
            }
        }
        #endregion // VR.ATO.IEE.410324

        #endregion
    }
}