using System;

namespace TeslaConsole.RedPlanet;

internal class RPMissionRecorder
{
	private RPMissionResults mMissionResults;

	private bool mStartSet;

	public RPMissionRecorder(RPMission mission)
	{
		mMissionResults = new RPMissionResults(mission);
	}

	public void SetMissionStart()
	{
		if (mStartSet)
		{
			throw new InvalidOperationException();
		}
		mMissionResults.mMissionStart = DateTime.Now;
		mStartSet = true;
	}

	private void ValidatePlayer(RPPlayer player, string param)
	{
		if (player == null)
		{
			throw new ArgumentNullException(param);
		}
		foreach (RPPlayer player2 in mMissionResults.Mission.Players)
		{
			if (player2 == player)
			{
				return;
			}
		}
		throw new ArgumentException(param);
	}

	private TimeSpan GetMissionTime()
	{
		if (!mStartSet)
		{
			return TimeSpan.Zero;
		}
		return DateTime.Now - mMissionResults.mMissionStart;
	}

	public void PlayerScored(RPPlayer reportingPlayer)
	{
		ValidatePlayer(reportingPlayer, "reportingPlayer");
		TimeSpan missionTime = GetMissionTime();
		mMissionResults.mEvents.Add(new ScoredEvent(reportingPlayer, missionTime));
	}

	public void PlayerKilled(RPPlayer reportingPlayer, RPPlayer killer)
	{
		ValidatePlayer(reportingPlayer, "reportingPlayer");
		ValidatePlayer(killer, "killer");
		TimeSpan missionTime = GetMissionTime();
		mMissionResults.mEvents.Add(new KilledEvent(reportingPlayer, missionTime, killer));
	}

	public void PlayerBoost(RPPlayer reportingPlayer, int boosterOn)
	{
		ValidatePlayer(reportingPlayer, "reportingPlayer");
		TimeSpan missionTime = GetMissionTime();
		mMissionResults.mEvents.Add(new BoostEvent(reportingPlayer, missionTime, boosterOn));
	}

	public void PlayerScoreUpdate(RPPlayer reportingPlayer, int score)
	{
		ValidatePlayer(reportingPlayer, "reportingPlayer");
		TimeSpan missionTime = GetMissionTime();
		mMissionResults.mEvents.Add(new ScoreUpdateEvent(reportingPlayer, missionTime, score));
	}

	public void PlayerDamaged(RPPlayer reportingPlayer, RPPlayer damager, int damageLoss, int pointsTransfered)
	{
		ValidatePlayer(reportingPlayer, "reportingPlayer");
		ValidatePlayer(damager, "damager");
		TimeSpan missionTime = GetMissionTime();
		mMissionResults.mEvents.Add(new DamagedEvent(reportingPlayer, missionTime, damager, damageLoss, pointsTransfered));
	}

	public void PlayerFinalScore(RPPlayer reportingPlayer, int finalScore)
	{
		ValidatePlayer(reportingPlayer, "reportingPlayer");
		mMissionResults.mFinalScores.Add(reportingPlayer, finalScore);
	}

	public RPMissionResults EndMission(TimeSpan missionLength)
	{
		mMissionResults.mActuallMissionTime = missionLength;
		RPMissionResults result = mMissionResults;
		mMissionResults = null;
		return result;
	}
}
