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

namespace Ato.CD.Inbound.PTR202502
{
    public class CrossFormValidatorIEE : ICrossFormValidator
    {
        private PTR2025 ParentDocument { get; }
        private IEE2021 ChildDocument { get; }
        /// <summary>
        /// The response parameter
        /// </summary>
        public List<ProcessMessageDocument> Response { get; private set; }

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

        public List<ProcessMessageDocument> ValidateCrossFormRules()
        {
            VRATOPTR430178();
            VRATOPTR440373();
            VRATOPTR430176();
            VRATOIEE410410();
            VRATOIEE410396();
            VRATOIEE410051();
            VRATOIEE410324();

            return Response;
        }

        #region VR.ATO.PTR.430178

        /*  
            VR.ATO.PTR.430178
            IEE specified income year must be present

            Legacy Rule Format:
            ^PTR26 = NULL AND CountDocument('IEE') > 0

            Technical Business Rule Format:
            ^PTR26 = NULL AND CountDocument('IEE') > 0

            Data Elements:

            ^PTR26 = PTR:RP:Elections.InterposedEntityElectionStatus.Year
        */
        public void VRATOPTR430178()
        {
            bool assertion = ParentDocument.PTR26 == null;

            if (assertion)
            {
                Response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.GEN.430178",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"IEE specified income year must be present",
                    LongDescription = @"If an IEE schedule is present, the Interposed entity election status - Specified income year must be present",
                    Location = "/tns:PTR/tns:RP/tns:ElectionsInterposedEntityElectionStatusY",
                    Parameters = new ProcessMessageParameters
                    {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.PTR.430178" },
                        new ProcessMessageParameter { Name = "PTR26", Value = "null" }
                    },
                    DocumentSequence = "parent_doc"
                });
            }
        }

        #endregion VR.ATO.PTR.430178

        #region VR.ATO.PTR.440373

        /*  
            VR.ATO.PTR.440373
            The Family Trust TFN on the IEE must not be the same as the main entity TFN

            Legacy Rule Format:
            CountDocument('IEE') > 0 AND ^IEE50 = ^PTR5

            Technical Business Rule Format:
            CountDocument('IEE') > 0 AND ^IEE50 = ^PTR5

            Data Elements:

            ^PTR5 = PTR:RP:Identifiers.TaxFileNumber.Identifier
            
        */
        public void VRATOPTR440373()
        {
            bool assertion = ParentDocument.PTR5 == ChildDocument.IEE50;
            if (assertion)
            {
                Response.Add(new ProcessMessageDocument
                {
                    Code = "CMN.ATO.GEN.430008",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"The Family Trust TFN on the IEE must not be the same as the main entity TFN",
                    LongDescription = @"An Entity cannot interpose itself; therefore the family trust tax file number quoted in Interposed Entity Election cannot be the same as the tax file number of the entity making the election ",
                    Location = "/tns:PTR/tns:RP/tns:TaxFileNumberId",

                    Parameters = new ProcessMessageParameters
                    {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.PTR.440373" },
                        new ProcessMessageParameter { Name = "PTR5", Value = ParentDocument.PTR5 },
                        new ProcessMessageParameter { Name = "IEE50", Value = ChildDocument.IEE50 },
                    },
                    DocumentSequence = "parent_doc"
                });
            }
        }


        #endregion VR.ATO.PTR.440373

        #region VR.ATO.PTR.430176

        /*  
            VR.ATO.PTR.430176
            Year of revocation must be the same as the year of the return

            Legacy Rule Format:
            CountDocument('IEE') > 0 AND (^IEE116 = 'R' AND ^IEE82 <> ^PTR1)

            Technical Business Rule Format:
            CountDocument('IEE') > 0 AND (^IEE116 = 'R' AND ^IEE82 <> ^PTR1)

            Data Elements:

            ^PTR1 = PTR:RP:Report.TargetFinancial.Year
            
        */
        public void VRATOPTR430176()
        {
            bool assertion = ChildDocument.IEE116.ToUpper() == "R" && ParentDocument.PTR1 != ChildDocument.IEE82;
            if (assertion)
            {
                Response.Add(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 = "/tns:PTR/tns:RP/tns:TargetFinancialY",

                    Parameters = new ProcessMessageParameters
                    {
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.PTR.430176" },
                        new ProcessMessageParameter { Name = "PTR1", Value = ParentDocument.PTR1.HasValue ? ParentDocument.PTR1.Value.ToString("yyyy"):"Null" },
                        new ProcessMessageParameter { Name = "IEE116", Value = ChildDocument.IEE116 },
                        new ProcessMessageParameter { Name = "IEE82", Value =ChildDocument.IEE82.HasValue ? ChildDocument.IEE82.Value.ToString("yyyy"):"Null" }
                    },
                    DocumentSequence = "parent_doc"
                });
            }
        }


        #endregion VR.ATO.PTR.430176

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

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

            Data Elements:

            ^PTR5 = PTR:RP:Identifiers.TaxFileNumber.Identifier

        */
        public void VRATOIEE410410()
        {
            bool assertion = !string.IsNullOrWhiteSpace(ChildDocument.IEE3) && ChildDocument.IEE3 != ParentDocument.PTR5;

            if (assertion)
            {
                Response.Add(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" },
                        new ProcessMessageParameter { Name = "PTR5", Value = ParentDocument.PTR5 },
                        new ProcessMessageParameter { Name = "IEE3", Value = ChildDocument.IEE3 },
                    }
                });
            }
        }
        #endregion

        #region VR.ATO.IEE.410396
        /*  
           VR.ATO.IEE.410396
           Your supplied ABN does not match the ABN supplied on the form it was submitted with

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

           Data Elements:

           ^PTR7 = PTR:RP:Identifiers.AustralianBusinessNumber.Identifier

       */
        public void VRATOIEE410396()
        {
            bool assertion = !string.IsNullOrWhiteSpace(ChildDocument.IEE162)
                          && !string.IsNullOrWhiteSpace(ParentDocument.PTR7)
                          && ChildDocument.IEE162 != ParentDocument.PTR7;

            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 = "/tns:IEE/tns:RP/tns:AustralianBusinessNumberId",
                    Parameters = new ProcessMessageParameters 
                    { 
                        new ProcessMessageParameter { Name = "RuleIdentifier", Value = "VR.ATO.IEE.410396" } ,
                        new ProcessMessageParameter { Name = "PTR7", Value = ParentDocument.PTR7 },
                        new ProcessMessageParameter { Name = "IEE162", Value = ChildDocument.IEE162 },
                    }
                });
            }
        }
        #endregion

        #region VR.ATO.IEE.410051
        /*  
          VR.ATO.IEE.410051
          Election Commencement Time must not be present if Income Year Specified is different to the parent return target financial year

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


          Data Elements:

          ^PTR1 = PTR:RP:Report.TargetFinancial.Year

      */
        public void VRATOIEE410051()
        {
            bool assertion = ChildDocument.IEE49.HasValue && ChildDocument.IEE45 != ParentDocument.PTR1;
            if (assertion)
            {
                Response.Add(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" },
                        new ProcessMessageParameter { Name = "PTR1", Value = ParentDocument.PTR1.HasValue ? ParentDocument.PTR1.Value.ToString("yyyy"):"Null"  },
                        new ProcessMessageParameter { Name = "IEE45", Value =ChildDocument.IEE45.HasValue ? ChildDocument.IEE45.Value.ToString("yyyy"):"Null"  },
                        new ProcessMessageParameter { Name = "IEE49", Value = ChildDocument.IEE49.HasValue ? ChildDocument.IEE49.Value.ToString("yyyy-MM-dd"):"null"  }
                    }
                });
            }
        }
        #endregion

        #region VR.ATO.IEE.410324

        /*  
          VR.ATO.IEE.410324
          Reporting period does not match the reporting period supplied on the form it was submitted with

          Technical Business Rule Format:
          WHERE PARENT RETURN EXISTS
          ^IEE201 <> ParentPeriodStartDate OR ^IEE202 <> ParentPeriodEndDate

          Data Elements:

          ^PTR500 = PTR:RP:Period.Start.Date    
          ^PTR501 = PTR:RP:Period.End.Date

        */
        public void VRATOIEE410324()
        {
            bool assertion = ChildDocument.IEE201 != ParentDocument.PTR500 || ChildDocument.IEE202 != ParentDocument.PTR501;
            if (assertion)
            {
                var 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" },
                        new ProcessMessageParameter { Name = "IEE201", Value = ChildDocument.IEE201.ToString() },
                        new ProcessMessageParameter { Name = "IEE202", Value = ChildDocument.IEE202.ToString() },
                        new ProcessMessageParameter { Name = "PTR500", Value = ParentDocument.PTR500.ToString() },
                        new ProcessMessageParameter { Name = "PTR501", Value = ParentDocument.PTR501.ToString() }
                    }
                };

                Response.Add(processMessage);
            }
        }

        #endregion VR.ATO.IEE.410324
    }
}