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

namespace LHDuisburg.Invoicing
{
	public class LHDuisburgDefaultInvoiceCreation : InvoiceCreation
	{
		private DateTime? accountingPeriodStart = null;
		private DateTime? accountingPeriodEnd = null;

		//public override void CheckMaxApprovedAmount(ServiceInvoice invoice, ServiceInvoicePeriod sip, SupportConceptApprovalPeriodDC scap,
		//	CostBearer2SupportConcept costBearer2SupportConcept, DateTimeSpan invoicePeriod, List<ServiceRecordDC> serviceRecords)
		//{
		//	// do nothing base.CheckMaxApprovedAmount(invoice, sip, scap, costBearer2SupportConcept, invoicePeriod, serviceRecords);
		//}

		public override void SetInvoiceBaseData(int invoiceCounter, ServiceInvoice invoice, CostBearer costBearer, DateTimeSpan invoicePeriod,
			IList<CompactSupportConceptDC> supportConceptList)
		{
			if (invoicePeriod != null)
			{
				accountingPeriodStart = invoicePeriod.StartDate;
				accountingPeriodEnd = invoicePeriod.EndDate;
			}
			base.SetInvoiceBaseData(invoiceCounter, invoice, costBearer, invoicePeriod, supportConceptList);
		}

		public override void SetSingleInvoiceBaseData(int invoiceCounter, ServiceInvoice invoice, CostBearer costBearer,
			DateTimeSpan invoicePeriod, CompactSupportConceptDC supportConcept)
		{
			base.SetSingleInvoiceBaseData(invoiceCounter, invoice, costBearer, invoicePeriod, supportConcept);

			Person p = invoice.InvoiceBase.CostBearer2SupportConcept.SupportConcept.Customer.Person;
			invoice.InvoiceBase.InvoiceTitle = String.Format("{0}, {1}, {2}", invoice.InvoiceBase.RecipientOrganisation, p.LastName, p.FirstName);
		}

		public override IList<InvoiceItem> CreateInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap, Calculations calc)
		{
			if (!accountingPeriodStart.HasValue)
				accountingPeriodStart = scap.StartDate;
			if (!accountingPeriodEnd.HasValue)
				accountingPeriodEnd = scap.EndDate;

			Dictionary<String, InvoiceItem> category2InvoiceItems = new Dictionary<string, InvoiceItem>();
			foreach (var iServiceRecord in serviceRecordsInPeriod)
			{
				if (iServiceRecord.ServiceDescription.Category.IsBillable)
				{
					if (!iServiceRecord.AlreadyAccounted)
					{
						String cat = "";
						if (!String.IsNullOrEmpty(iServiceRecord.ServiceDescription.Category.Name))
							cat = iServiceRecord.ServiceDescription.Category.Name.ToLower().Trim();

						var tempii = CreateInvoiceItem(iServiceRecord, scap, calc);
						tempii.ItemPeriodStart = accountingPeriodStart;
						tempii.ItemPeriodEnd = accountingPeriodEnd;

						CreateItemTextForCategory(tempii, cat);

						String key = String.Format("{0}_{1}_{2:0.00}_{3:0.00}", tempii.ItemDescription, tempii.Notice, tempii.AmountPerUnit, tempii.RateFactor);

						if (category2InvoiceItems.ContainsKey(key))
						{
							var ii = category2InvoiceItems[key];
							ii.UnitCount += tempii.UnitCount;
						}
						else
						{
							category2InvoiceItems.Add(key, tempii);
						}
						iServiceRecord.AlreadyAccounted = true;
					}
				}
			}

			IList<InvoiceItem> returnList = category2InvoiceItems.Values.ToList();
			foreach (var ii in returnList)
			{
				ii.UnitCount = Math.Round(ii.UnitCount.Value, 2, MidpointRounding.AwayFromZero);
				ii.AmountTotal = ii.UnitCount.Value * ii.AmountPerUnit;

				ii.GrossAmountTotal = ii.AmountTotal;

				if (ii.RateFactor.HasValue)
					ii.GrossAmountTotal = Math.Round(ii.GrossAmountTotal.Value, 2, MidpointRounding.AwayFromZero) * ((100m + ii.RateFactor) / 100m);
				
				
			}
			return returnList;
		}

		private void CreateItemTextForCategory(InvoiceItem ii, string cat)
		{
			ii.ItemDescription = cat;
			if (cat == "direkte Betreuungsleistung")
			{
				ii.ItemDescription = "Fachleistungsstunden";
				ii.Notice = "Direkte Betreuungsleistungen, Ambulant Betreutes Wohnen";
			}
			else if (cat == "assistenzleistungen")
			{
				ii.ItemDescription = "Assistenzleistung";
				ii.Notice = "Direkte Betreuungsleistungen, Ambulant Betreutes Wohnen";
			}
			else if (cat == "leistungsmodul hintergrunddienst")
			{
				ii.ItemDescription = "Leistungsmodul Hintergrunddienst";
				ii.Notice = "Direkte Betreuungsleistungen, Ambulant Betreutes Wohnen";
			}
			else if (cat == "leistungsmodul serviceorientiert")
			{
				ii.ItemDescription = "Leistungsmodul Serviceorientiert";
				ii.Notice = "Direkte Betreuungsleistungen, Ambulant Betreutes Wohnen";
			}
			else if (cat == "eb (face to face)" || cat == "ohne klient (eb)")
			{
				ii.ItemDescription = "Leistung nach dem SGB VIII (Hilfe zur Erziehung)";
				ii.Notice = "Erziehungsbeistand";
			}
			else if (cat == "hpff-fördereinheit")
			{
				ii.ItemDescription = "Fördereinheiten HP-FF";
				ii.Notice = "";
			}
			else if (cat == "hpfh betreuung (face to face)" || cat == "ohne klient (hpfh)")
			{
				ii.ItemDescription = "Leistung nach dem SGB VIII (Hilfe zur Erziehung)";
				ii.Notice = "Sozialpädagogische Familienhilfe mit heilpädagogischer Ausrichtung";
			}
			else if (cat == "iff-diagn.")
			{
				ii.ItemDescription = "Förderdiagnostik IFF";
				ii.Notice = "";
			}
			else if (cat == "iff-fördereinheit")
			{
				ii.ItemDescription = "Fördereinheiten IFF";
				ii.Notice = "";
			}
			else if (cat == "stabifam (face to face)" || cat == "ohne klient (stabifam)")
			{
				ii.ItemDescription = "Leistung nach dem SGB VIII (Hilfe zur Erziehung)";
				ii.Notice = "Stabilisierende Familienhilfe";
			}
			else if (cat.IndexOf("hpfh") >= 0)
			{
				ii.ItemDescription = "Leistung nach dem SGB VIII (Hilfe zur Erziehung)";
				ii.Notice = "Sozialpädagogische Familienhilfe mit heilpädagogischer Ausrichtung";
			}
			else if (cat == "tbt (zb)")
			{
				ii.ItemDescription = "Leistung nach dem SGB XI";
				ii.Notice = "zusätzliche Betreuungsleistung";
			}
			else if (cat == "tbt (vp)")
			{
				ii.ItemDescription = "Leistung nach dem SGB XI";
				ii.Notice = "Verhinderungspflege";
			}
			else
			{
				ii.ItemDescription = cat;
				ii.Notice = "";
			}
		}

		public override InvoiceItem CreateInvoiceItem(ServiceRecordDC iServiceRecord, SupportConceptApprovalPeriod scap, Calculations calc)
		{
			var invoiceItem = new InvoiceItem();

			var bd = calc.GetBillingData(iServiceRecord);

			invoiceItem.AmountPerUnit = bd.AmountPerUnit ?? 0;
			invoiceItem.UnitCount = bd.UnitCount ?? 0;
			invoiceItem.AmountTotal = bd.AmountTotal ?? 0;
			invoiceItem.ItemPeriodStart = bd.BillingPeriodStart;
			invoiceItem.ItemPeriodEnd = bd.BillingPeriodEnd;
			invoiceItem.RateFactor = bd.RateFactor ?? 0;
			invoiceItem.GrossAmountTotal = bd.GrossAmountTotal;
			invoiceItem.AccountingInterval = bd.AccountingInterval;
			
			if (scap != null)
				invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;

			return invoiceItem;
		}

		
    }
}
