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.IntegraReports
{
    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 ro)
        {
            QueryRO newQueryRo = new QueryRO();
	        DateTime? appointmentDate = null;
	        if (ro.Rows != null)
	        {
		        DateTime dt;
		        if (DateTime.TryParse(ro.Rows[0].Field1.ToString(), out dt))
		        {
					dt = new DateTime(dt.Year, dt.Month, dt.Day);
			        dt = dt.AddMonths(1).AddDays(-1).Date;
			        appointmentDate = dt;

			        xrLabel13.Text = String.Format("Forderungen/Verbindlichkeiten aus lfd. Hilfeplänen vom {0:dd.MM.yyyy}", dt);
		        }
	        }

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

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

            decimal totalBewilligt = 0;
            decimal totalGeleistet = 0;
            decimal totalEntgelt = 0;
            decimal totalBezahlt = 0;
            decimal totalDiff = 0;

            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)
                    {
                        bool hasSettlementReport = false;
                        if (settlementIncoices != null && settlementIncoices.Count > 0)
                        {
                            foreach (var settlementIncoice in settlementIncoices)
                            {
                                if (!hasSettlementReport && settlementIncoice.CostBearer2SupportConceptOid == cb2sc.Oid)
                                    hasSettlementReport = true;
                            }
                        }
						if (!hasSettlementReport)
                        {
							//t.Add(cb2sc.Oid.Value);
                            if (!c2sOids.ContainsKey(cb2sc.Oid.Value))
                            {
                                QueryRO.Row row = 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());
                                }


                                row.Field1 = String.Format("{0}, {1}\r\n{2}", sc.Customer.Person.LastName,
                                                           sc.Customer.Person.FirstName, sb.ToString());
                                if (cb2sc.CostBearer.Organisation != null)
                                    row.Field2 = String.Format("{0}", cb2sc.CostBearer.Organisation.Name);


                                decimal billableHours = 0;
                                decimal approvedHours = 0;

								var calc = Calculations.GetInstance(cb2sc.CostBearer.ID);
                                var relDC =
                                    MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(
                                        cb2sc);
                                approvedHours += calc.GetApprovedHoursTillNow(relDC, appointmentDate) ?? 0;

                                var serviceRecords =
                                    cb2sc.ServiceRecords.ToList().MapToNewDCs();


								//Stunden außerhalb des Bewilligungszeitraums rausnehmen

								DateTime? edt = null;
	                            if (appointmentDate.HasValue)
	                            {
		                            edt = appointmentDate.Value.Date;
		                            if (edt > cb2sc.EndDate)
			                            edt = cb2sc.EndDate;
	                            }
	                            if (edt.HasValue)
	                            {
		                            serviceRecords = serviceRecords.Where(sr => sr.Start < edt.Value.AddDays(1)).ToList();
	                            }
                                billableHours +=
                                    calc.GetBillableDurationInMinutes(serviceRecords)/60;

	                            if (approvedHours < 0)
		                            approvedHours = 0;
                                row.Field3 = String.Format("{0:#,##0.00}", approvedHours);
                                row.Field4 = String.Format("{0:#,##0.00}", billableHours);
                                totalBewilligt += approvedHours;
                                totalGeleistet += billableHours;

	                            Settlement2DC si = null;
	                            if (appointmentDate.HasValue)
	                            {
									DateTime? startDate = new DateTime(1900, 1, 1);
		                            si = oi.GenerateInitialSettlementDCForPeriod(cb2sc.Oid.Value, startDate, edt);
	                            }
	                            else
		                            si = oi.GenerateInitialSettlementDC(cb2sc.Oid.Value);

	                            decimal entgelt = si.AmountBillableTotal ?? 0;
                                entgelt = Math.Round(entgelt, 2, MidpointRounding.AwayFromZero);
                                row.Field5 = String.Format("{0:c}", entgelt);


                                totalEntgelt += entgelt;

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

                                var bookingList = cb2sc.AccountingTransactions;

                                bookingList = bookingList.Where(i => i.BookingDate.HasValue).ToList();
								if (edt.HasValue)
								{
									bookingList = bookingList.Where(i => i.BookingDate < edt.Value.AddDays(1)).ToList();
								}
                                foreach (var item in bookingList)
                                {
                                    payments += item.Amount;
                                }
                                payments = Math.Round(payments, 2, MidpointRounding.AwayFromZero);

                                //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;

                                row.Field6 = String.Format("{0:c}", payments);
                                totalBezahlt += payments;

                                row.Field7 = String.Format("{0:c}",
                                                           Math.Round(entgelt - payments, 2,
                                                                      MidpointRounding.AwayFromZero));

                                totalDiff += Math.Round(entgelt - payments, 2, MidpointRounding.AwayFromZero);

                                newQueryRo.Rows.Add(row);

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

            lblGesamtBewilligtFLS.Text = String.Format("{0:#,##0.00}", totalBewilligt);
            lblGesamtGeleistetFLS.Text = String.Format("{0:#,##0.00}", totalGeleistet);
            lblGesamtEntgeltFLS.Text = String.Format("{0:c}", totalEntgelt);
            lblGesamtBezahl.Text = String.Format("{0:c}", totalBezahlt);
            lblGesamtDiff.Text = String.Format("{0:c}", totalDiff);

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


    }

}
