using System;
using System.Collections.Generic;
using BeWo.Data.Access;
using BeWo.Data.Entities;

namespace BeWo.Report.ReportObjects
{
	public class MitarbeiterauslastungRO : AbstractBeWoReportObject<MitarbeiterauslastungRO>
	{
		private List<EmployeeDetail> employeeDetailList = new List<EmployeeDetail>();
		private List<TeamDetail> teamDetailList = new List<TeamDetail>();

		public DateTime ReportStartDate { get; set; }
		public DateTime ReportEndDate { get; set; }

		public decimal ApprovedHoursPerWeek { get; set; }

		public decimal ApprovedHoursPerWeekWithRateFactor { get; set; }

		public decimal DirectIst { get; set; }

		public decimal MittelbarIst { get; set; }

		public decimal RelationDirectToMittelbar { get; set; }

		public decimal RelationIstSoll { get; set; }

		public List<EmployeeDetail> EmployeeDetailList
		{
			get { return employeeDetailList; }

			set { employeeDetailList = value; }
		}

		public List<TeamDetail> TeamDetailList
		{
			get { return teamDetailList; }

			set { teamDetailList = value; }
		}

		public static MitarbeiterauslastungRO Create(long? employeeOid, long? teamOid, DateTime startDate, DateTime endDate)
		{
			Team team = null;

			var ro = new MitarbeiterauslastungRO();
			ro.ReportStartDate = startDate;
			ro.ReportEndDate = endDate;


			IList<Employee> employees = null;

			if (employeeOid.HasValue)
			{
				var emp = DAOFactory.GenericDAO.GetByID<Employee>(employeeOid.Value);
				employees = new List<Employee> {emp};
			}
			else if (teamOid.HasValue)
			{
				team = DAOFactory.GenericDAO.GetByID<Team>(teamOid.Value);
				employees = team.MemberList;
			}
			else
			{
				employees = DAOFactory.GenericDAO.GetAllActive<Employee>();
			}


			foreach (Employee emp in employees)
			{
				var empDetail = new EmployeeDetail();
				ro.EmployeeDetailList.Add(empDetail);

				empDetail.Teams = team == null ? DAOFactory.SearchDAO.FindTeamsOfEmployee(emp.Oid.Value) : new List<Team> {team};
				empDetail.Employee = emp;
				empDetail.LastName = emp.Person.LastName;
				empDetail.FirstName = emp.Person.FirstName;
				empDetail.FullName = String.Format("{0}, {1}", empDetail.LastName, empDetail.FirstName);
			}

			var teamOid2Details = new Dictionary<long, TeamDetail>();

			foreach (EmployeeDetail employee in ro.EmployeeDetailList)
			{
				if (employee.Teams.Count > 0)
				{
					foreach (Team t in employee.Teams)
					{
						TeamDetail td = null;
						if (!teamOid2Details.ContainsKey(t.Oid.Value))
						{
							td = new TeamDetail();
							td.TeamName = t.Name;
							td.TeamLeader = t.Leader;
							ro.TeamDetailList.Add(td);
							teamOid2Details.Add(t.Oid.Value, td);
						}
						else
						{
							td = teamOid2Details[t.Oid.Value];
						}
						td.EmployeeDetailList.Add(employee);
					}
				}
			}
			ro.TeamDetailList.Sort((t1, t2) => t1.TeamName.CompareTo(t2.TeamName));
			ro.EmployeeDetailList.Sort((e1, e2) => e1.FullName.CompareTo(e2.FullName));
			return ro;
		}

		public class EmployeeDetail
		{
			private List<SupportConceptDetail> scDetailList = new List<SupportConceptDetail>();

			public IList<Team> Teams { get; set; }

			public Employee Employee { get; set; }

			public string FirstName { get; set; }

			public string LastName { get; set; }

			public string FullName { get; set; }

			public bool HasContract { get; set; }

			public decimal ApprovedHoursPerWeek { get; set; }

			public decimal ApprovedHoursPerWeekWithRateFactor { get; set; }

			public decimal DirectIst { get; set; }

			public decimal MittelbarIst { get; set; }

			public decimal RelationDirectToMittelbar { get; set; }

			public decimal RelationIstSoll { get; set; }

			public decimal MinutesOfOtherActivities { get; set; }

			public decimal WeeklyTotalHoursByContract { get; set; }

			public decimal FLSTotalHoursByContract { get; set; }

			public List<SupportConceptDetail> SupportConceptDetailList
			{
				get { return scDetailList; }
				set { scDetailList = value; }
			}
		}

		public class SupportConceptDetail
		{
			public Customer Customer { get; set; }

			public String CustomerFullName
			{
				get
				{
					if (Customer != null)
						return String.Format("{0}, {1}", Customer.Person.LastName, Customer.Person.FirstName);
					return null;
				}
			}

			public CostBearer2SupportConcept CostBearer2SupportConcept { get; set; }

            public SupportConceptApprovalPeriod SupportConceptApprovalPeriod { get; set; }

            public String TimeRangeString
			{
				get { return String.Format("{0:dd.MM.yyyy}-{1:dd.MM.yyyy}", StartDate, EndDate); }
			}

			public decimal ApprovedHoursPerWeek { get; set; }

			public decimal ApprovedHoursPerWeekWithRateFactor { get; set; }

			public DateTime? StartDate { get; set; }

			public DateTime? EndDate { get; set; }

			public decimal DirectIst { get; set; }

			public decimal MinutesSoll { get; set; }

			public decimal MittelbarIst { get; set; }

			public decimal RelationDirectToMittelbar { get; set; }

			public decimal RelationIstSoll { get; set; }

			public decimal WeekCountUntilNow { get; set; }
		}

		public class TeamDetail
		{
			private List<EmployeeDetail> employeeDetailList = new List<EmployeeDetail>();
			private List<SupportConceptDetail> scDetailList = new List<SupportConceptDetail>();

			public string TeamName { get; set; }

			public Employee TeamLeader { get; set; }

			public decimal ApprovedHoursPerWeek { get; set; }

			public decimal ApprovedHoursPerWeekWithRateFactor { get; set; }

			public decimal DirectIst { get; set; }

			public decimal MittelbarIst { get; set; }

			public decimal RelationDirectToMittelbar { get; set; }

			public decimal RelationIstSoll { get; set; }


			public List<EmployeeDetail> EmployeeDetailList
			{
				get { return employeeDetailList; }
				set { employeeDetailList = value; }
			}

			public List<SupportConceptDetail> SupportConceptDetailList
			{
				get { return scDetailList; }
				set { scDetailList = value; }
			}
		}
	}
}