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

namespace BeWo.LebenshilfeWuerzburgReports
{
	public partial class Hilfeplanuebersicht : DevExpress.XtraReports.UI.XtraReport, IBeWoReport<QueryRO>
	{

		public Hilfeplanuebersicht()
		{
			InitializeComponent();
		}

		public void SetReportDataSource(QueryRO pRO)
		{

			this.bindingSource1.DataSource = CreateDataSource(pRO);
		}

		private QueryRO CreateDataSource(QueryRO queryRo)
		{
			bool showArchived = queryRo.Rows.Count > 0 && queryRo.Rows[0].Field1 != null && queryRo.Rows[0].Field1.ToString() == "1";

			DateTime? appointedDate = null;
			DateTime adOut = DateTime.Now.Date;
			DateTime adMaxNow = DateTime.Now.Date;
			if (queryRo.Rows.Count > 0 && queryRo.Rows[0].Field2 != null &&
			    DateTime.TryParse(queryRo.Rows[0].Field2.ToString(), out adOut))
			{

				adMaxNow = adOut.Date;

				adMaxNow = adMaxNow.AddMonths(1).AddDays(-1).Date;

				appointedDate = adMaxNow;
				
			}

			QueryRO newQueryRo = new QueryRO();
			QueryRO.Row row = new QueryRO.Row();
			row.ChildRows1 = new List<QueryRO.Row>();
			newQueryRo.Rows.Add(row);

			IList<SupportConcept> list = null;
			if (!showArchived)
				list = DAOFactory.GenericDAO.GetAllActive<SupportConcept>();
			else
				list = DAOFactory.GenericDAO.GetAllWithActivationType<SupportConcept>(ActivationTypeId.Archived);
				
			
			Dictionary<long, bool> c2sOids = new Dictionary<long, bool>();

			decimal summeGesamt = 0;
			decimal summeBewilligt = 0;
			decimal summeDirect = 0;
			decimal summeIndirect = 0;
			decimal summeHilfskraft = 0;
			
			foreach (SupportConcept sc in list)
			{
				if (sc.CostBearer2SupportConceptList != null && sc.CostBearer2SupportConceptList.Count > 0)
				{
					foreach (CostBearer2SupportConcept cb2sc in sc.CostBearer2SupportConceptList)
					{
						if ((cb2sc.StartDate.HasValue && cb2sc.StartDate.Value.Date <= adMaxNow) && !c2sOids.ContainsKey(cb2sc.Oid.Value))
						{

							QueryRO.Row detailRow = new QueryRO.Row();
							row.ChildRows1.Add(detailRow);
							DateTime? start = cb2sc.StartDate;
							DateTime? end = cb2sc.EndDate;

							StringBuilder sb = new StringBuilder();

							if (start != null && start.Value > DateTime.MinValue)
							{
								sb.Append(String.Format("{0:dd.MM.yy}", start));
							}

							if (start != null || end != null)
							{
								sb.Append(" - ");
							}

							if (end != null && end.Value < DateTime.MaxValue)
							{
								sb.Append(String.Format("{0:dd.MM.yy}", end));
							}


							detailRow.Field1 = String.Format("{0}, {1}", sc.Customer.Person.LastName, sc.Customer.Person.FirstName);
							detailRow.Field2 = sb.ToString();

							var calc = Calculations.GetInstance(cb2sc.CostBearer.ID);
							var relDc = MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(cb2sc);
							
							var serviceRecords = DAOFactory.SearchDAO.FindServiceRecordsDetailsForLastDays(cb2sc.Oid.Value, null);
							Dictionary<long, bool> serviceRecordsProcessed = new Dictionary<long, bool>();


							decimal direct = 0;
							decimal indirect = 0;
							decimal hilfskraft = 0;

							
							//Alle nicht archivierten+
							//		2.Liste alle archivierten

							//Gesamtsummen am Ende

							//Nur Administratoren
							//ServiceCategory:
							//Direkte Leistung OID=7
							//Indirekte Leistung OID=9

							//ServiceDescription:
							//Direkte Zeit HK OID =54
							foreach (var sr in serviceRecords)
							{
								
								if (!serviceRecordsProcessed.ContainsKey(sr.Oid.Value) && (!appointedDate.HasValue || sr.Start.Value < appointedDate.Value.Date.AddDays(1)))
								{
									
									bool isIndirect = false;
									if (sr.ServiceDescription != null && sr.ServiceDescription.ServiceCategory != null)
									{
										isIndirect = sr.ServiceDescription.ServiceCategory.Oid.Value == 9;
									}
									
									
									var minutes = GetBillableDurationInMinutes(sr);
									
									
									if (isIndirect)
									{
										indirect += minutes;
									}
									else
									{
										direct += minutes;
									}
									if (sr.ServiceDescription.Oid == 54)
									{
										hilfskraft += minutes;
									}
									
									serviceRecordsProcessed.Add(sr.Oid.Value, true);
								}
							}

							//Gesamtstunden
							decimal totalMinutes = direct + indirect;
							detailRow.Field3 = String.Format("{0:0.00}", totalMinutes / 60);
							summeGesamt += totalMinutes;

							//Stunden/Woche
						
							//decimal anzahlWochen = calc.GetDurationInWeeks(relDc) ?? 0;
							DateTime now = adMaxNow;
							if (DateTime.Now.Date < adMaxNow)
								now = DateTime.Now;

							decimal anzahlWochenBisHeute = calc.GetDurationInWeeksTillNow(relDc, now) ?? 0;
							decimal istProWoche = 0;
							
							if (anzahlWochenBisHeute > 0)
								istProWoche = (totalMinutes/anzahlWochenBisHeute)/60;

							detailRow.Field4 = String.Format("{0:0.00}", istProWoche);
							
							//Genehmigte Stunden
							var hoursApproved = (calc.GetApprovedHoursPerWeekAverage(relDc, true) ?? 0m);
							detailRow.Field5 = String.Format("{0:0.00}", hoursApproved);

							detailRow.Field9 = String.Format("{0:0.00}", istProWoche - hoursApproved);

							//Direkte Leistung
							detailRow.Field6 = String.Format("{0:0.00}", direct / 60);
							summeDirect += direct;
							

							//Indirekte Leistung
							detailRow.Field7 = String.Format("{0:0.00}", indirect / 60);
							summeIndirect += indirect;

							//Direkte Leistung in %
							if (totalMinutes > 0)
								detailRow.Field8 = String.Format("{0:0.00}", (direct * 100) / totalMinutes);
							else
								detailRow.Field8 = String.Format("{0:0.00}", 0);
							

							////Fachkraft
							//detailRow.Field9 = String.Format("{0:0.00}", (totalMinutes - hilfskraft) / 60);
							
							////Hilfskraft
							//detailRow.Field10 = String.Format("{0:0.00}", hilfskraft / 60);
							summeHilfskraft += hilfskraft;

							//Fachkraft in %
							if (totalMinutes > 0)
								detailRow.Field11 = String.Format("{0:0.00}", ((totalMinutes - hilfskraft) * 100) / totalMinutes);
							else
								detailRow.Field11 = String.Format("{0:0.00}", 0);

							String hauptbetreuer = String.Empty;
							Customer c = sc.Customer;
							foreach (var e2c in c.Employee2CustomerList)
							{
								foreach (var valueEntry in e2c.ValueList)
								{
									if (valueEntry.Entry.SystemEntryID != null && valueEntry.Entry.SystemEntryID.Value == SystemEntryID.EmployeeRoleMainAttendant)
									{
										var empName = e2c.Employee.Person.FirstName + " " + e2c.Employee.Person.LastName;
										if (String.IsNullOrEmpty(hauptbetreuer))
											hauptbetreuer = empName;
										else
										{
											if (!hauptbetreuer.Contains(empName))
											{
												hauptbetreuer += ", " + empName;
											}
										}

									}
								}
							}
							
							detailRow.Field12 = hauptbetreuer;

							c2sOids.Add(cb2sc.Oid.Value, true);
						}
					}
				}
			}
			//lblGesamt.Text = String.Format("{0:0.00}", summeGesamt / 60);
			//lblGenehmigt.Text = String.Format("{0:0.00}", summeGenehmigt);
			//lblDirect.Text = String.Format("{0:0.00}", summeDirect / 60);
			//lblIndirect.Text = String.Format("{0:0.00}", summeIndirect / 60);
			decimal directPercent = 0;
			decimal fachkraftPercent = 0;

			if (summeGesamt != 0)
			{
				directPercent = (summeDirect*100)/summeGesamt;
				fachkraftPercent = ((summeGesamt - summeHilfskraft)*100)/summeGesamt;
			}
			lblDirectPercent.Text = String.Format("{0:0.00}", directPercent);
			//lblFachkraft.Text = String.Format("{0:0.00}", (summeGesamt - summeHilfskraft) / 60);
			//lblHilfskraft.Text = String.Format("{0:0.00}", summeHilfskraft / 60);
			lblFachkraftPercent.Text = String.Format("{0:0.00}", fachkraftPercent);

			foreach (var r in newQueryRo.Rows)
			{
				r.ChildRows1.Sort((a, b) => a.Field1.ToString().CompareTo(b.Field1));

			}
			newQueryRo.Rows.Sort((a, b) => a.Field2.ToString().CompareTo(b.Field2));

			return newQueryRo;
		}

		private decimal GetBillableDurationInMinutes(ServiceRecord record)
		{
			decimal rdMinutes = record.RoundedDuration;
			if (record.ServiceDescription.ServiceCategory.Percentage != 100)
			{
				rdMinutes = (rdMinutes * record.ServiceDescription.ServiceCategory.Percentage) / 100;
			}
			if (record.GroupEmployeeCount.HasValue)
				rdMinutes /= record.GroupEmployeeCount.Value;

			return rdMinutes;
		}

	}
	
}
