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


namespace ReallifeGamemode.Server.Util
{
  public class CheckPointHandle : Script
  {
    public int BusSkill1RouteVerdienst = 500;
    public int BusSkill2RouteVerdienst = 650;
    public int BusSkill3RouteVerdienst = 800;
    public int PilotSkill1RouteVerdienst = 550;
    public int PilotSkill2RouteVerdienst = 750;
    public static List<CheckPointListForPlayer> listHandle = new List<CheckPointListForPlayer>();

    public static void DeleteCheckpoints(Player player)
    {
      player.SetData("HatRoute", false);
      player.ResetData("Route");
      RemovePlayerHandlerFromList(player);
      player.TriggerEvent("destroyCP");
    }

    public static void StartCheckPointRoute(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);
      player.ResetData("Route");
      playerHandle.StartRoute();

      player.SetData("HatRoute", true);
      /*if(player.GetUser().BusSkill >= 1000)
      {
        playerHandle.LastCheckpoint = 2;
      }*/
    }

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

    [RemoteEvent("playerWaitsInCheckpoint")]
    public void PlayerWaitsInCheckpoint(Player user)
    {
      if (user.GetUser().JobId == 4)
      {
        Job.JobBase job = Managers.JobManager.GetJob(user.GetUser().JobId ?? -1);
        if (job.GetUsersInJob().Contains(user))
        {
          if (!user.IsInVehicle || user.VehicleSeat != 0) return;
          Vehicle veh = user.Vehicle;
          user.TriggerEvent("CLIENT:FreezeVehicle", veh);
          user.TriggerEvent("CLIENT:UnFreezeVehicle", veh);
          user.TriggerEvent("CLIENT:PlaySound", "jobs/busfahrer/AnfahrtHaltestelle", "wav", 50);
          if ((VehicleHash)veh.Model == VehicleHash.Bus)
          {
            user.TriggerEvent("CLIENT:SetDoorOpen", 0, false, false);
            user.TriggerEvent("CLIENT:SetDoorOpen", 1, false, false);
            user.TriggerEvent("CLIENT:SetDoorOpen", 2, false, false);
            user.TriggerEvent("CLIENT:SetDoorOpen", 3, false, false);
            user.TriggerEvent("CLIENT:SetDoorOpen", 0, false, false);
            NAPI.Task.Run(() =>
            {
              BusCheckpoint(user);
            }, delayTime: 3600);
          }
          if ((VehicleHash)veh.Model == VehicleHash.Coach)
          {
            user.TriggerEvent("CLIENT:SetDoorOpen", 0, false, false);
            NAPI.Task.Run(() =>
            {
              BusCheckpoint(user);
            }, delayTime: 2800);
          }
          if ((VehicleHash)veh.Model == VehicleHash.Tourbus)
          {
            user.TriggerEvent("CLIENT:SetDoorOpen", 2, false, false);
            user.TriggerEvent("CLIENT:SetDoorOpen", 3, false, false);
            NAPI.Task.Run(() =>
            {
              BusCheckpoint(user);
            }, delayTime: 3250);
          }
          if (!(veh.GetData<IndicatorData>("indicatorData") is IndicatorData data)) data = new IndicatorData();
          data.Left = false;
          data.Right = true;
          veh.SetData("indicatorData", data);
          NAPI.ClientEvent.TriggerClientEventForAll("SERVER:setIndicatorStatus", veh.Handle.Value, data.Left, data.Right);
          /*NAPI.Task.Run(() =>
          {
            veh.Position = new Vector3(veh.Position.X, veh.Position.Y, veh.Position.Z + 0.25);
          }, delayTime: 500);*/
          NAPI.Task.Run(() =>
          {
            veh.Position = new Vector3(veh.Position.X, veh.Position.Y, veh.Position.Z + 0.1);
            user.TriggerEvent("CLIENT:FreezeVehicle", veh);
          }, delayTime: 500);
        }
      }
    }
    public static void BusCheckpoint(Player user)
    {
      if (!user.IsInVehicle || user.VehicleSeat != 0) return;
      Vehicle veh = user.Vehicle;
      if ((VehicleHash)veh.Model == VehicleHash.Bus)
      {
        user.TriggerEvent("CLIENT:PlaySound", "jobs/busfahrer/AbfahrtHaltestelleBus", "wav", 25);
        user.TriggerEvent("CLIENT:SetDoorShutDelayed", 0, false, 1850);
        user.TriggerEvent("CLIENT:SetDoorShutDelayed", 1, false, 1850);
        user.TriggerEvent("CLIENT:SetDoorShutDelayed", 2, false, 1850);
        user.TriggerEvent("CLIENT:SetDoorShutDelayed", 3, false, 1850);
        user.TriggerEvent("CLIENT:SetDoorShutDelayed", 0, false, 1850);
        NAPI.Task.Run(() =>
        {
          user.TriggerEvent("CLIENT:UnFreezeVehicle", veh);
        }, delayTime: 1850);
      }
      if ((VehicleHash)veh.Model == VehicleHash.Coach)
      {
        user.TriggerEvent("CLIENT:PlaySound", "jobs/busfahrer/AbfahrtHaltestelleCoach", "wav", 35);
        user.TriggerEvent("CLIENT:SetDoorShutDelayed", 0, false, 1000);
        NAPI.Task.Run(() =>
        {
          user.TriggerEvent("CLIENT:UnFreezeVehicle", veh);
        }, delayTime: 1000);
      }
      if ((VehicleHash)veh.Model == VehicleHash.Tourbus)
      {
        user.TriggerEvent("CLIENT:PlaySound", "jobs/busfahrer/AbfahrtHaltestelleTourbus", "wav", 25);
        user.TriggerEvent("CLIENT:SetDoorShutDelayed", 3, false, 2600);
        user.TriggerEvent("CLIENT:SetDoorShutDelayed", 2, false, 2600);
        user.TriggerEvent("CLIENT:SetDoorShutDelayed", 3, false, 2600);
        NAPI.Task.Run(() =>
        {
          user.TriggerEvent("CLIENT:UnFreezeVehicle", veh);
        }, delayTime: 2600);
      }
      //user.TriggerEvent("CLIENT:UnFreezeVehicle", veh);
    }

    [RemoteEvent("playerInCheckpoint")]
    public void PlayerInCheckpoint(Player user)
    {
      CheckPointListForPlayer temp = null;
      for (int a = 0; a < listHandle.Count; a++)
      {
        temp = listHandle[a];
        if (temp.player == user)
        {
          break;
        }
      }
      if (temp.LastCheckpoint != 1)
      {
        Job.JobBase job = Managers.JobManager.GetJob(user.GetUser().JobId ?? -1);
        if (job?.GetUsersInJob().Contains(user) ?? false)
        {
          if (user.GetUser().JobId == 3)
          {
            if (temp.checkPointsDone == 2)
            {
              if (user.GetData<string>("Route") == "Skill1Route1" || user.GetData<string>("Route") == "Skill1Route2" || user.GetData<string>("Route") == "Skill1Route3")
              {
                BusDriverJob.payWage(user, PilotSkill1RouteVerdienst / temp.list.Count());
                BusDriverJob.payWage(user, PilotSkill1RouteVerdienst / temp.list.Count());
              }
              if (user.GetData<string>("Route") == "Skill2Route1" || user.GetData<string>("Route") == "Skill2Route2" || user.GetData<string>("Route") == "Skill2Route3")
              {
                BusDriverJob.payWage(user, PilotSkill2RouteVerdienst / temp.list.Count());
                BusDriverJob.payWage(user, PilotSkill2RouteVerdienst / temp.list.Count());
              }
            }
            if (temp.checkPointsDone > 2)
            {
              if (user.GetData<string>("Route") == "Skill1Route1" || user.GetData<string>("Route") == "Skill1Route2" || user.GetData<string>("Route") == "Skill1Route3")
              {
                BusDriverJob.payWage(user, PilotSkill1RouteVerdienst / temp.list.Count());
              }
              if (user.GetData<string>("Route") == "Skill2Route1" || user.GetData<string>("Route") == "Skill2Route2" || user.GetData<string>("Route") == "Skill2Route3")
              {
                BusDriverJob.payWage(user, PilotSkill2RouteVerdienst / temp.list.Count());
              }
            }
            //PilotJob.payWage(user, 100);
          }
          if (user.GetUser().JobId == 4)
          {
            if (temp.checkPointsDone == 2)
            {
              if (user.GetData<string>("Route") == "Skill1Route1" || user.GetData<string>("Route") == "Skill1Route2" || user.GetData<string>("Route") == "Skill1Route3" || user.GetData<string>("Route") == "Skill1Route4")
              {
                BusDriverJob.payWage(user, BusSkill1RouteVerdienst / temp.list.Count());
                BusDriverJob.payWage(user, BusSkill1RouteVerdienst / temp.list.Count());
              }
              if (user.GetData<string>("Route") == "Skill2Route1" || user.GetData<string>("Route") == "Skill2Route2" || user.GetData<string>("Route") == "Skill2Route3" || user.GetData<string>("Route") == "Skill2Route4")
              {
                BusDriverJob.payWage(user, BusSkill2RouteVerdienst / temp.list.Count());
                BusDriverJob.payWage(user, BusSkill2RouteVerdienst / temp.list.Count());
              }
              if (user.GetData<string>("Route") == "Skill3Route1" || user.GetData<string>("Route") == "Skill3Route2" || user.GetData<string>("Route") == "Skill3Route3" || user.GetData<string>("Route") == "Skill3Route4")
              {
                BusDriverJob.payWage(user, BusSkill3RouteVerdienst / temp.list.Count());
                BusDriverJob.payWage(user, BusSkill3RouteVerdienst / temp.list.Count());
              }
            }
            if (temp.checkPointsDone > 2)
            {
              if (user.GetData<string>("Route") == "Skill1Route1" || user.GetData<string>("Route") == "Skill1Route2" || user.GetData<string>("Route") == "Skill1Route3" || user.GetData<string>("Route") == "Skill1Route4")
              {
                BusDriverJob.payWage(user, BusSkill1RouteVerdienst / temp.list.Count());
              }
              if (user.GetData<string>("Route") == "Skill2Route1" || user.GetData<string>("Route") == "Skill2Route2" || user.GetData<string>("Route") == "Skill2Route3" || user.GetData<string>("Route") == "Skill2Route4")
              {
                BusDriverJob.payWage(user, BusSkill2RouteVerdienst / temp.list.Count());
              }
              if (user.GetData<string>("Route") == "Skill3Route1" || user.GetData<string>("Route") == "Skill3Route2" || user.GetData<string>("Route") == "Skill3Route3" || user.GetData<string>("Route") == "Skill3Route4")
              {
                BusDriverJob.payWage(user, BusSkill3RouteVerdienst / temp.list.Count());
              }
            }
            //BusDriverJob.payWage(user, 100);
            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);
          }
        }
      }
      else
      {
      }
      temp.NextCheckpoint();
    }
  }

  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();
        player.SetData("HatRoute", false);
        if (player.GetUser().JobId == 3 && player.HasData("Route"))
        {
          //PilotJob.payWage(player, 200);
          PilotJob.PilotLetzterCheckpoint(player);
        }
        else if (player.GetUser().JobId == 4 && player.HasData("Route"))
        {
          //BusDriverJob.payWage(player, 200);
          //CheckPointHandle.BusCheckpoint(player);
          BusDriverJob.BusLetzterCheckpoint(player);
          if (!player.IsInVehicle || player.VehicleSeat != 0) return;
          Vehicle veh = player.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);
        }
      }
      //NAPI.Chat.SendChatMessageToAll($"this.list.Count() = {this.list.Count()}, checkPointsDone = {checkPointsDone}, LastCheckpoint = {LastCheckpoint}");
    }

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