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

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

        private DISTBENTRT2024 ChildDocument { get; }

        public CrossFormValidatorDISTBENTRT(CTR2025 report, BusinessDocument childDocument)
        {
            ParentDocument = report;
            ChildDocument = (DISTBENTRT2024)childDocument.ConsumedReport;
        }

        public List<ProcessMessageDocument> ValidateCrossFormRules()
        {
            List<ProcessMessageDocument> response = new List<ProcessMessageDocument>();

            VRATOCTR500390(response);
            VRATOCTR500392(response);
            VRATOCTR500393(response);
            VRATOCTRW00027(response);

            return response;
        }

        //DISTBENTRT_CTR

        #region VR.ATO.CTR.500390 
        /*  VR.ATO.CTR.500390
                    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

                Legacy Rule Format:
                    IF COUNT(SCHEDULE = "DISTBENTRT") = 1 AND RP:entity.identifier.TFN <> [DISTBENTRT3]
                       RETURN VALIDATION MESSAGE
                    ENDIF

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

        Data Elements:
    
            ^DISTBENTRT3 = DISTBENTRT3
    
            ^TFN = RP
        */
        public void VRATOCTR500390(List<ProcessMessageDocument> response)
        {
            ProcessMessageDocument processMessage;
            bool assertion = !ParentDocument.RPIdentifierTFN.Equals(ChildDocument.DISTBENTRT3);

            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.CTR.500390",
                    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 = "/xbrli:xbrl/xbrli:context/xbrli:entity/xbrli:identifier",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.CTR.500390" },
                                                                  new ProcessMessageParameter() { Name = "RPEndDate", Value = ParentDocument.RPIdentifierTFN },
                                                                  new ProcessMessageParameter() { Name = "DISTBENTRT3", Value = ChildDocument.DISTBENTRT3 }}
                };

                response.Add(processMessage);
            }
        }
        #endregion VR.ATO.CTR.500390       

        #region VR.ATO.CTR.500392
        /*  VR.ATO.CTR.500392
                    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

                Legacy Rule Format:
                    IF COUNT(SCHEDULE = "DISTBENTRT") = 1 AND RP:period.startDate <> [DISTBENTRT1]
                       RETURN VALIDATION MESSAGE
                    ENDIF

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

        Data Elements:
    
            ^StartDate1 = RP
    
            ^DISTBENTRT1 = DISTBENTRT1
        */

        public void VRATOCTR500392(List<ProcessMessageDocument> response)
        {
            bool assertion = !ParentDocument.RPStartDate.Equals(ChildDocument.DISTBENTRT1);

            if (assertion)
            {
                var processMessage = new ProcessMessageDocument
                {
                    Code = "CMN.ATO.CTR.500392",
                    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 = "/xbrli:xbrl/xbrli:context" + OccurrenceIndex(ParentDocument.RPOccurrenceIndex) + "/xbrli:period/xbrli:startDate",
                    Parameters = new ProcessMessageParameters { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.CTR.500392" },
                                                                new ProcessMessageParameter() { Name = "RPEndDate", Value = ParentDocument.RPStartDate.Value.ToString("yyyy-MM-dd") },
                                                                new ProcessMessageParameter() { Name = "DISTBENTRT1", Value = ChildDocument.DISTBENTRT1.Value.ToString("yyyy-MM-dd") }}
                };
                response.Add(processMessage);
            }
        }
        #endregion // VR.ATO.CTR.500392

        #region  VR.ATO.CTR.500393
        /*  VR.ATO.CTR.500393
                    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

                Legacy Rule Format:
                    IF COUNT(SCHEDULE = "DISTBENTRT") = 1 AND RP:period.endDate <> [DISTBENTRT2]
                       RETURN VALIDATION MESSAGE
                    ENDIF

            Technical Business Rule Format:
                    CountDocument('DISTBENTRT') = 1 AND ^EndDate <> ^DISTBENTRT2

        Data Elements:
    
            ^EndDate = RP
    
            ^DISTBENTRT2 = DISTBENTRT2
            */
        public void VRATOCTR500393(List<ProcessMessageDocument> response)
        {
            ProcessMessageDocument processMessage;
            bool assertion = !ParentDocument.RPEndDate.Equals(ChildDocument.DISTBENTRT2);

            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.CTR.500393",
                    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 = "/xbrli:xbrl/xbrli:context" + OccurrenceIndex(ParentDocument.RPOccurrenceIndex) + "/xbrli:period/xbrli:endDate",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.CTR.500393" } ,
                                                                  new ProcessMessageParameter() { Name = "RPEndDate", Value = ParentDocument.RPEndDate.Value.ToString("yyyy-MM-dd") },
                                                                  new ProcessMessageParameter() { Name = "DISTBENTRT2", Value = ChildDocument.DISTBENTRT2.Value.ToString("yyyy-MM-dd") }}
                };

                response.Add(processMessage);
            }
        }

        #endregion // VR.ATO.CTR.500393

        #region VR.ATO.CTR.W00027

        /*  VR.ATO.CTR.W00027
                    Distributions to Beneficiaries of Trust schedule is provided but Gross distribution from trusts amount is not declared

                Legacy Rule Format:
                    IF (COUNT(SCHEDULE= "DISTBENTRT") = 1) AND [CTR61] = NULL
                       RETURN VALIDATION MESSAGE
                    ENDIF

            Technical Business Rule Format:
                    (CountDocument('DISTBENTRT') = 1) AND ^CTR61 = NULL

        Data Elements:
    
            ^CTR61 = RP:TrustDistributionIncome:Income.TrustDistributionGross.Amount
            */
        public void VRATOCTRW00027(List<ProcessMessageDocument> response)
        {
            ProcessMessageDocument processMessage;
            bool assertion = ParentDocument.CTR61 == null;
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.CTR.W00027",
                    Severity = ProcessMessageSeverity.Warning,
                    Description = @"Ensure Gross distribution from trusts amount is declared",
                    LongDescription = @"Ensure Gross distribution from trusts amount is declared when Distributions to Beneficiaries of Trust schedule is provided",
                    Location = "/xbrli:xbrl/tns:TrustDistributionIncome/tns:Income.TrustDistributionGross.Amount",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.CTR.W00027" },
                                                                { new ProcessMessageParameter() { Name = "CTR61", Value = GetValueOrEmpty(ParentDocument.CTR61) }}}
                };

                response.Add(processMessage);
            }
        }
        #endregion // VR.ATO.CTR.W00027

        private static string GetValueOrEmpty(decimal? val)
        {
            return (val.HasValue) ? val.ToString() : string.Empty;
        }

        /// <summary>
        /// Returns an occurrence index as [occurrenceIndex] of occurrenceIndex > 0, otherwise the empty string
        /// </summary>
        /// <param name="occurrenceIndex">Index of the occurrence.</param>
        /// <returns>Occurrence in XPath [#] format</returns>
        public string OccurrenceIndex(int occurrenceIndex)
        {
            return occurrenceIndex > 0 ? "[" + occurrenceIndex + "]" : "";
        }
    }
}