using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BS.Shared;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using BS.Shared.Services;

namespace VSDHammReports
{
	public class VSDCalculations : LWLCalculations
	{
		
		public override decimal? GetApprovedHoursTotal(SupportConceptCostBearerRelDC relDC, bool useIsCalculationWithFactor)
		{
			if (relDC.ApprovalPeriodList == null || !relDC.GetApprovedDuration().HasValue)
			{
				return null;
			}

			if (!useIsCalculationWithFactor)
			{
				return base.GetApprovedHoursTotal(relDC, useIsCalculationWithFactor);
			}

			decimal hoursTotal = 0;

			foreach (var scap in relDC.ApprovalPeriodList)
			{
				var newhoursTotal = this.GetApprovedHoursTotal(scap, relDC.CostBearer.CostRatePeriods);

				if (newhoursTotal.HasValue)
				{
					newhoursTotal = ApplyIsCalculationWithFactor(relDC, scap, newhoursTotal);
					hoursTotal += newhoursTotal.Value;
				}
			}
			

			
			hoursTotal = Math.Round(hoursTotal, 10, MidpointRounding.AwayFromZero);
			return hoursTotal;
		}

		public override decimal? GetApprovedHoursForPeriod(SupportConceptCostBearerRelDC relDC,
														  SupportConceptApprovalPeriodDC scap,
														  List<CostRatePeriodDC> costRatePeriods,
														  DateTime? pStart,
														  DateTime? pEnd,
														  bool useIsCalculationWithFactor)
		{
			decimal? approvedHours = GetApprovedHoursForPeriod(scap, costRatePeriods, pStart, pEnd);
			if (approvedHours.HasValue && useIsCalculationWithFactor)
				approvedHours = ApplyIsCalculationWithFactor(relDC, scap, approvedHours);
			return approvedHours;

		}

		public decimal? ApplyIsCalculationWithFactor(SupportConceptCostBearerRelDC relDC, SupportConceptApprovalPeriodDC scap, decimal? valueToApply)
		{
			if (valueToApply.HasValue && relDC .CostBearer != null && relDC.CostBearer.IsCalculatingWithFactor)
			{
				if (relDC.CostBearer.CostRatePeriods != null)
				{
					var rateFactorsInSpan = relDC.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.RateFactor, scap.StartDate.Value.Date, scap.EndDate.Value.Date).ToList();

					if (rateFactorsInSpan.Count > 1)
					{
						decimal totalhours = 0;

						var totalDays = (scap.EndDate.Value - scap.StartDate.Value).Days + 1;
						foreach (var keyValuePair in rateFactorsInSpan)
						{
							var span = keyValuePair.Value;
							var rf = keyValuePair.Key;

							if (rf.CostRateValue.HasValue && rf.CostRateValue.Value > 0)
							{
								var spanDays = (span.EndDate - span.StartDate).Days + 1;

								decimal prozent = (spanDays/(decimal)totalDays);
								decimal hours = valueToApply.Value * prozent;

								hours = (hours * 100) / (rf.CostRateValue.Value + 100);

								totalhours += hours;
							}


						}

						return totalhours;
					}
					else
					{
						decimal? rateFactor =
							relDC.CostBearer.CostRatePeriods.GetValidRateValueForDate(CostRatePeriodType.RateFactor, scap.StartDate.Value);
						if (rateFactor.HasValue && rateFactor.Value > 0)
							valueToApply = (valueToApply.Value*100)/(rateFactor.Value + 100);
					}
				}

			}
			return valueToApply;
		}

		public override decimal? GetApprovedHoursForPeriod(SupportConceptApprovalPeriodDC scap,
														  List<CostRatePeriodDC> costRatePeriods,
														  DateTime? pStart,
														  DateTime? pEnd)
		{
			if (!pStart.HasValue || !pEnd.HasValue)
			{
				return null;
			}
			if (scap.ApprovedBEInterval.HasValue && scap.ApprovedBEPerInterval.HasValue)
			{
				if (scap.ApprovedBEInterval.Value == SupportConceptApprovalInterval.Monthly)
				{
					var months = GetTotalMonths(pStart.Value, pEnd.Value);
					return months * scap.ApprovedBEPerInterval.Value;
				}
                else if (scap.ApprovedBEInterval.Value == SupportConceptApprovalInterval.Quarterly)
                {
                    var qs = GetTotalQuarters(pStart.Value, pEnd.Value);
                    return qs * scap.ApprovedBEPerInterval.Value;
                }
            }

			var periodInDays = (pEnd.Value.Date - pStart.Value.Date).Days + 1;

			return this.GetApprovedHoursPerDay(scap, costRatePeriods) * periodInDays;
		}

		public override decimal? GetApprovedHoursPerDay(SupportConceptApprovalPeriodDC scap,
													   List<CostRatePeriodDC> costRatePeriods)
		{
			if (scap.EndDate.HasValue && scap.StartDate.HasValue && scap.ApprovedBEPerInterval.HasValue && !scap.ApprovedBETotal.HasValue
				&& scap.ApprovedBEInterval.HasValue && scap.ApprovedBEInterval.Value == SupportConceptApprovalInterval.Weekly)
			{
				var scapDurationInDays = (scap.EndDate.Value - scap.StartDate.Value).Days + 1;

				decimal weeks = Math.Round(scapDurationInDays * 0.1427m, 2, MidpointRounding.AwayFromZero);
				decimal total = weeks * scap.ApprovedBEPerInterval.Value;

				decimal ah = 0;
				if (scapDurationInDays != 0)
					ah = total / scapDurationInDays;
				return ah;

			}
			return base.GetApprovedHoursPerDay(scap, costRatePeriods);


		}
		

	}
}
