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

namespace BeWo.GpzBiberachReports.Invoicing
{
	[IDSpecificClass(Identifiers = new string[] { "Soziotherapie" })]
	public class SoziotherapieInvoiceCreation : InvoiceCreation
    {
		private decimal minutesCountUntilNow = 0;

		private const decimal AMOUNTPERUNIT_HAUSBESUCH_BG = 8.49m;

		private const decimal AMOUNTPERUNIT_HAUSBESUCH_VOR_APRIL_14 = 4.16m;
		private const decimal AMOUNTPERUNIT_HAUSBESUCH_AB_APRIL_14 = 4.28m;
		private const decimal AMOUNTPERUNIT_HAUSBESUCH_AB_APRIL_15 = 4.39m;
        private const decimal AMOUNTPERUNIT_HAUSBESUCH_AB_APRIL_16 = 4.52m;

        //private const decimal AMOUNTPERUNIT_AB_60_STUNDEN_VOR_APRIL_14 = 46.82m;
        //private const decimal AMOUNTPERUNIT_AB_60_STUNDEN_AB_APRIL_14 = 48.14m;

        public override void SetInvoiceId(ServiceInvoice invoice)
		{
			invoice.InvoiceBase.InvoiceId = "Soziotherapie";
			invoice.InvoiceBase.InvoiceTypeText = "Soziotherapie";
		}

		public override void SetServiceInvoicePeriods(ServiceInvoice invoice, CostBearer2SupportConcept c2s, DateTimeSpan invoicePeriod, List<ServiceRecordDC> serviceRecords)
		{
			var list = DAOFactory.SearchDAO.FindServiceRecordsDetailsForLastDays(c2s.Oid.Value, null);

			DateTime min = DateTime.MaxValue;

			foreach (var srDC in serviceRecords)
			{
				if (srDC.Start.HasValue && srDC.Start.Value < min)
					min = srDC.Start.Value;
			}
			foreach (var sr in list)
			{
				if (sr.ServiceDescription.ServiceCategory.IsBillable && sr.Start.HasValue && sr.Start < min && sr.ServiceDescription.Name.ToLower().IndexOf("bg") == -1)
				{
					minutesCountUntilNow += sr.RoundedDuration;
				}
			}
			base.SetServiceInvoicePeriods(invoice, c2s, invoicePeriod, serviceRecords);
		}

		public override IList<InvoiceItem> CreateInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap, Calculations calc)
		{
			var list = base.CreateInvoiceItems(serviceRecordsInPeriod, invoicePeriod, scap, calc);

			var items = CreateHausbesuchInvoiceItems(serviceRecordsInPeriod, scap, calc);
			if (items != null && items.Count > 0)
				list.AddRange(items);
			return list;
		}

		public override IList<InvoiceItem> CreateSummaryInvoiceItems(IList<InvoiceItem> itemList, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap,
			Calculations calc)
		{
			return itemList;
		}

		public override InvoiceItem CreateInvoiceItem(ServiceRecordDC iServiceRecord, SupportConceptApprovalPeriod scap, Calculations calc)
		{
			DateTime april14 = new DateTime(2014, 4, 1);
			var invoiceItem = new InvoiceItem();

			var bd = calc.GetBillingData(iServiceRecord);
			if (minutesCountUntilNow >= 3600)
			{
				//if (iServiceRecord.Start < april14)
				//	bd.AmountPerUnit = AMOUNTPERUNIT_AB_60_STUNDEN_VOR_APRIL_14;
				//else
				//	bd.AmountPerUnit = AMOUNTPERUNIT_AB_60_STUNDEN_AB_APRIL_14;

				//bd.AmountTotal = bd.AmountPerUnit * bd.UnitCount;
				//bd.GrossAmountTotal = bd.AmountTotal;
			}
			minutesCountUntilNow += iServiceRecord.RoundedDuration;

			invoiceItem.AmountPerUnit = bd.AmountPerUnit;
			invoiceItem.UnitCount = bd.UnitCount;
			invoiceItem.AmountTotal = bd.AmountTotal;
			invoiceItem.ItemPeriodStart = bd.BillingPeriodStart;
			invoiceItem.ItemPeriodEnd = bd.BillingPeriodEnd;
			invoiceItem.RateFactor = bd.RateFactor;
			invoiceItem.GrossAmountTotal = bd.GrossAmountTotal;
			invoiceItem.AccountingInterval = bd.AccountingInterval;
			invoiceItem.ItemDescription = iServiceRecord.ServiceDescription.Name; //iServiceRecord.Employee + " - " + iServiceRecord.ServiceDescription.Name;
			invoiceItem.ServiceRecord = DAOFactory.GenericDAO.LoadByID<ServiceRecord>(iServiceRecord.ServiceRecordOid.Value);
			if (scap != null)
				invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
			
			return invoiceItem;
		}

		public virtual IList<InvoiceItem> CreateHausbesuchInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, SupportConceptApprovalPeriod scap, Calculations calc)
		{
			//Dictionary<String, int> differentDays = new Dictionary<string, int>();
			IList<InvoiceItem> items = new List<InvoiceItem>();

			DateTime april14 = new DateTime(2014, 4, 1);
			DateTime april15 = new DateTime(2015, 4, 1);
            DateTime april16 = new DateTime(2016, 4, 1);

            int countHausbesuchVorApril14 = 0;
			int countHausbesuchAbApril14 = 0;
			int countHausbesuchAbApril15 = 0;
            int countHausbesuchAbApril16 = 0;
            int countHausbesuchBg = 0;
			foreach (var sr in serviceRecordsInPeriod)
			{
				if (sr.ServiceDescription.Name.ToLower().Contains("hausbesuch"))
				{
					//String key = String.Format("{0:dd.MM.yyyy}", sr.Start);
					//if (!differentDays.ContainsKey(key))
					//	differentDays.Add(key, 1);
					if (sr.Start < april14)
						countHausbesuchVorApril14++;
					else if (sr.Start < april15)
						countHausbesuchAbApril14++;
                    else if (sr.Start < april16)
                        countHausbesuchAbApril15++;
                    else
                        countHausbesuchAbApril16++;
				}
				else if (sr.ServiceDescription.Name.ToLower().Contains("st bg hb"))
				{
					countHausbesuchBg++;
				}
			}

			if (countHausbesuchVorApril14 > 0)
			{
				var invoiceItem = new InvoiceItem();

				//decimal anzahlHausbesuche = differentDays.Count;
				decimal anzahlHausbesuche = countHausbesuchVorApril14;


				invoiceItem.AmountPerUnit = AMOUNTPERUNIT_HAUSBESUCH_VOR_APRIL_14;
				invoiceItem.UnitCount = anzahlHausbesuche;
				invoiceItem.AmountTotal = anzahlHausbesuche * AMOUNTPERUNIT_HAUSBESUCH_VOR_APRIL_14;
				invoiceItem.ItemPeriodStart = scap.StartDate;
				invoiceItem.ItemPeriodEnd = scap.EndDate;
				invoiceItem.RateFactor = null;
				invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
				invoiceItem.ItemDescription = "Hausbesuchspauschale";
				if (scap != null)
					invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;

				items.Add(invoiceItem);
			}
			if (countHausbesuchAbApril14 > 0)
			{
				var invoiceItem = new InvoiceItem();

				//decimal anzahlHausbesuche = differentDays.Count;
				decimal anzahlHausbesuche = countHausbesuchAbApril14;


				invoiceItem.AmountPerUnit = AMOUNTPERUNIT_HAUSBESUCH_AB_APRIL_14;
				invoiceItem.UnitCount = anzahlHausbesuche;
				invoiceItem.AmountTotal = anzahlHausbesuche * AMOUNTPERUNIT_HAUSBESUCH_AB_APRIL_14;
				invoiceItem.ItemPeriodStart = scap.StartDate;
				invoiceItem.ItemPeriodEnd = scap.EndDate;
				invoiceItem.RateFactor = null;
				invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
				invoiceItem.ItemDescription = "Hausbesuchspauschale";
				if (scap != null)
					invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;

				items.Add(invoiceItem);
			}
			if (countHausbesuchAbApril15 > 0)
			{
				var invoiceItem = new InvoiceItem();

				//decimal anzahlHausbesuche = differentDays.Count;
				decimal anzahlHausbesuche = countHausbesuchAbApril15;


				invoiceItem.AmountPerUnit = AMOUNTPERUNIT_HAUSBESUCH_AB_APRIL_15;
				invoiceItem.UnitCount = anzahlHausbesuche;
				invoiceItem.AmountTotal = anzahlHausbesuche * AMOUNTPERUNIT_HAUSBESUCH_AB_APRIL_15;
				invoiceItem.ItemPeriodStart = scap.StartDate;
				invoiceItem.ItemPeriodEnd = scap.EndDate;
				invoiceItem.RateFactor = null;
				invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
				invoiceItem.ItemDescription = "Hausbesuchspauschale";
				if (scap != null)
					invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;

				items.Add(invoiceItem);
			}
            if (countHausbesuchAbApril16 > 0)
            {
                var invoiceItem = new InvoiceItem();

                //decimal anzahlHausbesuche = differentDays.Count;
                decimal anzahlHausbesuche = countHausbesuchAbApril16;


                invoiceItem.AmountPerUnit = AMOUNTPERUNIT_HAUSBESUCH_AB_APRIL_16;
                invoiceItem.UnitCount = anzahlHausbesuche;
                invoiceItem.AmountTotal = anzahlHausbesuche * AMOUNTPERUNIT_HAUSBESUCH_AB_APRIL_16;
                invoiceItem.ItemPeriodStart = scap.StartDate;
                invoiceItem.ItemPeriodEnd = scap.EndDate;
                invoiceItem.RateFactor = null;
                invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
                invoiceItem.ItemDescription = "Hausbesuchspauschale";
                if (scap != null)
                    invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;

                items.Add(invoiceItem);
            }
            if (countHausbesuchBg > 0)
			{
				var invoiceItem = new InvoiceItem();

				//decimal anzahlHausbesuche = differentDays.Count;
				decimal anzahlHausbesuche = countHausbesuchBg;


				invoiceItem.AmountPerUnit = AMOUNTPERUNIT_HAUSBESUCH_BG;
				invoiceItem.UnitCount = anzahlHausbesuche;
				invoiceItem.AmountTotal = anzahlHausbesuche * AMOUNTPERUNIT_HAUSBESUCH_BG;
				invoiceItem.ItemPeriodStart = scap.StartDate;
				invoiceItem.ItemPeriodEnd = scap.EndDate;
				invoiceItem.RateFactor = null;
				invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
				invoiceItem.ItemDescription = "Hausbesuchspauschale";
				if (scap != null)
					invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;

				items.Add(invoiceItem);
			}
			return items;
		}
		
    }
}
