using iRIS.InsuranceCore.Code.CustomProcesses.BasketPreparationProcess.Enums;
using iRIS.InsuranceCore.Entities;
using iRIS.InsuranceCore.OSS.Code.Constants;
using iRIS.InsuranceCore.OSS.Code.Dto.Uni;
using iRIS.InsuranceCore.OSS.Code.Mappers;
using System;
using System.Collections.Generic;
using System.Linq;
using iRIS.Framework.ExtensionMethods;

namespace iRIS.KaskoCore.CreateOn.Code.Utilities
{
    public sealed class OssKaskoOptionsParser : IOssKaskoOptionsParser
    {
        private List<PreviousOssOption> _ossKaskoOptions;

        public IReadOnlyList<PreviousOssOption> Parse(OssUniPolicyDto ossUniPolicy)
        {
            _ossKaskoOptions = new List<PreviousOssOption>();

            ParseCovers(ossUniPolicy);
            ParseOptions(ossUniPolicy);
            ParsePayments(ossUniPolicy);
            ParseTelematics(ossUniPolicy);

            return _ossKaskoOptions;
        }

        private void ParseCovers(OssUniPolicyDto ossUniPolicy)
        {
            foreach (var ossCoverage in ossUniPolicy.Covers)
            {
                var ossCoverageSum = GetSum(ossCoverage.Restrictions);

                AddOssKaskoOption(
                    ProductConfigurationType.Coverage,
                    ossCoverage.Code,
                    ossCoverageSum,
                    ossCoverage.Premium);

                foreach (var ossRisk in ossCoverage.Risks)
                {
                    AddOssKaskoOption(
                        ProductConfigurationType.Risk,
                        ossRisk,
                        null,
                        null,
                        ossCoverage.Code);
                }

                foreach (var ossFranchise in ossCoverage.Restrictions.Where(r => MapDictionarys.ProductCodeToOssRestrictionType.Values.Contains(r.Type)))
                {
                    var sumFranchise = MapHelper.ConvertToDecimal(ossFranchise.Value);
                    if (sumFranchise <= 0m)
                    {
                        continue;
                    }

                    AddOssKaskoOption(
                        ProductConfigurationType.Franchise,
                        ossFranchise.Name,
                        sumFranchise,
                        null,
                        ossCoverage.Code);
                }
            }
        }

        private void ParseOptions(OssUniPolicyDto ossUniPolicy)
        {
            foreach (var ossOption in ossUniPolicy.Options)
            {
                AddOssKaskoOption(
                    ProductConfigurationType.Option,
                    ossOption.Key,
                    null,
                    null);
            }
        }

        private void ParsePayments(OssUniPolicyDto ossUniPolicy)
        {
            var code = !string.IsNullOrEmpty(ossUniPolicy?.Payments?.PremiumPlan)
                ? ossUniPolicy.Payments.PremiumPlan
                : "Единовременно";

            AddOssKaskoOption(
                ProductConfigurationType.PaymentSchedule,
                code,
                null,
                null);
        }

        private void ParseTelematics(OssUniPolicyDto ossUniPolicy)
        {
            if (ossUniPolicy.Telematics == null)
            {
                return;
            }

            // Если тип телематики не указан, но имеется Mileagelimit, то определяем тип как "ограничение пробега" ("LIM")
            if (string.IsNullOrEmpty(ossUniPolicy.Telematics.Type) && !string.IsNullOrEmpty(ossUniPolicy.Telematics.Mileagelimit))
            {
                ossUniPolicy.Telematics.Type = OSSTelematicCodes.MileLimit;
            }

            switch (ossUniPolicy.Telematics.Type)
            {
                case OSSTelematicCodes.MileLimit:
                    AddOssKaskoOption(
                        ProductConfigurationType.Option,
                        OSSTelematicCodes.MileLimit,
                        MapHelper.ConvertToDecimal(ossUniPolicy.Telematics.Mileagelimit),
                        null);
                    break;
                case OSSTelematicCodes.SafeDriveTelematic:
                    AddOssKaskoOption(
                        ProductConfigurationType.Option,
                        OSSTelematicCodes.SafeDriveTelematic,
                        null,
                        null);
                    break;
                case OSSTelematicCodes.MobileTelematic:
                    AddOssKaskoOption(
                        ProductConfigurationType.Option,
                        OSSTelematicCodes.MobileTelematic,
                        null,
                        null);
                    break;
            }
        }

        private void AddOssKaskoOption(ProductConfigurationType type, string ossCode, decimal? sum, decimal? premium, string parentOssCode = null)
        {
            var ossKaskoOption = new PreviousOssOption()
            {
                Sum = sum,
                OssCode = ossCode,
                Premium = premium,
                ParentOssCode = parentOssCode,
                Type = type.ToString()
            };

            _ossKaskoOptions.Add(ossKaskoOption);
        }

        private decimal? GetSum(IReadOnlyList<OssUniRestrictionDto> restrictions)
        {
            if (restrictions.Count == 0)
            {
                return null;
            }

            var sumStr = restrictions.SingleOrDefault(r => r.Type == "2")?.Value;
            return MapHelper.ConvertToDecimal(sumStr);
        }
    }
}



Расскажи куда сохраняются данные по платежам?