using System;
using System.Collections.Generic;
using System.Linq;
using BS.Shared.Core;

namespace BS.Shared
{
    public class ComplexWohnheimbuchungsRelationHelper
    {
        public DateTimeSpan Zeitspanne { get; set; }
        public List<long> RelatedEmployees { get; set; }
        public List<long> RelatedSupportConcepts { get; set; }

        public ComplexWohnheimbuchungsRelationHelper(DateTimeSpan pZeitspanne, List<long> pRelatedEmployees, List<long> pRelatedSupportConcepts)
        {
            RelatedEmployees       = pRelatedEmployees ?? new List<long>();
            RelatedSupportConcepts = pRelatedSupportConcepts ?? new List<long>();
            Zeitspanne             = pZeitspanne;
        }

        public static IEnumerable<ComplexWohnheimbuchungsRelationHelper> CalculateServiceRecordTimeSpans(IEnumerable<ComplexWohnheimbuchungsRelationHelper> pMitarbeiterTimeSpans, List<ComplexWohnheimbuchungsRelationHelper> pHilfeplanTimeSpans)
        {
            var result = new List<ComplexWohnheimbuchungsRelationHelper>();

            var liste = pMitarbeiterTimeSpans.Where(w => pHilfeplanTimeSpans.Any(a => a.Zeitspanne.Overlaps(w.Zeitspanne))).ToList();

            foreach (var m in liste)
            {
                var hps = pHilfeplanTimeSpans.Where(w => m.Zeitspanne.Overlaps(w.Zeitspanne)).ToList();
                var start = m.Zeitspanne.StartDate;
                var ende = m.Zeitspanne.EndDate;

                foreach (var hp in hps)
                {
                    var zs = hp.Zeitspanne;
                    var datum = new DateTimeSpan { IsCalculatingHoursAndMinutesByDates = true, StartDate = zs.StartDate < start ? start : zs.StartDate };

                    if (hps.Any(a => a.Zeitspanne.Overlaps(hp.Zeitspanne)))
                    {
                        var tmp = GetNextDate(hps.Where(a => a.Zeitspanne.Overlaps(hp.Zeitspanne)).Select(s => s.Zeitspanne).ToList(), datum.StartDate);
                        datum.EndDate = tmp > ende ? ende : tmp;
                    }
                    else
                    {
                        datum.EndDate = zs.EndDate > ende ? ende : zs.EndDate;
                    }

                    result.Add(new ComplexWohnheimbuchungsRelationHelper(datum, m.RelatedEmployees, hp.RelatedSupportConcepts));
                }
            }

            return result;
        }

        private static DateTime GetNextDate(List<DateTimeSpan> pSpans, DateTime pPreviousDateTime)
        {
            var einzelneDaten = pSpans.Select(s => s.StartDate).ToList();
            einzelneDaten.AddRange(pSpans.Select(s => s.EndDate));
            einzelneDaten.Sort();

            var nextDate = pPreviousDateTime;

            foreach (var datum in einzelneDaten.Where(datum => datum > pPreviousDateTime))
            {
                nextDate = datum;
                break;
            }

            return nextDate;
        }
    }
}