using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.ServiceImplementations;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using BS.Shared;
using BeWo.Service.Invoicing;
using BeWo.Data;
using BS.Shared.Services;

namespace BeWo.Report.ReportObjects
{
	public class FinanceRO : AbstractBeWoReportObject<FinanceRO>
	{
		public DateTime? ReportStartDate { get; set; }

		public DateTime? ReportEndDate { get; set; }

		public decimal? RateFactor { get; set; }

		public IList<SupportConceptFinanceRO> SupportConceptFinanceList { get; set; }


		public class SupportConceptFinanceRO
		{
			public string CustomerName { get; set; }

			public string SupportConceptTimeSpanString { get; set; }

			public string CostBearerName { get; set; }

			public decimal AmountTotal { get; set; }

			public decimal AmountPaid { get; set; }

			public decimal OpenAmount { get; set; }

			public decimal ApprovedHours { get; set; }

			public decimal BillableHours { get; set; }

			public decimal ApprovedHoursInReportTimeSpan { get; set; }

			public decimal BillableHoursInReportTimeSpan { get; set; }

			public decimal BillableHoursInReportTimeSpanWithFactor { get; set; }

			public decimal? RateFactor { get; set; }

			public List<ServiceRecordDC> ServiceRecords { get; set; }

			public bool IsApproved { get; set; }

			public SupportConceptCostBearerRelDC Costbearer2Supportconcept { get; set; }
		}

		public static FinanceRO Create(DateTime? start, DateTime? end)
		{
			var result = new FinanceRO();
			result.ReportStartDate = start;
			result.ReportEndDate = end;
			result.SupportConceptFinanceList = new List<SupportConceptFinanceRO>();

            var service = new AnalysisServiceImp();
            var financeList = service.GetOutstandingReceivables(false, false, start, end);
			
            foreach (var item in financeList)
            {
                if (item.SupportConcept != null && item.SupportConcept.ActivationType != ActivationTypeId.Deleted)
                {
					var ro = new SupportConceptFinanceRO();

	                ro.CustomerName = item.CustomerName;
					ro.SupportConceptTimeSpanString = item.SupportConceptTimeSpanString;
					ro.CostBearerName = item.CostBearerName;

					ro.AmountTotal = item.AmountTotal;
					ro.AmountPaid = item.AmountPaid;
					ro.OpenAmount = item.OpenAmount;
                    

                    var cb2sc = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(item.CostBearer.CostBearer2SupportConceptOid);

                    

                    var calc = Calculations.GetInstance(cb2sc.CostBearer.ID);
                    var relDC =
                        MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(cb2sc);
                    ro.ApprovedHours = calc.GetApprovedHoursTillNow(relDC, null) ?? 0;
	                ro.ServiceRecords =
		                cb2sc.ServiceRecords.Where(sr => sr.Start.Value.Date <= DateTime.Now.Date).ToList().MapToNewDCs();

	                ro.Costbearer2Supportconcept = relDC;
	                ro.IsApproved = (relDC.ApprovedEndDate.HasValue || relDC.ApprovedStartDate.HasValue);

					ro.BillableHours = calc.GetBillableDurationInMinutes(ro.ServiceRecords) / 60;

	                if (start.HasValue && end.HasValue)
	                {
		                ro.ApprovedHoursInReportTimeSpan = calc.GetApprovedHoursForPeriod(relDC, start.Value, end.Value);

		                ro.BillableHoursInReportTimeSpan =
			                calc.GetBillableDurationInMinutes(
				                cb2sc.ServiceRecords.Where(sr => sr.Start >= start && sr.Start.Value.Date <= end.Value.Date).ToList().
					                MapToNewDCs())/60;

		                var costRateDcs =
			                MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(cb2sc.CostBearer.CostRatePeriods);

		                var rfcr = costRateDcs.GetCostRatePeriodForDate(CostRatePeriodType.RateFactor, start.Value);
		                if (rfcr != null && rfcr.CostRateValue.HasValue)
		                {
			                ro.BillableHoursInReportTimeSpanWithFactor = ro.BillableHoursInReportTimeSpan*(rfcr.CostRateValue.Value + 100m)/100m;
			                ro.RateFactor = (rfcr.CostRateValue.Value + 100m)/100m;

			                if (!result.RateFactor.HasValue)
			                {
				                result.RateFactor = ro.RateFactor;
			                }
		                }
	                }

					

	                result.SupportConceptFinanceList.Add(ro);
                }
            }

			return result;
		}
	}
}
    