using System;
using System.Collections.Generic;
using System.Linq;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Report;
using BeWo.Report.ReportObjects;
using BS.Shared;
using BS.Shared.Core;
using DevExpress.XtraPrinting;
using DevExpress.XtraReports.UI;

namespace BloemelingUndTeckhaus
{
    public partial class ServiceInvoiceReport : XtraReport, IBeWoReport<ServiceInvoiceRO>
    {
	    private int mEinheitenTotal = 0;

		public List<SoziotherapieRow> SoziotherapieRowList { get; set; }

        public ServiceInvoiceReport()
        {
            InitializeComponent();
        }

        public void SetReportDataSource(ServiceInvoiceRO pRO)
        {
	        var allServiceInvoiceItems = new List<ServiceInvoiceItemRO>();
			pRO.ServiceInvoicePeriods.ForEach(f => allServiceInvoiceItems.AddRange(f.ServiceInvoiceItems));

			//decimal? unitSum = 0;
			//pRO.ServiceInvoicePeriods.ForEach(fe => fe.ServiceInvoiceItems.ForEach(f => unitSum += f.UnitCount));

			//xrTableCell123.Text = unitSum.ToString();

			BuildSoziotherapieRow(pRO, allServiceInvoiceItems);

	        var firstRow = SoziotherapieRowList.FirstOrDefault();

	        if (firstRow != null)
	        {
				var fr = xrTable3.Rows[0];
				fr.Cells[0].Text = firstRow.Title;
				for (var i = 1; i <= firstRow.Days.Length; i++)
				{
					var units = firstRow.Days[i - 1];
					xrTable3.Rows[0].Cells[i].Text = units == 0 ? String.Empty : "X";
					xrTable3.Rows[1].Cells[i].Text = units == 0 ? String.Empty : units.ToString();
				}

		        if (SoziotherapieRowList.Count > 1)
		        {
			        for (var j = 1; j < SoziotherapieRowList.Count; j++)
			        {
				        var obj = SoziotherapieRowList[j];

						var newRow1 = xrTable3.InsertRowBelow(xrTable3.Rows[xrTable3.Rows.Count - 1]);
				        var newRow2 = xrTable3.InsertRowBelow(newRow1);

				        newRow1.Height = xrTable3.Rows[0].Height;
						newRow2.Height = xrTable3.Rows[1].Height;

				        newRow1.Cells[0].Text = obj.Title;
						newRow1.Cells[0].Padding = xrTable3.Rows[1].Cells[0].Padding;
						newRow2.Cells[0].Text = "Therapieeinh.";
				        newRow2.Cells[0].TextAlignment = xrTable3.Rows[0].TextAlignment;
						newRow2.Cells[0].Padding = xrTable3.Rows[1].Cells[0].Padding;


						// 0 -> Therapieeinh.
						// 1 -> 1.
						for (var i = 1; i <= obj.Days.Length; i++)
						{
							var units = obj.Days[i - 1];
							
							newRow1.Cells[i].Text = units == 0 ? String.Empty : "X";
							newRow1.Cells[i].TextAlignment = TextAlignment.MiddleCenter;
							newRow1.Cells[i].Padding = xrTable3.Rows[0].Cells[1].Padding;

							newRow2.Cells[i].Text = units == 0 ? String.Empty : units.ToString();
							newRow2.Cells[i].TextAlignment = TextAlignment.MiddleCenter;
							newRow2.Cells[i].Padding = xrTable3.Rows[0].Cells[1].Padding;
						}
			        }
		        }
	        }

	        var period = pRO.ServiceInvoicePeriods.FirstOrDefault(f => f.Customer != null && f.Customer.Oid != null);

			if (period != null && period.Customer != null && period.Customer.Oid != null)
			{
				var fod = period.ServiceInvoiceItems.FirstOrDefault();
				if (fod != null && fod.AmountPerUnit != null)
				{
					cellBetragJeStunden.Text = fod.AmountPerUnit.Value.ToString("0.00 €");
				}

				
	        }
	        cellAnzahlEinheitenGesamt.Text = String.Format("{0:0}", mEinheitenTotal);

	        SetAnbieterFields(pRO);
			SetVarFields(pRO);
	        SetZwischenEndabrechnung(pRO);
	        bindingSource1.DataSource = pRO;
        }

		private void SetZwischenEndabrechnung(ServiceInvoiceRO pRO)
		{
			bool isZwischen = true;
			if (pRO.ServiceInvoicePeriods != null && pRO.ServiceInvoicePeriods.Count > 0)
			{
				var sip = pRO.ServiceInvoicePeriods[0];
				if (sip.CostBearer2SupportConcept != null)
				{
					if (pRO.AccountingPeriodEnd >= sip.CostBearer2SupportConcept.EndDate)
					{
						isZwischen = false;
					}
				}
			}

			zwischenabrechnungsCB.Checked = isZwischen;
			endabrechnungsCB.Checked = !isZwischen;
		}

		private void SetAnbieterFields(ServiceInvoiceRO pRO)
		{
			var cust = GetCustomer(pRO);
			if (cust != null)
			{
				//foreach (var valueEntry in item.ValueList)
				//	{
				//		if (valueEntry.Entry.SystemEntryID != null && valueEntry.Entry.SystemEntryID.Value == SystemEntryID.EmployeeRoleMainAttendant)
				//		{
				var hauptbetreuer =
					cust.Employee2CustomerList.FirstOrDefault(
						e2c => e2c.ValueList.Any(ve => ve.Entry.SystemEntryID.HasValue && ve.Entry.SystemEntryID.Value == SystemEntryID.EmployeeRoleMainAttendant));
				if (hauptbetreuer != null && hauptbetreuer.Employee.Person.LastName == "Blömeling")
				{
					lblAddress.Text = "M.Blömeling, Bahnhofstr. 16-18, 51143 Köln";
					cellKontoInhaber.Text = "Michaela Blömeling";
					cellIKNr.Text = "490 534 083";
				}
			}
		}

		private void SetVarFields(ServiceInvoiceRO pRO)
	    {
			var c = GetCustomer(pRO);
			if (c == null)
			{
				return;
			}
			foreach (var vv in c.VarFieldValueList)
			{
				var varFieldValue = Utils.XMLDeserializeFromString(vv.SerializedValue, Type.GetType(vv.TypeName));
				if (varFieldValue != null)
				{
					var vValue = varFieldValue.ToString();

					switch (vv.VarFieldDefOid)
					{
						case 1:
							kassennrLabel.Text = vValue;
							break;
						case 2:
							versichertennrLabel.Text = vValue;
							break;
						case 3:
							statusLabel.Text = vValue;
							break;
						case 4:
							vertragsarztNrLabel.Text = vValue;
							break;
						case 5:
							vkGueltigBisLabel.Text = ((DateTime)varFieldValue).ToShortDateString();
							break;
						case 6:
							cellBeginn.Text = ((DateTime)varFieldValue).ToShortDateString();
							break;
						case 7:
							cellBeendigung.Text = ((DateTime)varFieldValue).ToShortDateString();
							break;
						case 8:
							chkPlanmaessig.Checked = (bool)varFieldValue;
							break;
						case 9:
							if (!String.IsNullOrEmpty(vValue))
							{
								chkAbbruch.Checked = true;
								chkAbbruch.Text = vValue;
							}
							
							break;
					}
				}
			}
	    }

	    private Customer GetCustomer(ServiceInvoiceRO pRO)
	    {
		    if (pRO.ServiceInvoicePeriods != null && pRO.ServiceInvoicePeriods.Count > 0)
		    {
			    var sip = pRO.ServiceInvoicePeriods[0];
			    if (sip.Customer != null)
			    {
				    return DAOFactory.GenericDAO.LoadByID<Customer>(sip.Customer.CustomerOid);
			    }
		    }
			

		    return null;
	    }

		public void BuildSoziotherapieRow(ServiceInvoiceRO pRO, IEnumerable<ServiceInvoiceItemRO> serviceItems)
	    {
			SoziotherapieRowList = new List<SoziotherapieRow>();

			DateTime start = pRO.AccountingPeriodStart;

			while (start < pRO.AccountingPeriodEnd)
			{
				var title = String.Format("{0}. {1}", start.ToString("MMM"), start.ToString("yy"));
				SoziotherapieRowList.Add(new SoziotherapieRow { Title = title });
				start = start.AddMonths(1);
			}

			foreach (var item in serviceItems)
			{
				if (!item.AccountingPeriodStart.HasValue) continue;

				var date = item.AccountingPeriodStart.Value;
				var title = String.Format("{0}. {1}", date.ToString("MMM"), date.ToString("yy"));
				
				if (!SoziotherapieRowList.Any(a => a.Title.Equals(title)))
				{
					SoziotherapieRowList.Add(new SoziotherapieRow { Title = title });
				}

				var row = SoziotherapieRowList.First(f => f.Title.Equals(title));

				int volleStunden = 0;
				if (item.Hours.HasValue)
				{
					volleStunden = (int)Math.Floor(item.Hours.Value);
				}

				row.Days[item.AccountingPeriodStart.Value.Day - 1] += volleStunden;

				mEinheitenTotal += volleStunden;
			}
	    }
    }

	public class SoziotherapieRow
	{
		public String Title { get; set; }

		public int[] Days { get; set; }

		public SoziotherapieRow()
		{
			Title = string.Empty;
			Days = new int[31];
		}
	}
}