using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;

namespace TeslaConsole.RedPlanet;

[Serializable]
internal class RPMissionResults
{
	private RPMission mMission;

	internal DateTime mMissionStart;

	internal TimeSpan mActuallMissionTime;

	internal readonly List<MissionEvent> mEvents = new List<MissionEvent>();

	internal readonly Dictionary<RPPlayer, int> mFinalScores = new Dictionary<RPPlayer, int>();

	public RPMission Mission => mMission;

	public DateTime MissionStart => mMissionStart;

	public TimeSpan ActuallMissionTime => mActuallMissionTime;

	public IEnumerable<MissionEvent> Events => mEvents;

	internal RPMissionResults(RPMission mission)
	{
		mMission = mission;
	}

	public static string GetRPMissionsDirectory()
	{
		string text = Path.Combine(Program.GetCommonAppDataDirectory(), "RP Missions");
		if (!Directory.Exists(text))
		{
			Directory.CreateDirectory(text);
		}
		return text;
	}

	public static RPMissionResults Load(string file)
	{
		using GZipStream gZipStream = new GZipStream(File.OpenRead(file), CompressionMode.Decompress);
		BinaryFormatter binaryFormatter = new BinaryFormatter();
		RPMissionResults result = (RPMissionResults)binaryFormatter.Deserialize(gZipStream);
		gZipStream.Close();
		return result;
	}

	public void Save()
	{
		string path = Path.Combine(GetRPMissionsDirectory(), mMissionStart.ToString("yyyy-MM-dd HH-mm-ss.ffff") + ".rpm");
		using GZipStream gZipStream = new GZipStream(File.OpenWrite(path), CompressionMode.Compress);
		BinaryFormatter binaryFormatter = new BinaryFormatter();
		binaryFormatter.Serialize(gZipStream, this);
		gZipStream.Close();
	}

	private RPPlayer GetScoreReportingPlayer(RPPlayer player)
	{
		if (player is RPFootballPlayer)
		{
			RPFootballPlayer rPFootballPlayer = (RPFootballPlayer)player;
			if (rPFootballPlayer.PositionKey != "runner")
			{
				RPFootballMission rPFootballMission = (RPFootballMission)mMission;
				{
					foreach (RPFootballPlayer footballPlayer in rPFootballMission.FootballPlayers)
					{
						if (footballPlayer.PositionKey == "runner" && footballPlayer.TeamKey == rPFootballPlayer.TeamKey)
						{
							return footballPlayer;
						}
					}
					return player;
				}
			}
		}
		return player;
	}

	public int GetScore(RPPlayer player)
	{
		return GetScore(player, TimeSpan.MaxValue);
	}

	public int GetScore(RPPlayer player, TimeSpan gameTime)
	{
		RPPlayer scoreReportingPlayer = GetScoreReportingPlayer(player);
		if (gameTime == TimeSpan.MaxValue && mFinalScores.ContainsKey(scoreReportingPlayer))
		{
			return mFinalScores[scoreReportingPlayer];
		}
		int result = 1000;
		TimeSpan timeSpan = TimeSpan.MinValue;
		foreach (MissionEvent mEvent in mEvents)
		{
			if (mEvent is ScoreUpdateEvent && mEvent.ReportingPilot == scoreReportingPlayer && mEvent.GameTime > timeSpan && mEvent.GameTime <= gameTime)
			{
				result = ((ScoreUpdateEvent)mEvent).Score;
				timeSpan = mEvent.GameTime;
			}
		}
		return result;
	}

	public int GetFinalPlace(RPPlayer player)
	{
		int num = 1;
		int score = GetScore(player, TimeSpan.MaxValue);
		if (mMission is RPFootballMission)
		{
			RPFootballMission rPFootballMission = (RPFootballMission)mMission;
			RPFootballPlayer rPFootballPlayer = (RPFootballPlayer)player;
			{
				foreach (RPFootballPlayer footballPlayer in rPFootballMission.FootballPlayers)
				{
					if (footballPlayer.PositionKey == "runner" && footballPlayer.TeamKey != rPFootballPlayer.TeamKey && GetScore(footballPlayer, TimeSpan.MaxValue) > score)
					{
						num++;
					}
				}
				return num;
			}
		}
		foreach (RPPlayer player2 in mMission.Players)
		{
			if (player2 != player && GetScore(player2, TimeSpan.MaxValue) > score)
			{
				num++;
			}
		}
		return num;
	}

	public RPPlayer[][] GetChartOrder()
	{
		return GetChartOrder(TimeSpan.MaxValue);
	}

	public RPPlayer[][] GetChartOrder(TimeSpan gameTime)
	{
		List<Tuple<RPPlayer[], int>> list = new List<Tuple<RPPlayer[], int>>();
		if (mMission is RPFootballMission)
		{
			RPFootballMission rPFootballMission = (RPFootballMission)mMission;
			Dictionary<string, List<RPPlayer>> dictionary = new Dictionary<string, List<RPPlayer>>();
			foreach (RPFootballPlayer footballPlayer in rPFootballMission.FootballPlayers)
			{
				if (!dictionary.ContainsKey(footballPlayer.TeamKey))
				{
					dictionary.Add(footballPlayer.TeamKey, new List<RPPlayer>());
				}
				if (footballPlayer.PositionKey == "runner")
				{
					dictionary[footballPlayer.TeamKey].Insert(0, footballPlayer);
				}
				else
				{
					dictionary[footballPlayer.TeamKey].Add(footballPlayer);
				}
			}
			foreach (List<RPPlayer> value2 in dictionary.Values)
			{
				list.Add(new Tuple<RPPlayer[], int>(value2.ToArray(), GetScore(value2[0], gameTime)));
			}
		}
		else
		{
			foreach (RPPlayer player in Mission.Players)
			{
				list.Add(new Tuple<RPPlayer[], int>(new RPPlayer[1] { player }, GetScore(player, gameTime)));
			}
		}
		for (int i = 0; i < list.Count - 1; i++)
		{
			for (int j = i + 1; j < list.Count; j++)
			{
				if (list[i].B < list[j].B || (list[i].B == list[j].B && string.CompareOrdinal(list[i].A[0].Name, list[j].A[0].Name) > 0))
				{
					Tuple<RPPlayer[], int> value = list[i];
					list[i] = list[j];
					list[j] = value;
				}
			}
		}
		List<RPPlayer[]> list2 = new List<RPPlayer[]>();
		foreach (Tuple<RPPlayer[], int> item in list)
		{
			list2.Add(item.A);
		}
		return list2.ToArray();
	}

	public PrintDocument GetPrintDocument()
	{
		return new RPPrintDocument(this);
	}
}
