using System.Collections.Generic;
using System.Linq;
using GTANetworkAPI;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Job;
using ReallifeGamemode.Server.Managers;

namespace ReallifeGamemode.Server.Util
{
  public static class CheckPointHandle
  {
    public static int PilotSkill1RouteVerdienst = 1100;
    public static int PilotSkill2RouteVerdienst = 1500;
    public static List<CheckPointListForPlayer> listHandle = new List<CheckPointListForPlayer>();

    public static void DeleteCheckpoints(Player player)
    {
      RemovePlayerHandlerFromList(player);
      player.TriggerEvent("destroyCP");
    }

    public static void StartCheckPointRoute(this Player player, IEnumerable<Vector3> nListCps, int delay, int markerID, int markerSize, int markerDist, bool useVehicle, string nEvent)
    {
      RemovePlayerHandlerFromList(player);
      CheckPointListForPlayer playerHandle = new CheckPointListForPlayer(player, nListCps, delay, markerID, markerSize, markerDist, useVehicle, nEvent);
      playerHandle.DeleteCheckpoints();

      listHandle.Add(playerHandle);
      playerHandle.StartRoute();
    }

    public static void RemovePlayerHandlerFromList(this Player player)
    {
      for (int a = 0; a < listHandle.Count; a++)
      {
        CheckPointListForPlayer temp = listHandle[a];
        if (temp.player == player)
        {
          listHandle.Remove(temp);
        }
      }
    }
  }

  public class CheckPointListForPlayer
  {
    public int LastCheckpoint;
    public IEnumerable<Vector3> list = new List<Vector3>();
    public Player player;
    public int delay = 0;
    public int markerID;
    public int markerSize;
    public int markerDist;
    public bool useVehicle;
    public string eventInCheckpoint = "";

    public int checkPointsDone = 0;

    public CheckPointListForPlayer(Player nPlayer, IEnumerable<Vector3> nList, int nDelay, int nMarkerID, int nMarkerSize, int nMarkerDist, bool nUseVehicle, string nEvent)
    {
      this.player = nPlayer;
      this.list = nList;
      this.delay = nDelay;
      this.markerID = nMarkerID;
      this.markerSize = nMarkerSize;
      this.markerDist = nMarkerDist;
      this.useVehicle = nUseVehicle;
      this.eventInCheckpoint = nEvent;
      this.checkPointsDone = 0;
    }

    public void StartRoute()
    {
      player.TriggerEvent("setCheckPoint", this.list.ElementAt(0), player, 0, this.delay, this.markerID, this.markerSize, this.markerDist, this.useVehicle, this.eventInCheckpoint);
    }

    public void NextCheckpoint()
    {
      this.checkPointsDone++;
      if (this.list.Count() > checkPointsDone)
      {
        LastCheckpoint = 0;
        Vector3 nextCp = list.ElementAt(checkPointsDone);
        this.player.TriggerEvent("setCheckPoint", nextCp, player, this.checkPointsDone, delay, this.markerID, this.markerSize, this.markerDist, this.useVehicle, this.eventInCheckpoint);
      }
      if (checkPointsDone == this.list.Count() - 1)
      {
        LastCheckpoint = 1;
      }
      if (this.list.Count() == checkPointsDone)
      {
        LastCheckpoint = 0;
        CheckPointHandle.RemovePlayerHandlerFromList(this.player);
        DeleteCheckpoints();

        JobBase job = JobManager.GetJob(player.GetUser().JobId ?? -1);
        if (job != null && job.GetUsersInJob().Contains(player))
          job.LastCheckpoint(player);
      }
      //NAPI.Chat.SendChatMessageToAll($"this.list.Count() = {this.list.Count()}, checkPointsDone = {checkPointsDone}, LastCheckpoint = {LastCheckpoint}");
    }

    public void DeleteCheckpoints()
    {
      this.player.TriggerEvent("destroyCP");
    }
  }

  public class CheckPointEvents : Script
  {
    [RemoteEvent("playerWaitsInCheckpoint")]
    public void PlayerWaitsInCheckpoint(Player player)
    {
      JobBase job = JobManager.GetJob(player.GetUser().JobId ?? -1);
      if (job == null || !job.GetUsersInJob().Contains(player))
        return;

      if (job.Id == JobManager.GetJob<BusDriverJob>().Id)
        JobManager.GetJob<BusDriverJob>().AtBusStop(player);
    }

    [RemoteEvent("playerInCheckpoint")]
    public void PlayerInCheckpoint(Player user)
    {
      CheckPointListForPlayer temp = null;
      for (int a = 0; a < CheckPointHandle.listHandle.Count; a++)
      {
        temp = CheckPointHandle.listHandle[a];
        if (temp.player == user)
        {
          break;
        }
      }
      if (temp.LastCheckpoint != 1)
      {
        if (!user.IsInVehicle || user.VehicleSeat != 0) return;
        Vehicle veh = user.Vehicle;
        if (!(veh.GetData<IndicatorData>("indicatorData") is IndicatorData data)) data = new IndicatorData();
        data.Left = false;
        data.Right = false;
        veh.SetData("indicatorData", data);
        NAPI.ClientEvent.TriggerClientEventForAll("SERVER:setIndicatorStatus", veh.Handle.Value, data.Left, data.Right);
        //BusCheckpoint(user);
      }

      temp.NextCheckpoint();
    }
  }
}
