using Core.Calculation;
using Core.Entities;
using Tests.Parsers;

namespace Tests.Calculation;

[TestFixture]
public class TeamSchedulerTest
{
	[Test]
	public void Prototype_Test()
	{
		var teamSchedulerTest = new Core.Calculation.TeamScheduler_Prototype();
		teamSchedulerTest.Solve();
	}

	[Test]
	public void SolutionTest()
	{
		var events = TestEntityHandler.GetCompetitiveEvents();
		var students = TestEntityHandler.GetStudents(events);
		
		var allTeams = TestEntityHandler.GetTeams(events, students);
		var teams = allTeams;

		teams =
			(from e in events
			 from t in teams
			 where t.Event == e
				      //&& t.Students.Count > 1
				      && (e.Format == EventFormat.Team && e.RegionalEvent)
				select t).ToArray();
		teams =
			teams.Where(t => !t.Event.Name.Contains("Tech Bowl")).ToArray();

		//var eventAssignment = new EventAssigner(events, students);
		//var teams = eventAssignment.Solve();

		IList<Team>[] timeSlots;
		if (true)
		{
			var teamScheduler = TeamScheduler.CreateInstance(teams, 3);
			timeSlots = teamScheduler.Solve();
		}
		else
		{
			var teamScheduler = new TeamScheduler_DecisionTree(teams, 3);
			timeSlots = teamScheduler.Solve();
		}

		timeSlots = new UnassignedStudentScheduler(allTeams, timeSlots).ScheduleStrategy(UnassignedScheduleStrategy.BiggestGroup);
		timeSlots = new UnassignedStudentScheduler(allTeams, timeSlots).ScheduleStrategy(UnassignedScheduleStrategy.IndividualEvents);

		var i = 1;
		foreach (var slot in timeSlots)
		{
			Console.WriteLine($"Time slot {i++}");
			foreach (var team in slot.OrderBy(s => s.Event.Name))
			{
				var names = string.Join(", ", team.Students.OrderByDescending(s => s.Grade + s.TsaYear).Select(s => s.FirstName));
				Console.WriteLine($"\t{team.Name}");
				Console.WriteLine($"\t\t{names}");
			}

			var overlaps = Team.GetStudentTeamOverlaps(slot).ToList();

			if (overlaps.Any())
			{
				Console.WriteLine("\toverlaps");
				foreach (var overlap in overlaps)
					Console.WriteLine(
						$"\t\t{overlap.Item1.Name} : {string.Join(", ", overlap.Item2.Select(t => t.Name))}");
			}

			var unassigned = UnassignedStudentScheduler.UnassignedStudents(students, slot).ToList();
			
			if (unassigned.Any())
				Console.WriteLine("\tunassigned");
			Console.WriteLine($"\t\t{string.Join(", ", unassigned.Select(s => s.FirstName))}");
		}

		//var allScheduledTeams = timeSlots.SelectMany(list => list).GroupBy(t => t.Name).SelectMany(g => g).Distinct();
		//foreach (var allScheduledTeam in allScheduledTeams.OrderBy(a => a.Name))
		//{
		//	Console.WriteLine($"{allScheduledTeam.Name}");
		//	Console.WriteLine($"\t{string.Join(", ", allScheduledTeam.Students.Select(s => s.FirstName))}");
		//}
	}
}