using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Ink;
using BS.Shared.Core;
using BeWo.Data.Access;
using BeWo.Data.Entities;

namespace BeWo.Report.ReportObjects
{
	public class MitarbeiterstundenkontoRO : AbstractBeWoReportObject<MitarbeiterstundenkontoRO>
    {
		List<EmployeeDetail> _EmployeeDetailList = new List<EmployeeDetail>();
		List<TeamDetail> _TeamDetailList = new List<TeamDetail>();

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

		public decimal FlsSollGesamt { get; set; }

		public decimal FlsIstGesamt { get; set; }

		public decimal FlsDiffGesamt { get; set; }

		public decimal StundenGesamt { get; set; }

		public decimal RelationIstSollGesamt { get; set; }

		public decimal MittelbarIst { get; set; }

		public decimal RelationFlsZuMittelbar { get; set; }

		public List<EmployeeDetail> EmployeeDetailList
		{
			get { return this._EmployeeDetailList; }

			set { this._EmployeeDetailList = value; }
		}

		public List<TeamDetail> TeamDetailList
		{
			get { return this._TeamDetailList; }

			set { this._TeamDetailList = value; }
		}

		public static MitarbeiterstundenkontoRO Create(long? employeeOid, long? teamOid, DateTime startDate, DateTime endDate, IEnumerable<long> employeeOids)
		{
			Team team = null;

			var ro = new MitarbeiterstundenkontoRO {ReportStartDate = startDate, 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 if(employeeOids != null)
			{
				employees = DAOFactory.GenericDAO.LoadByIDs<Employee>(employeeOids);
			}
			else
			{
				employees = DAOFactory.GenericDAO.GetAllActive<Employee>();
			}

			foreach (var 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 (var employee in ro.EmployeeDetailList)
			{
				if (employee.Teams.Count > 0)
				{
					foreach (var t in employee.Teams)
					{
						TeamDetail td;
						if (!teamOid2Details.ContainsKey(t.Oid.Value))
						{
							td = new TeamDetail {TeamName = t.Name, 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 TeamDetail
		{
			private List<EmployeeDetail> _EmployeeDetailList = new List<EmployeeDetail>();

			public string TeamName { get; set; }

			public Employee TeamLeader { get; set; }

			public decimal SollGesamt { get; set; }

			public decimal FlsSollGesamt { get; set; }

			public decimal FlsIstGesamt { get; set; }

			public decimal FlsDiffGesamt { get; set; }

			public decimal StundenGesamt { get; set; }

			public decimal RelationIstSollGesamt { get; set; }

			public decimal MittelbarIst { get; set; }

			public decimal RelationFlsZuMittelbar { get; set; }

			public List<EmployeeDetail> EmployeeDetailList
			{
				get
				{
					return this._EmployeeDetailList;
				}

				set
				{
					this._EmployeeDetailList = value;
				}
			}

		}

        public class EmployeeDetail
        {

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

			public IList<DayDetail> Days { 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 FlsIst { get; set; }

			public decimal MittelbarIst { get; set; }

			public decimal Bu { get; set; }

			public decimal StundenSollMax { get; set; }

			//FLS Max - Urlaub/Krankheit und Fortbildung
			public decimal StundenSollOhneUrlaubKrankheit { get; set; }

			public decimal FlsSoll { get; set; }

			public decimal FlsDiff { get; set; }

			public decimal? Fehlzeiten { get; set; }

			public decimal? TageUrlaub { get; set; }

			public decimal? TageKrankheit { get; set; }

			public decimal? UrlaubUndKrankheit { get; set; }

			public decimal? UrlaubGesamtImAktuellenJahr { get; set; }

			public decimal? UrlaubSoll { get; set; }

			public decimal? UrlaubsKonto { get; set; }

			public decimal StundenMittelbarIst { get; set; }

			public decimal StundenGesamtIst { get; set; }

			public decimal RelationFlsZuMittelbar { get; set; }

			public decimal RelationIstSoll { get; set; }

			public decimal? Ueberstunden { get; set; }

			public decimal? UeberstundenVormonat { get; set; }

			public decimal? UeberstundenGesamt { get; set; }

			public decimal UeberstundenAusbezahlt { get; set; }

			public decimal WorkDaysThisMonth { get; set; }

			public decimal SollProTag { get; set; }
		}

		public class DayDetail
		{
			public DateTime Date { get; set; }

			public DateTime? StartDateTime1 { get; set; }
			public DateTime? EndDateTime1 { get; set; }

			public DateTime? StartDateTime2 { get; set; }
			public DateTime? EndDateTime2 { get; set; }

			public DateTime? StartDateTime3 { get; set; }
			public DateTime? EndDateTime3 { get; set; }

			public DateTime? StartDateTime4 { get; set; }
			public DateTime? EndDateTime4 { get; set; }

			public decimal HoursSaturday { get; set; }

			public decimal HoursSunday { get; set; }

			public decimal HoursHoliday { get; set; }

			public decimal HoursHoliday2 { get; set; }

			public IList<AbsenceTime> AbsenceTimes { get; set; }

			public decimal HoursInVacation { get; set; }

			public decimal HoursSick { get; set; }

			public decimal MinutesTotal { get; set; }

			public String Custom1 { get; set; }

			public String Custom2 { get; set; }

			public String Custom3 { get; set; }

			public String Custom4 { get; set; }

			public IList<ServiceRecord> ServiceRecords { get; set; }

			public int? NightStart { get; set; }

			public int? NightEnd { get; set; }

			public int? MaxHoursUntilBreak { get; set; }

			public int? BreakMinutes { get; set; }

			public decimal SpecialHours { get; set; }
		}
	}
}