using System;
using System.Collections.Generic;
using System.Linq;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.ServiceImplementations;
using BS.Shared;
using BS.Shared.DataContracts;

namespace BeWo.Report.ReportObjects
{
    public class 
		SupportConceptListRO : AbstractBeWoReportObject<SupportConceptListRO>
    {
        private List<SupportConceptDetail> _SupportConceptDetailList = new List<SupportConceptDetail>();

		public DateTime? AppointedDate { get; set; }

        public List<SupportConceptDetail> SupportConceptDetailList
        {
            get
            {
                return this._SupportConceptDetailList;
            }

            set
            {
                this._SupportConceptDetailList = value;
            }
        }

		private List<EmployeeSupportConceptDetail> _EmployeeSupportConceptDetailList = new List<EmployeeSupportConceptDetail>();

		public List<EmployeeSupportConceptDetail> EmployeeSupportConceptDetailList
		{
			get
			{
				return this._EmployeeSupportConceptDetailList;
			}

			set
			{
				this._EmployeeSupportConceptDetailList = value;
			}
		}

        public static SupportConceptListRO Create(long eOid, bool onlyMySupportConcepts, bool archivedSupportConcepts, DateTime? appointedDate)
        {
            // var pSpan = new DateTimeSpan();
            // pSpan.StartDateTime = new DateTime(pYear, pMonth, 1);
            // pSpan.EndDateTime = pSpan.StartDateTime.AddMonths(1).AddTicks(-1);
            long starttime = DateTime.Now.Ticks;

            SupportConceptListRO ro = new SupportConceptListRO();
	        ro.AppointedDate = appointedDate;
	        if (!ro.AppointedDate.HasValue)
		        ro.AppointedDate = DateTime.Now;

            List<SupportConceptOverviewDC> soList = null;

            AnalysisServiceImp service = new AnalysisServiceImp();

            soList = service.GetSupportConceptAnalysis(eOid, onlyMySupportConcepts, archivedSupportConcepts, appointedDate);

            if (soList != null)
            {
                soList = soList.OrderBy(so => String.Format("{0}, {1}", so.CustomerLastName, so.CustomerFirstName)).ToList();
            }

			Dictionary<long, EmployeeSupportConceptDetail> emp2Details = new Dictionary<long, EmployeeSupportConceptDetail>();

            foreach (SupportConceptOverviewDC dc in soList)
            {
                SupportConceptDetail detail = new SupportConceptDetail();

                detail.CustomerFirstName = dc.CustomerFirstName;
                detail.CustomerLastName = dc.CustomerLastName;
                detail.Costbearer = dc.CostBearer;
                if (dc.ApprovedStartDate != null)
                {
                    detail.StartDate = dc.ApprovedStartDate.Value;
                }
                else if (dc.RequestedStartDate != null)
                {
                    detail.StartDate = dc.RequestedStartDate.Value;
                }

                if (dc.ApprovedEndDate != null)
                {
                    detail.EndDate = dc.ApprovedEndDate.Value;
                }
                else if (dc.RequestedEndDate != null)
                {
                    detail.EndDate = dc.RequestedEndDate.Value;
                }

                detail.IsApproved = dc.IsApproved;
                detail.FLSTotal = dc.FLSApprovedSum;
                detail.FLSTotalRecordedBillable = dc.FLSBilledTillNow;
                detail.FLSRemaining = dc.FLSApprovedSum - dc.FLSBilledTillNow;
                detail.FLSOpenPerWeek = dc.FLSOpenPerWeek;
                detail.OpenWeeks = dc.OpenWeeks;
                detail.OpenMonths = dc.OpenMonths;
                detail.TotalWeeks = dc.WeeksTotal;
                detail.WeeksPassed = dc.WeeksTotal - dc.OpenWeeks;
                detail.FLSPerWeekSoll = dc.FLSApprovedPerWeek;
                detail.FLSDifferenceApprovedRecordedTillNow = dc.FLSDifferenceApprovedRecordedTillNow;
                detail.PassageStatus = dc.PassageStatus;
	            detail.FLSApprovedTillNow = dc.FLSApprovedTillNow;
	            detail.CostBearer2SupportConceptOid = dc.CostBearer2SupportConceptOid;

                if (detail.WeeksPassed != 0)
                {
                    detail.FLSPerWeekIst = dc.FLSBilledTillNow / detail.WeeksPassed;
                }
                else
                {
                    detail.FLSPerWeekIst = 0;
                }

                decimal fact = (100 + dc.CurrentRateFactor) / 100;

                detail.DiffPerWeekAmount = (detail.FLSPerWeekSoll - detail.FLSPerWeekIst) * dc.CurrentHourlyRate * fact;

                // detail.DurationPercentage = dc.DurationPercentage;
                decimal percentage = 0;
                if (detail.FLSPerWeekSoll != 0)
                {
                    percentage = (detail.FLSPerWeekIst * 100) / detail.FLSPerWeekSoll;
                }

                detail.DurationPercentage = percentage;


	            var sc = DAOFactory.GenericDAO.GetByID<SupportConcept>(dc.SupportConceptOid);
	            var customer = sc.Customer;

	            detail.RequisitionSendDate = sc.RequisitionSendDate;
				detail.SupportConceptSendDate = sc.SupportConceptSendDate;

				EmployeeSupportConceptDetail empDetails = null;

				foreach (var item in customer.Employee2CustomerList)
				{
					foreach (var valueEntry in item.ValueList)
					{
						if (valueEntry.Entry.SystemEntryID != null && valueEntry.Entry.SystemEntryID.Value == SystemEntryID.EmployeeRoleMainAttendant)
						{
				
							if (emp2Details.ContainsKey(item.Employee.Oid.Value))
							{
								empDetails = emp2Details[item.Employee.Oid.Value];
							}
							else
							{
								empDetails = new EmployeeSupportConceptDetail();
								ro.EmployeeSupportConceptDetailList.Add(empDetails);
								empDetails.EmployeeName = String.Format("{0} {1}", item.Employee.Person.FirstName, item.Employee.Person.LastName);

								Contract c = item.Employee.GetValidContractForDate(appointedDate);
								if (c != null)
								{
									empDetails.HoursPerWeek = c.WeeklyTotalHours;
									empDetails.FlsPerWeek = c.WeeklyFLS;

								}
								emp2Details.Add(item.Employee.Oid.Value, empDetails);
							}
							

							string employeeAbbr = item.Employee.Person.Abbreviation;
							
							if (string.IsNullOrEmpty(employeeAbbr))
							{
								employeeAbbr = item.Employee.Person.FirstName.Substring(0, 1) + ". " + item.Employee.Person.LastName;
							}
							if (String.IsNullOrEmpty(detail.MainAttendant))
								detail.MainAttendant = employeeAbbr;
							else
							{
								if (!detail.MainAttendant.Contains(employeeAbbr))
								{
									detail.MainAttendant += ", " + employeeAbbr;
								}
							}
							if (detail.MainEmployee == null)
							{
								detail.MainEmployee = item.Employee;
							}

							var teams = DAOFactory.SearchDAO.FindTeamsOfEmployee(item.EmployeeOid.Value);

							foreach (var team in teams)
							{
								if (String.IsNullOrEmpty(detail.Team))
									detail.Team = team.Name;
								else
								{
									if (!detail.Team.Contains(team.Name))
									{
										detail.Team += ", " + team.Name;
									}
								}
							}
							
						}
					}
				}

	            if (empDetails != null)
	            {
		            var copy = CreateCopy(detail);
		            copy.RowIndex = empDetails.SupportConceptDetailList.Count + 1;
					empDetails.SupportConceptDetailList.Add(copy);
	            }
				detail.RowIndex = ro.SupportConceptDetailList.Count + 1;
                ro.SupportConceptDetailList.Add(detail);
            }

            long endtime = DateTime.Now.Ticks;

            long diff = endtime - starttime;
            double secs = diff / (double)10000000;

            return ro;

            // return DAOFactory.SearchDAO.FindSupportConceptsInSpan(pSpan).OrderBy(ob => ob.Customer.Person.LastName + ", " + ob.Customer.Person.FirstName).Select(
            // sc => Create(sc.Customer.Oid.Value, pMonth, pYear, true)).ToList();
        }

		private static SupportConceptDetail CreateCopy(SupportConceptDetail detail)
		{
			return new SupportConceptDetail
			{
				Costbearer = detail.Costbearer,
				CustomerFirstName = detail.CustomerFirstName,
				CustomerLastName = detail.CustomerLastName,
				DiffPerWeekAmount = detail.DiffPerWeekAmount,
				DurationPercentage = detail.DurationPercentage,
				EndDate = detail.EndDate,
				FLSApprovedTillNow = detail.FLSApprovedTillNow,
				FLSDifferenceApprovedRecordedTillNow = detail.FLSDifferenceApprovedRecordedTillNow,
				FLSOpenPerWeek = detail.FLSOpenPerWeek,
				FLSPerWeekIst = detail.FLSPerWeekIst,
				FLSPerWeekSoll = detail.FLSPerWeekSoll,
				FLSRemaining = detail.FLSRemaining,
				FLSTotal = detail.FLSTotal,
				FLSTotalRecordedBillable = detail.FLSTotalRecordedBillable,
				IsApproved = detail.IsApproved,
				MainAttendant = detail.MainAttendant,
				MainEmployee = detail.MainEmployee,
				OpenMonths = detail.OpenMonths,
				OpenWeeks = detail.OpenWeeks,
				PassageStatus = detail.PassageStatus,
				RequisitionSendDate = detail.RequisitionSendDate,
				StartDate = detail.StartDate,
				SupportConceptSendDate = detail.SupportConceptSendDate,
				TotalWeeks = detail.TotalWeeks,
				WeeksPassed = detail.WeeksPassed
			};
		}

        public class SupportConceptDetail
        {
			public int RowIndex { get; set; }

			public string MainAttendant { get; set; }

			public Employee MainEmployee { get; set; }

            public string Costbearer { get; set; }

            public string CustomerFirstName { get; set; }

            public string CustomerLastName { get; set; }

            public decimal DiffPerWeekAmount { get; set; }

            public decimal DurationPercentage { get; set; }

            public DateTime EndDate { get; set; }

			public decimal FLSApprovedTillNow { get; set; }

            public decimal FLSOpenPerWeek { get; set; }

            public decimal FLSPerWeekIst { get; set; }

            public decimal FLSPerWeekSoll { get; set; }

            public decimal FLSRemaining { get; set; }

            public decimal FLSTotal { get; set; }

            public decimal FLSTotalRecordedBillable { get; set; }

            public decimal FLSDifferenceApprovedRecordedTillNow { get; set; }

            public bool IsApproved { get; set; }

            public decimal OpenMonths { get; set; }

            public decimal OpenWeeks { get; set; }

            public DateTime StartDate { get; set; }

            public decimal TotalWeeks { get; set; }

            public decimal WeeksPassed { get; set; }

            public String PassageStatus { get; set; }

			public String Team { get; set; }

			public DateTime? RequisitionSendDate { get; set; } //Beantragt am

			public DateTime? SupportConceptSendDate { get; set; } //Eingereicht am

			public long CostBearer2SupportConceptOid { get; set; } //Eingereicht am
        }

		public class EmployeeSupportConceptDetail
		{
			private List<SupportConceptDetail> _SupportConceptDetailList = new List<SupportConceptDetail>();

			public List<SupportConceptDetail> SupportConceptDetailList
			{
				get
				{
					return this._SupportConceptDetailList;
				}

				set
				{
					this._SupportConceptDetailList = value;
				}
			}

			public Employee Employee { get; set; }

			public String EmployeeName { get; set; }

			public decimal? HoursPerWeek { get; set; }

			public decimal? FlsPerWeek { get; set; }
		}

	}
}