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

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

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

        public List<ProcessMessageDocument> ValidateCrossFormRules()
        {
            VRATODIS406032();
            VRATODIS406036();
            VRATODIS406038();

            return Response;
        }

        #region VR.ATO.DIS.406032

        /*  VR.ATO.DIS.406032
        The supplied ABN needs to match the ABN supplied on the parent  form it was submitted with

        Legacy Rule Format:
        WHERE PARENT RETURN EXISTS
        IF (RP:pyid.xx.xx:Identifiers.AustralianBusinessNumber.Identifier <> NULLORBLANK) AND (PARENT RETURN:RP:pyid.xx.xx:Identifiers.AustralianBusinessNumber.Identifier <> NULLORBLANK) AND (RP:pyid.xx.xx:Identifiers.AustralianBusinessNumber.Identifier <> PARENT RETURN:RP:pyid.xx.xx:Identifiers.AustralianBusinessNumber.Identifier)
            RETURN VALIDATION MESSAGE
        ENDIF

        Data Elements:

        ^CTR11 = CTR:RP:Identifiers.AustralianBusinessNumber.Identifier
        ^DIS23 = DIS:RP:Identifiers.AustralianBusinessNumber.Identifier
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATODIS406032()
        {
            ProcessMessageDocument processMessage;
            bool assertion = !string.IsNullOrWhiteSpace(ChildDocument.DIS23) &&
                             !string.IsNullOrWhiteSpace(ParentDocument.CTR11) &&
                             !ChildDocument.DIS23.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 = "/xbrli:xbrl/tns:Identifiers.AustralianBusinessNumber.Identifier",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.DIS.406032" } },
                };

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

        #endregion // VR.ATO.DIS.406032

        #region VR.ATO.DIS.406036

        /*  VR.ATO.DIS.406036
        The supplied TFN needs to match the TFN supplied on the parent form it was submitted with

        Legacy Rule Format:
        WHERE PARENT RETURN EXISTS
        IF (RP:entity.identifier.TFN <> PARENT RETURN:RP:entity.identifier.TFN)
            RETURN VALIDATION MESSAGE
        ENDIF

        Data Elements:

        ^CTR TFN = CTR:RP:entity.identifier.TFN
        ^DIS TFN = DIS:RP:entity.identifier.TFN
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATODIS406036()
        {
            ProcessMessageDocument processMessage;
            bool assertion = !string.IsNullOrWhiteSpace(ChildDocument.RPIdentifierTFN) &&
                            !ChildDocument.RPIdentifierTFN.Equals(ParentDocument.RPIdentifierTFN);
            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.DIS.406036",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Your supplied TFN does not match the TFN supplied on the parent form it was submitted with.",
                    Location = ChildDocument.RPOccurrenceIndex > 1 ? "/xbrli:xbrl/xbrli:context[" + ChildDocument.RPOccurrenceIndex.ToString() + "]/xbrli:entity/xbrli:identifier" : $"/xbrli:xbrl/xbrli:context/xbrli:entity/xbrli:identifier",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.DIS.406036" } },
                };

                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "CTR TFN", Value = ParentDocument.RPIdentifierTFN });
                processMessage.Parameters.Add(new ProcessMessageParameter { Name = "DIS TFN", Value = ChildDocument.RPIdentifierTFN });
                Response.Add(processMessage);
            }
        }
        #endregion // VR.ATO.DIS.406036

        #region VR.ATO.DIS.406038

        /*  VR.ATO.DIS.406038
        Organisation main name on schedule does not match parent return

        Legacy Rule Format:
        WHERE PARENT RETURN EXISTS
        IF RP:pyde.xx.xx:OrganisationNameDetails.OrganisationalName.Text
        IN TUPLE (xbrli\orgname1.xx.xx:OrganisationNameDetails) <> NULL
        AND RP:pyde.xx.xx:OrganisationNameDetails.OrganisationalName.Text
        IN TUPLE (xbrli\orgname1.xx.xx:OrganisationNameDetails) <> 
        (PARENT RETURN:RP:pyde.xx.xx:OrganisationNameDetails.OrganisationalName.Text
        IN TUPLE (xbrli\orgname2.xx.xx:OrganisationNameDetails)
        WHERE (TUPLE EXPLICIT pyde.xx.xx:OrganisationNameDetails.OrganisationalNameType.Code = "MN")
        AND  (TUPLE EXPLICIT pyde.xx.xx:OrganisationNameDetails.Currency.Code = "C")) 
        RETURN VALIDATION MESSAGE
        ENDIF

        Data Elements:

        ^CTR9 = CTR:RP:OrganisationNameDetails.OrganisationalName.Text
        ^DIS24 = DIS:RP:OrganisationNameDetails.OrganisationalName.Text
        */
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public virtual void VRATODIS406038()
        {
            ProcessMessageDocument processMessage;
            bool assertion = !string.IsNullOrWhiteSpace(ChildDocument.DIS24) &&
                             !ChildDocument.DIS24.Equals(ParentDocument.CTR9);

            if (assertion)
            {
                processMessage = new ProcessMessageDocument()
                {
                    Code = "CMN.ATO.DIS.406038",
                    Severity = ProcessMessageSeverity.Error,
                    Description = @"Organisation main name on schedule does not match parent return.",
                    Location = ChildDocument.OrganisationNameDetailsCollection_MN_RPOccurrenceIndex > 1 ? "/xbrli:xbrl/tns:OrganisationNameDetails[" + ChildDocument.OrganisationNameDetailsCollection_MN_RPOccurrenceIndex + "]/tns:OrganisationNameDetails.OrganisationalName.Text"
                    : "/xbrli:xbrl/tns:OrganisationNameDetails/tns:OrganisationNameDetails.OrganisationalName.Text",
                    Parameters = new ProcessMessageParameters() { new ProcessMessageParameter() { Name = "RuleIdentifier", Value = "VR.ATO.DIS.406038" } },
                };

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

        #endregion // VR.ATO.DIS.406038
    }
}
