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 VSDHammReports
{
	public partial class Forderungen : DevExpress.XtraReports.UI.XtraReport, IBeWoReport<QueryRO>
	{

		public Forderungen()
		{
			InitializeComponent();
		}

		public void SetReportDataSource(QueryRO pRO)
		{

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

		private QueryRO CreateDataSource(QueryRO queryRo)
		{
			QueryRO newQueryRo = new QueryRO();

			AccountingServiceImp ai = new AccountingServiceImp();
			OperationsServiceImp oi = new OperationsServiceImp();
			IList<SupportConcept> list = DAOFactory.GenericDAO.GetAllActive<SupportConcept>();

			Dictionary<long, bool> c2sOids = new Dictionary<long, bool>();

			Summen gesamtSummen = new Summen();
			
			Dictionary<String, QueryRO.Row> orgName2RowDict = new Dictionary<string, QueryRO.Row>();
			Dictionary<String, Summen> summe2RowDict = new Dictionary<string, Summen>();

			foreach (SupportConcept sc in list)
			{
				//var settlementIncoices = ai.GetSettlementInvoicesForSupportConcept(sc.Oid.Value);
				//var equityInvoices = ai.GetInvoiceBasesForSupportConcept(InvoiceType.CustomerEquity, sc.Oid.Value);

				if (sc.CostBearer2SupportConceptList != null && sc.CostBearer2SupportConceptList.Count > 0)
				{
					foreach (CostBearer2SupportConcept cb2sc in sc.CostBearer2SupportConceptList)
					{

						if (!c2sOids.ContainsKey(cb2sc.Oid.Value))
						{
							QueryRO.Row detailRow = new QueryRO.Row();

							DateTime? start = cb2sc.StartDate;
							DateTime? end = cb2sc.EndDate;

							StringBuilder sb = new StringBuilder();

							if (start != null)
							{
								sb.Append(start.Value.ToShortDateString());
							}

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

							if (end != null)
							{
								sb.Append(end.Value.ToShortDateString());
							}


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

							String kostentraeger = "";
							if (cb2sc.CostBearer.Organisation != null)
								kostentraeger = cb2sc.CostBearer.Organisation.Name;

							QueryRO.Row kostenTraegerRow = null;
							Summen summenBewilligt = null;
							Summen summenNichtBewilligt = null;
							if (!orgName2RowDict.ContainsKey(kostentraeger))
							{
								kostenTraegerRow = new QueryRO.Row();
								kostenTraegerRow.ChildRows1 = new List<QueryRO.Row>();
								kostenTraegerRow.ChildRows2 = new List<QueryRO.Row>();
								kostenTraegerRow.Field2 = kostentraeger; //String.Format("{0}, {1}", emp.Person.LastName, emp.Person.FirstName);
								newQueryRo.Rows.Add(kostenTraegerRow);

								orgName2RowDict.Add(kostentraeger, kostenTraegerRow);

								summenBewilligt = new Summen();
								summenNichtBewilligt = new Summen();
								summe2RowDict.Add(kostentraeger + "_bewilligt", summenBewilligt);
								summe2RowDict.Add(kostentraeger + "_nichtbewilligt", summenNichtBewilligt);
							}
							else
							{
								kostenTraegerRow = orgName2RowDict[kostentraeger];
								summenBewilligt = summe2RowDict[kostentraeger + "_bewilligt"];
								summenNichtBewilligt = summe2RowDict[kostentraeger + "_nichtbewilligt"];
							}

							var si = oi.GenerateInitialSettlementDC(cb2sc.Oid.Value);

							decimal rechnungsbetrag = si.AmountBillableTotal ?? 0;
							rechnungsbetrag = Math.Round(rechnungsbetrag, 2, MidpointRounding.AwayFromZero);

							detailRow.Field2 = String.Format("{0:c}", rechnungsbetrag);


							//Bereit bezahlt
							if (!start.HasValue)
								start = DateTime.MinValue;
							if (!end.HasValue)
								end = DateTime.MaxValue;
							decimal payments = 0;

							var bookingList = cb2sc.AccountingTransactions;
							
							foreach (var item in bookingList)
							{
								payments += item.Amount;
							}
							payments = Math.Round(payments, 2, MidpointRounding.AwayFromZero);

							var test = si.AmountAdvancedPayments;

							//decimal equityPayments = 0;
							//if (equityInvoices != null && equityInvoices.Count > 0)
							//{
							//    foreach (var equityInvoice in equityInvoices)
							//    {
							//        //if (equityInvoice.SupportConceptCostBearerRelDc != null && equityInvoice.SupportConceptCostBearerRelDc.CostBearer2SupportConceptOid == cb2sc.Oid)
							//            equityPayments += equityInvoice.TotalAmount ?? 0;
							//        equityInvoice.TotalAmount = 0;
							//    }
							//}
							//equityPayments = Math.Round(equityPayments, 2, MidpointRounding.AwayFromZero);

							payments += si.EquityContribution ?? 0;

							detailRow.Field3 = String.Format("{0:c}", payments);

							decimal forderung = 0;
							decimal verbindlichkeit = 0;

							if (rechnungsbetrag > payments)
								forderung = rechnungsbetrag - payments;
							else
								verbindlichkeit = payments - rechnungsbetrag;


							detailRow.Field4 = String.Format("{0:c}", Math.Round(forderung, 2, MidpointRounding.AwayFromZero));
							detailRow.Field5 = String.Format("{0:c}", Math.Round(verbindlichkeit, 2, MidpointRounding.AwayFromZero));

							

							if (!cb2sc.ApprovedStartDate.HasValue || !cb2sc.ApprovedEndDate.HasValue)
							{
								kostenTraegerRow.ChildRows2.Add(detailRow); //nicht bewilligt
								summenNichtBewilligt.Forderungen += forderung;
								summenNichtBewilligt.Verbindlichkeiten += verbindlichkeit;
							}
							else
							{
								kostenTraegerRow.ChildRows1.Add(detailRow); //bewilligt
								summenBewilligt.Forderungen += forderung;
								summenBewilligt.Verbindlichkeiten += verbindlichkeit;
							}

							gesamtSummen.Forderungen += forderung;
							gesamtSummen.Verbindlichkeiten += verbindlichkeit;

							c2sOids.Add(cb2sc.Oid.Value, true);
						}
					}
				}
			}

			lblSummeForderungen.Text = String.Format("{0:c}", gesamtSummen.Forderungen);
			lblSummeVerbindlichkeiten.Text = String.Format("{0:c}", gesamtSummen.Verbindlichkeiten);

			decimal saldoForderungen = 0;
			decimal saldoVerbindlichkeiten = 0;

			if (gesamtSummen.Forderungen > gesamtSummen.Verbindlichkeiten)
				saldoForderungen = gesamtSummen.Forderungen - gesamtSummen.Verbindlichkeiten;
			else
				saldoVerbindlichkeiten = gesamtSummen.Verbindlichkeiten - gesamtSummen.Forderungen;

			lblSaldoForderungen.Text = String.Format("{0:c}", saldoForderungen);
			lblSaldoVerbindlichkeiten.Text = String.Format("{0:c}", saldoVerbindlichkeiten);


			foreach (var key in orgName2RowDict.Keys)
			{
				var row = orgName2RowDict[key];
				var summenBewilligt = summe2RowDict[key + "_bewilligt"];
				var summenNichtBewilligt = summe2RowDict[key + "_nichtbewilligt"];

				//Bewilligte Gesamtsummen
				row.Field3 = String.Format("{0:c}", summenBewilligt.Forderungen);
				row.Field4 = String.Format("{0:c}", summenBewilligt.Verbindlichkeiten);

				saldoForderungen = 0;
				saldoVerbindlichkeiten = 0;

				if (summenBewilligt.Forderungen > summenBewilligt.Verbindlichkeiten)
					saldoForderungen = summenBewilligt.Forderungen - summenBewilligt.Verbindlichkeiten;
				else
					saldoVerbindlichkeiten = summenBewilligt.Verbindlichkeiten - summenBewilligt.Forderungen;

				row.Field5 = String.Format("{0:c}", saldoForderungen);
				row.Field6 = String.Format("{0:c}", saldoVerbindlichkeiten);

				//Nicht bewilligte Gesamtsummen
				row.Field7 = String.Format("{0:c}", summenNichtBewilligt.Forderungen);
				row.Field8 = String.Format("{0:c}", summenNichtBewilligt.Verbindlichkeiten);

				saldoForderungen = 0;
				saldoVerbindlichkeiten = 0;

				if (summenNichtBewilligt.Forderungen > summenNichtBewilligt.Verbindlichkeiten)
					saldoForderungen = summenNichtBewilligt.Forderungen - summenNichtBewilligt.Verbindlichkeiten;
				else
					saldoVerbindlichkeiten = summenNichtBewilligt.Verbindlichkeiten - summenNichtBewilligt.Forderungen;

				row.Field9 = String.Format("{0:c}", saldoForderungen);
				row.Field10 = String.Format("{0:c}", saldoVerbindlichkeiten);
			}

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

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

			return newQueryRo;
		}


	}
	class Summen
	{
		public decimal Forderungen = 0;
		public decimal Verbindlichkeiten = 0;
	}
}
