using System;
using BS.Shared;
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;

namespace BeWo.BetreuWoReports.Alt
{
	public partial class Kostenstellenauswertung : DevExpress.XtraReports.UI.XtraReport, IBeWoReport<QueryRO>
    {
        
        public Kostenstellenauswertung()
        {
            InitializeComponent();
        }

        public void SetReportDataSource(QueryRO pRO)
        {

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

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

            Dictionary<long, QueryRO.Row> customerCareTypes2Row = new Dictionary<long, QueryRO.Row>();
            Dictionary<long, TotalSummary> customerCareTypes2TotalSummary = new Dictionary<long, TotalSummary>();
            Dictionary<long, QueryRO.Row> customer2Row = new Dictionary<long, QueryRO.Row>();
            Dictionary<long, TotalSummary> customer2TotalSummary = new Dictionary<long, TotalSummary>();

            int customerCareTypeOid = 0;

            Int32.TryParse(ro.Rows[0].Field3.ToString(), out customerCareTypeOid);

            DateTime startDate = DateTime.Parse(ro.Rows[0].Field1.ToString());
            DateTime endDate = DateTime.Parse(ro.Rows[0].Field2.ToString());
            DateTimeSpan span = new DateTimeSpan();
            span.StartDateTime = startDate;
            span.EndDateTime = endDate;

            var serviceRecordList = DAOFactory.SearchDAO.FindServiceRecordsInSpan(span, null);
            
            IList<Employee> employees = DAOFactory.GenericDAO.GetAllActiveAndArchived<Employee>();
            Dictionary<long, Employee> empDict = new Dictionary<long, Employee>();
            foreach (var item in employees)
            {
                empDict.Add(item.Oid.Value, item);
            }


            IList<Customer> customers = DAOFactory.GenericDAO.GetAllActiveAndArchived<Customer>();
            Dictionary<long, Customer> custDict = new Dictionary<long, Customer>();
            foreach (var item in customers)
            {
                custDict.Add(item.Oid.Value, item);
            }

            TotalSummary totalSummary = new TotalSummary();
            
            foreach (var sr in serviceRecordList)
            {
                //Kategorien: LVR Fachleistung, ALS Assistenz, Hausmeister 0,5, FLS-HD
                if (sr.ServiceDescription != null && (sr.ServiceDescription.ServiceCategory.Oid == 1 || sr.ServiceDescription.ServiceCategory.Oid == 4 || 
                    sr.ServiceDescription.ServiceCategory.Oid == 27 || sr.ServiceDescription.ServiceCategory.Oid == 30))
                {
                    if (sr.CustomerOid.HasValue && custDict.ContainsKey(sr.CustomerOid.Value) &&
                        empDict.ContainsKey(sr.EmployeeOid.Value))
                    {
                        Customer c = custDict[sr.CustomerOid.Value];
                        Employee e = empDict[sr.EmployeeOid.Value];

                        
                        var customerCareTypes = c.ValueList.FindByType(ValueListEntryType.CustomerCareType);

                        bool addedToTotal = false;
                        foreach (var valueListEntry2Object in customerCareTypes)
                        {
                            if (valueListEntry2Object.Entry.IsActive == ActivationTypeId.Active &&
                                (customerCareTypeOid == 0 ||
                                 customerCareTypeOid == valueListEntry2Object.Entry.Oid.Value))
                            {
                                QueryRO.Row customerCareTypeRow = null;
                                TotalSummary customerCareSummary = null;
                                if (customerCareTypes2Row.ContainsKey(valueListEntry2Object.Entry.Oid.Value))
                                {
                                    customerCareTypeRow = customerCareTypes2Row[valueListEntry2Object.Entry.Oid.Value];
                                    customerCareSummary =
                                        customerCareTypes2TotalSummary[valueListEntry2Object.Entry.Oid.Value];
                                }
                                else
                                {
                                    customerCareTypeRow = new QueryRO.Row();
                                    customerCareTypeRow.Field1 = String.Format("{0}, {1:dd.MM.yyyy}-{2:dd.MM.yyyy}",
                                                                               valueListEntry2Object.Entry.Value,
                                                                               startDate, endDate.AddDays(-1));
                                    customerCareTypeRow.ChildRows1 = new List<QueryRO.Row>();
                                    newQueryRo.Rows.Add(customerCareTypeRow);

                                    customerCareTypes2Row[valueListEntry2Object.Entry.Oid.Value] = customerCareTypeRow;

                                    customerCareSummary = new TotalSummary();
                                    customerCareTypes2TotalSummary[valueListEntry2Object.Entry.Oid.Value] =
                                        customerCareSummary;
                                }

                                Contract contract = e.GetValidContractForDate(sr.Start);

                                QueryRO.Row customerRow = null;
                                TotalSummary customerSummary = null;
                                if (customer2Row.ContainsKey(c.Oid.Value))
                                {
                                    customerRow = customer2Row[c.Oid.Value];
                                    customerSummary = customer2TotalSummary[c.Oid.Value];
                                }
                                else
                                {
                                    customerRow = new QueryRO.Row();
                                    customerRow.Field1 = String.Format("{0}, {1}", c.Person.LastName, c.Person.FirstName);

                                    customerCareTypeRow.ChildRows1.Add(customerRow);

                                    customer2Row[c.Oid.Value] = customerRow;

                                    customerSummary = new TotalSummary();
                                    customer2TotalSummary[c.Oid.Value] = customerSummary;

                                    List<CostBearer2SupportConcept> cbsInSpan = new List<CostBearer2SupportConcept>();
                                    foreach (var sc in c.SupportConcepts)
                                    {
                                        foreach (var c2s in sc.CostBearer2SupportConceptList)
                                        {
                                            if (c2s.StartDate.HasValue && c2s.EndDate.HasValue && c2s.StartDate.Value < endDate && c2s.EndDate.Value >= startDate)
                                            {
                                                cbsInSpan.Add(c2s);
                                            }

                                        }
                                    }
                                    if (cbsInSpan.Count > 0)
                                    {
                                        foreach (var c2s in cbsInSpan)
                                        {
                                            Calculations calc = Calculations.GetInstance(c2s.CostBearer.ID);
                                            SupportConceptCostBearerRelDC relDC =
                                                MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.
                                                    MapToNewDC(c2s);
                                            decimal approvedHours =
                                                calc.GetApprovedHoursForPeriod(relDC, startDate, endDate.AddDays(-1)) ;

                                            
                                            if (c2s.CostBearer.Organisation.Name.ToLower() == "lvr fls")
                                            {
                                                customerSummary.approvedMinFl += approvedHours;
                                            }
                                            else if (c2s.CostBearer.Organisation.Name.ToLower() == "lvr als")
                                            {
                                                customerSummary.approvedMinAls += approvedHours;
                                            }
                                            else
                                            {
                                                customerSummary.approvedMinOthers += approvedHours;
                                            }
                                        }
                                        
                                    }
                                }

                                //QueryRO.Row serviceRecordRow = new QueryRO.Row();
                                //DateTime end = sr.Start.Value.AddMinutes((double)sr.RoundedDuration);
                                //serviceRecordRow.Field1 = String.Format("{0}, {1}", c.Person.LastName, c.Person.FirstName);
                                //serviceRecordRow.Field2 = String.Format("{0}, {1}", e.Person.LastName, e.Person.FirstName);
                                //serviceRecordRow.Field3 = String.Format("{0:0.00}", sr.RoundedDuration/60);

                                decimal hourlyRate = 0;
                                if (contract != null && contract.HourlyRate.HasValue)
                                    hourlyRate = contract.HourlyRate.Value;
                                //serviceRecordRow.Field4 = String.Format("{0:c}", hourlyRate);
                                //serviceRecordRow.Field5 = String.Format("{0:c}", (sr.RoundedDuration/60)*hourlyRate);

                                //customerCareTypeRow.ChildRows1.Add(serviceRecordRow);
                                customerSummary.countTotal++;
                                customerSummary.flmTotal += sr.RoundedDuration;
                                customerSummary.amountTotal += (sr.RoundedDuration/60)*hourlyRate;

                                customerCareSummary.countTotal++;
                                customerCareSummary.flmTotal += sr.RoundedDuration;
                                customerCareSummary.amountTotal += (sr.RoundedDuration/60)*hourlyRate;


                                if (!addedToTotal)
                                {
                                    totalSummary.countTotal++;
                                    totalSummary.flmTotal += sr.RoundedDuration;
                                    totalSummary.amountTotal += (sr.RoundedDuration/60)*hourlyRate;
                                    addedToTotal = true;
                                }
                            }
                        }
                    }
                }
            }

            foreach (var totalSummaryKey in customerCareTypes2TotalSummary.Keys)
            {
                QueryRO.Row customerCareTypeRow = customerCareTypes2Row[totalSummaryKey];
                TotalSummary ts = customerCareTypes2TotalSummary[totalSummaryKey];

                
                //DateTime end = sr.Start.Value.AddMinutes((double)sr.RoundedDuration);
                
                customerCareTypeRow.Field2 = String.Format("{0:0.00}", ts.flmTotal / 60);
                customerCareTypeRow.Field3 = String.Format("{0:c}", ts.amountTotal);

            }

            foreach (var totalSummaryKey in customer2TotalSummary.Keys)
            {
                QueryRO.Row customerRow = customer2Row[totalSummaryKey];
                TotalSummary ts = customer2TotalSummary[totalSummaryKey];


                //DateTime end = sr.Start.Value.AddMinutes((double)sr.RoundedDuration);

                customerRow.Field2 = String.Format("{0:0.00}", ts.flmTotal / 60);
                customerRow.Field3 = String.Format("{0:c}", ts.amountTotal);

                customerRow.Field4 = String.Format("{0:0.00}", ts.approvedMinFl);
                customerRow.Field5 = String.Format("{0:0.00}", ts.approvedMinAls);
                customerRow.Field6 = String.Format("{0:0.00}", ts.approvedMinOthers);

            }

            lblTotalSummary.Text = String.Format("FLS Gesamt: {0:0.00}, Gesamtbetrag: {1:c}", totalSummary.flmTotal/60,
                                                 totalSummary.amountTotal);

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

        private QueryRO.Row CreateMonatsRow(DateTime dt)
        {
            QueryRO.Row row = new QueryRO.Row();

            row.Field1 = String.Format("{0:MMM yyyy}", dt);

            row.ChildRows2 = new List<QueryRO.Row>();

            return row;
        }

        

    }

    internal class TotalSummary
    {
        internal decimal flmTotal;
        internal decimal amountTotal;
        internal int countTotal;
        internal decimal approvedMinFl;
        internal decimal approvedMinAls;
        internal decimal approvedMinOthers;
    }
}
