using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Forces.BeamShearActions;
using StructureHelperLogics.Models.BeamShears.Logics;

namespace StructureHelperLogics.Models.BeamShears
{
    public class CheckBeamShearCalculatorInputDataLogic : ICheckInputDataLogic<IBeamShearCalculatorInputData>
    {
        private bool result;
        private string checkResult;
        private ICheckEntityLogic<IBeamShearAction> checkActionsLogic;
        private ICheckEntityLogic<IBeamShearSection> checkSectionLogic;
        private ICheckEntityLogic<IHasStirrups> StirrupCheckLogic;

        public string CheckResult => checkResult;
        public IBeamShearCalculatorInputData InputData { get; set; }
        public IShiftTraceLogger? TraceLogger { get; set; }
        public CheckBeamShearCalculatorInputDataLogic(IBeamShearCalculatorInputData inputData, IShiftTraceLogger? traceLogger)
        {
            InputData = inputData;
            TraceLogger = traceLogger;
        }

        public bool Check()
        {
            result = true;
            checkResult = string.Empty;
            if (InputData is null)
            {
                result = false;
                string errorString = ErrorStrings.ParameterIsNull + ": Input data";
                throw new StructureHelperException(errorString);
            }
            CheckActions();
            CheckSections();
            CheckStirrups();
            return result;
        }

        private void CheckActions()
        {
            if (InputData.Actions is null || !InputData.Actions.Any())
            {
                result = false;
                string errorString = "\nCollection of actions does not contain any action";
                TraceMessage(errorString);
            }
            else
            {
                checkActionsLogic ??= new CheckBeamShearActionLogic(TraceLogger);
                foreach (var action in InputData.Actions)
                {
                    checkActionsLogic.Entity = action;
                    if (checkActionsLogic.Check() == false)
                    {
                        result = false;
                        checkResult += checkActionsLogic.CheckResult;
                    }
                }
            }
        }

        private void CheckStirrups()
        {
            StirrupCheckLogic ??= new HasStirrupsCheckLogic(TraceLogger);
            StirrupCheckLogic.Entity = InputData;
            if (StirrupCheckLogic.Check() == false)
            {
                result = false;
                checkResult += StirrupCheckLogic.CheckResult;
            }
        }

        private void CheckSections()
        {
            if (InputData.Sections is null || !InputData.Sections.Any())
            {
                result = false;
                TraceMessage("\nCollection of sections does not contain any section");
            }
            else
            {
                checkSectionLogic = new CheckBeamShearSectionLogic(InputData.CodeType, TraceLogger);
                foreach (var item in InputData.Sections)
                {
                    checkSectionLogic.Entity = item;
                    if (checkSectionLogic.Check() == false)
                    {
                        result = false;
                        checkResult += checkSectionLogic.CheckResult;
                    }
                }
            }
        }

        private void TraceMessage(string errorString)
        {
            checkResult += errorString;
            TraceLogger?.AddMessage(errorString);
        }
    }
}
