using System.Reflection;
using System.Text.RegularExpressions;

namespace Core.Entities;

public class Team
{
	public string Name { get; }
	public CompetitiveEvent Event { get; }
	public IList<Student> Students { get; }

	public Student? Captain { get; set;  }

	public string TeamNumber { get; set; }

	public string RegionalTimeSlot { get; set; }

	public Tuple<DateTime,DateTime?>? RegionalTimeSlotObj
	{
		get
		{
			
			if (string.IsNullOrEmpty(RegionalTimeSlot))
				return null;
			var times = Regex.Matches(RegionalTimeSlot, @"(.*)\s*-\s*(.*)");
			if (times.Count == 0)
				return Tuple.Create(P(RegionalTimeSlot), (DateTime?)null);
			var match = times[0];
			if (!match.Success)
				return Tuple.Create(P(RegionalTimeSlot), (DateTime?)null);

			return Tuple.Create(P(match.Groups[1].Value), (DateTime?)P(match.Groups[2].Value));
			return null;
		}
	}

	private DateTime P(string s)
	{
		var dt = DateTime.Parse(s);
		if (dt.TimeOfDay < TimeSpan.FromHours(7))
			return dt + TimeSpan.FromHours(12);
		return dt;
	}

	public Team(string name, CompetitiveEvent @event, IList<Student> students, Student? captain = null, string teamNumber = null, string regionalTimeSlot = null)
	{
		Name = name;
		Event = @event;
		Students = students;
		Captain = captain;
		TeamNumber = teamNumber;
		RegionalTimeSlot = regionalTimeSlot;
	}

	public virtual Team CloneWithOmittedStudents(IEnumerable<Student> studentsToOmit)
	{
		var studentsToOmitList = studentsToOmit.ToList();
		var omittedStudents = Students.Where(studentsToOmitList.Contains).ToList();
		if (!omittedStudents.Any())
			return new Team(Name, Event, Students.ToList(), Captain);

		var remainingStudents = Students.Where(s => !studentsToOmitList.Contains(s)).ToList();
		return new PartialTeam(Name, Event, remainingStudents,  omittedStudents);
	}

	public Team Clone() => CloneWithOmittedStudents(Array.Empty<Student>());
	
	public static int GetStudentTeamOverlapCount(IList<Team>[] timeSlots)
	{
		return timeSlots.Sum(GetStudentTeamOverlapCount);
	}

	private static int GetStudentTeamOverlapCount(IList<Team> timeSlot)
	{
		return GetStudentTeamOverlaps(timeSlot).Count();
	}

	public static IEnumerable<Tuple<Student, IEnumerable<Team>>> GetStudentTeamOverlaps(IList<Team> timeSlot)
	{
		return
			from s in timeSlot.SelectMany(ts => ts.Students).Distinct()
			group s by timeSlot.Where(t => t.Students.Contains(s))
			into gs
			where gs.Key.Count() > 1
			select Tuple.Create(gs.First(), gs.Key);
	}

	public override string ToString()
	{
		return Name;
	}

	public string ToStringWithIndividualAndRegional()
	{
		var ind = Event.Format is EventFormat.Individual ? " (Ind.)" : string.Empty;
		var regional= Event.RegionalEvent ? " (Reg.)" : string.Empty;
		//var regional= Event.RegionalEvent ? " (Reg.)" : string.Empty;

		var eventAttributes = Event.EventAttributes();
		return string.IsNullOrEmpty(eventAttributes) ? Name : Name + " (" + eventAttributes + ")";
	}
}