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

namespace SozialeDienstleistungenGessnerReports
{
	public class SDGDefaultInvoiceCreation : InvoiceCreation
	{
		public override List<ServiceInvoiceDC> GenerateServiceInvoices(long costBearerOid, DateTimeSpan invoicePeriod, Dictionary<CompactSupportConceptDC, List<ServiceRecordDC>> supportConcepts2ServiceRecords)
		{
			var costBearer = DAOFactory.GenericDAO.LoadByID<CostBearer>(costBearerOid);
			var result = new List<ServiceInvoiceDC>();
			var invoiceList = new List<ServiceInvoice>();

			int invoiceCounter = 0;

			foreach (var iSupportConcept2ServiceRecords in supportConcepts2ServiceRecords)
			{
				var splitList = SplitServiceRecordsToInvoiceType(iSupportConcept2ServiceRecords.Value);

				foreach (var data in splitList)
				{
					var invoice = CreateSingleInvoice(invoiceCounter, costBearer, invoicePeriod, iSupportConcept2ServiceRecords.Key, data.ServiceRecords);
					invoice.InvoiceBase.InvoiceId = data.InvoiceId;
					invoice.InvoiceBase.InvoiceTypeText = data.Title;
					invoiceList.Add(invoice);

					invoiceCounter++;	
				}
			}
			

			foreach (var item in invoiceList)
			{
				result.Add(MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(item));
			}
			if (result.Count > 1)
				return result.OrderBy(i => i.InvoiceBase.CustomerLastName).ToList();
			else
				return result;
		}


		private IList<SDGInvoiceData> SplitServiceRecordsToInvoiceType(List<ServiceRecordDC> allRecords)
		{
			IList<SDGInvoiceData> result = new List<SDGInvoiceData>();

			List<ServiceRecordDC> besonderePsyHilfenArbeit = null;
			List<ServiceRecordDC> indPersoenlBudget = null;
			List<ServiceRecordDC> pflege = null;
			List<ServiceRecordDC> bewo = null;

			foreach (var sr in allRecords)
			{
				var cat = sr.ServiceDescription.CategoryName.ToLower();

				if (cat.StartsWith("arbeit") || cat.StartsWith("besondere psycho"))
				{
					if (besonderePsyHilfenArbeit == null)
					{
						besonderePsyHilfenArbeit = new List<ServiceRecordDC>();
					}
					besonderePsyHilfenArbeit.Add(sr);
				}
				else if (cat.StartsWith("individuelle hilfen"))
				{
					if (indPersoenlBudget == null)
					{
						indPersoenlBudget = new List<ServiceRecordDC>();
					}
					indPersoenlBudget.Add(sr);
				}
				else if (cat.Contains("alltagskompetenz"))
				{
					if (pflege == null)
					{
						pflege = new List<ServiceRecordDC>();
					}
					pflege.Add(sr);
				}
				else
				{
					if (bewo == null)
					{
						bewo = new List<ServiceRecordDC>();
					}
					bewo.Add(sr);
				}
			}

			if (besonderePsyHilfenArbeit != null)
			{
				result.Add(new SDGInvoiceData
				{
					Title = "Persönliches Budget",
					InvoiceId = "PB-BesonderePsyHilfenArbeitBeschaeftigung",
					ServiceRecords = besonderePsyHilfenArbeit
				});
			}
			if (indPersoenlBudget != null)
			{
				result.Add(new SDGInvoiceData
				{
					Title = "Persönliches Budget-Individuelle Hilfen",
					InvoiceId = "PB-IndHilfen",
					ServiceRecords = indPersoenlBudget
				});
			}
			if (pflege != null)
			{
				result.Add(new SDGInvoiceData
				{
					Title = "Pflegegeld",
					InvoiceId = "Pflegegeld",
					ServiceRecords = pflege
				});
			}
			if (bewo != null)
			{
				result.Add(new SDGInvoiceData
				{
					Title = "Betreutes Wohnen",
					InvoiceId = "Betreutes Wohnen",
					ServiceRecords = bewo
				});
			}
			return result;
		}

		public override IList<InvoiceItem> CreateSummaryInvoiceItems(IList<InvoiceItem> itemList, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap,
			Calculations calc)
		{
			var items = base.CreateSummaryInvoiceItems(itemList, invoicePeriod, scap, calc);

			if (itemList.Count > 0)
			{
				foreach (var invoiceItem in itemList)
				{
					if (invoiceItem.ServiceRecord != null)
					{
						foreach (var item in items)
						{
							item.ItemDescription = invoiceItem.ServiceRecord.ServiceDescription.ServiceCategory.Name;
						}
					}
				}
			}
			return items;
		}
	}

	

	internal class SDGInvoiceData
	{
		public String InvoiceId { get; set; }
		public String Title { get; set; }
		public List<ServiceRecordDC> ServiceRecords { get; set; }
	}
}
