using System;
using GTANetworkAPI;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Types;
using ReallifeGamemode.Server.Util;

namespace ReallifeGamemode.Server.Events
{
  public class Vehicle : Script
  {
    [RemoteEvent("VehicleMenu_ToggleEngine")]
    public void VehicleMenuToggleEngineEvent(Player player)
    {
      if (player.IsInVehicle && player.VehicleSeat == 0)
      {
        player.TriggerEvent("CLIENT:SELECT_ROUTE");
        GTANetworkAPI.Vehicle v = player.Vehicle;

        User u = player.GetUser();
        if (u == null) return;

        if (NAPI.Entity.GetEntityVelocity(v).Length() > 1 && v.Class != 16)
        {
          player.SendNotification("~r~Der Motor kann nur im Stand betätigt werden.", true);
          return;
        }

        bool state = VehicleStreaming.GetEngineState(v);
        ServerVehicle sV = v.GetServerVehicle();
        if (sV != null)
        {
          if (sV is ShopVehicle)
          {
            VehicleStreaming.SetEngineState(v, false);
            return;
          }
          else if (sV is FactionVehicle fV)
          {
            if (fV.Model == VehicleHash.Burrito3 && u.FactionId == 1
            || fV.Model == VehicleHash.Burrito3 && u.FactionId == 3
            || fV.Model == VehicleHash.Burrito3 && u.FactionId == 7
            || fV.Model == VehicleHash.Burrito3 && u.FactionId == 8
            || fV.Model == VehicleHash.Policet && u.FactionId == 1
            || fV.Model == VehicleHash.Policet && u.FactionId == 3
            || fV.Model == VehicleHash.Policet && u.FactionId == 7
            || fV.Model == VehicleHash.Policet && u.FactionId == 8)
            {
              VehicleStreaming.SetEngineState(v, !state);
            }
            else if (!fV.GetOwners().Contains(u.FactionId ?? 0) && !state && !(u.IsAdmin(AdminLevel.HEADADMIN) && player.IsAdminDuty()))
            {
              player.SendNotification("~r~Du hast keinen Schlüssel.");
              return;
            }
          }
          else if (sV is GroupVehicle gV)
          {
            if (gV.GroupId != u.Group.Id && !state && !u.IsAdmin(AdminLevel.ADMIN3))
            {
              player.SendNotification("~r~Du hast keinen Schlüssel.");
              return;
            }
          }
          else if (sV is JobVehicle jV)
          {
            if (jV.JobId != player.GetUser().JobId && !state && !(u.IsAdmin(AdminLevel.HEADADMIN) && player.IsAdminDuty()))
            {
              player.SendNotification("~r~Du hast keinen Schlüssel.");
              return;
            }
            else
            {
              if (!jV.GetJob().GetUsersInJob().Contains(player) && !player.IsAdminDuty())
              {
                player.SendNotification("~y~[JOB] ~w~Du musst den Job vorher starten!");
                return;
              }
              else
              {
                /*if(player.IsAdminDuty())
                {
                  player.SendChatMessage("");
                }*/
                if (jV.JobId == 3 && player.GetUser().JobId == 3 && jV.GetJob().GetUsersInJob().Contains(player))
                {
                  Job.PilotJob c = new Job.PilotJob();
                  if ((VehicleHash)jV.Model == VehicleHash.Cuban800 && !state)
                  {
                    if (!player.HasData("HatRoute") || player.GetData<bool>("HatRoute") == false)
                    {
                      player.SetData("HatRoute", true);
                      c.StartPilotRoute(player, "RouteStart");
                    }
                  }
                  if ((VehicleHash)jV.Model == VehicleHash.Velum && !state || (VehicleHash)jV.Model == VehicleHash.Velum2 && !state)
                  {
                    if (player.GetUser().PilotSkill >= 300)
                    {
                      if (!player.HasData("HatRoute") || player.GetData<bool>("HatRoute") == false)
                      {
                        player.SetData("HatRoute", true);
                        c.StartPilotRoute(player, "RouteStart");
                      }
                    }
                    else
                    {
                      player.SendNotification("~y~[JOB] ~r~Du besitzt nicht das nötige Skilllevel(2) ");
                      return;
                    }
                  }
                }
                if (jV.JobId == 4 && player.GetUser().JobId == 4 && jV.GetJob().GetUsersInJob().Contains(player))
                {
                  Job.BusDriverJob c = new Job.BusDriverJob();
                  if ((VehicleHash)jV.Model == VehicleHash.Bus && !state)
                  {
                    if (!player.HasData("HatRoute") || player.GetData<bool>("HatRoute") == false)
                    {
                      player.SetData("HatRoute", true);
                      c.StartBusRoute(player, "RouteStart");
                      player.TriggerEvent("CLIENT:PlaySound", "jobs/busfahrer/StartJob", "wav", 45);
                    }
                  }
                  if ((VehicleHash)jV.Model == VehicleHash.Coach && !state)
                  {
                    if (player.GetUser().BusSkill >= 300)
                    {
                      if (!player.HasData("HatRoute") || player.GetData<bool>("HatRoute") == false)
                      {
                        player.SetData("HatRoute", true);
                        c.StartBusRoute(player, "RouteStart");
                        player.TriggerEvent("CLIENT:PlaySound", "jobs/busfahrer/StartJob", "wav", 45);
                      }
                    }
                    else
                    {
                      player.SendNotification("~y~[JOB] ~r~Du besitzt nicht das nötige Skilllevel(2) ");
                      return;
                    }
                  }
                  if ((VehicleHash)jV.Model == VehicleHash.Tourbus && !state)
                  {
                    if (player.GetUser().BusSkill >= 800)
                    {
                      if (!player.HasData("HatRoute") || player.GetData<bool>("HatRoute") == false)
                      {
                        player.SetData("HatRoute", true);
                        c.StartBusRoute(player, "RouteStart");
                        player.TriggerEvent("CLIENT:PlaySound", "jobs/busfahrer/StartJob", "wav", 45);
                      }
                    }
                    else
                    {
                      player.SendNotification("~y~[JOB] ~r~Du besitzt nicht das nötige Skilllevel(3) ");
                      return;
                    }
                  }
                }
              }
            }
          }
          else if (sV is UserVehicle uV)
          {
            if (uV.UserId != u.Id)
            {
              return;
            }
          }
        }
        VehicleStreaming.SetEngineState(v, !state);

      }
    }

    [RemoteEvent("VehicleMenu_LockCar")]
    public static void VehicleMenuLockCarEvent(Player player)
    {
      if (player.IsInVehicle && player.VehicleSeat == 0)
      {
        GTANetworkAPI.Vehicle v = player.Vehicle;

        User u = player.GetUser();
        if (u == null) return;

        bool state = VehicleStreaming.GetLockState(v);
        ServerVehicle sV = v.GetServerVehicle();

        if (sV != null)
        {
          if (sV is ShopVehicle)
          {
            VehicleStreaming.SetEngineState(v, false);
            return;
          }
          else if (sV is FactionVehicle fV)
          {
            if (!fV.GetOwners().Contains(u.FactionId ?? 0))
            {
              return;
            }
          }
          else if (sV is UserVehicle uV)
          {
            if (uV.UserId != u.Id)
            {
              player.SendNotification("~r~Du hast keinen Schlüssel.");
              return;
            }
          }
          else if (sV is JobVehicle)
          {
            return;
          }
          else if (sV is SchoolVehicle)
          {
            return;
          }
        }
        state = !state;
        VehicleStreaming.SetLockStatus(v, state);
        string msg = "Fahrzeug ";
        msg += state ? "~r~abgeschlossen" : "~g~aufgeschlossen";
        player.TriggerEvent("vehsync:OpenCar", state);
        using (var dbContext = new DatabaseContext())
        {
          ServerVehicle carlocked = v.GetServerVehicle(dbContext);

          if(state == true)
          { 
            carlocked.Locked = true;
            dbContext.SaveChanges();
          }
          else
          {
            carlocked.Locked = false;
            dbContext.SaveChanges();
          }
        }
          player.SendNotification(msg);
      }
      else if (!player.IsInVehicle)
      {
        GTANetworkAPI.Vehicle vehicle = null;
        foreach (var veh in NAPI.Pools.GetAllVehicles())
        {
          if (player.Position.DistanceTo(veh.Position) <= 3f)
          {
            vehicle = veh;
            break;
          }
        }

        if (vehicle == null)
          return;
        User u = player.GetUser();
        if (u == null) return;

        bool state = VehicleStreaming.GetLockState(vehicle);
        ServerVehicle sV = vehicle.GetServerVehicle();

        if (sV != null)
        {
          if (sV is ShopVehicle)
          {
            VehicleStreaming.SetEngineState(vehicle, false);
            return;
          }
          else if (sV is FactionVehicle fV)
          {
            if (!fV.GetOwners().Contains(u.FactionId ?? 0))
            {
              return;
            }
          }
          else if (sV is UserVehicle uV)
          {
            if (uV.UserId != u.Id)
            {
              return;
            }
          }
          else if (sV is JobVehicle)
          {
            return;
          }
        }
        state = !state;
        VehicleStreaming.SetLockStatus(vehicle, state);
        string msg = "Fahrzeug ";
        msg += state ? "~r~abgeschlossen" : "~g~aufgeschlossen";
        player.TriggerEvent("vehsync:OpenCar", state);
        using (var dbContext = new DatabaseContext())
        {
          ServerVehicle carlocked = vehicle.GetServerVehicle(dbContext);

          if (state == true)
          {
            carlocked.Locked = true;
            dbContext.SaveChanges();
          }
          else
          {
            carlocked.Locked = false;
            dbContext.SaveChanges();
          }
        }
        player.SendNotification(msg);
      }
    }

    [RemoteEvent("CLIENT:VehicleMenu_ParkCar")]
    public void VehicleMenuParkCarEvent(Player player)
    {
      if (player.IsInVehicle && player.VehicleSeat == 0)
      {
        GTANetworkAPI.Vehicle v = player.Vehicle;

        User u = player.GetUser();
        if (u == null) return;

        using (var dbContext = new DatabaseContext())
        {
          ServerVehicle sV = v.GetServerVehicle(dbContext);

          if (sV == null) return;

          if (sV is UserVehicle uV)
          {
            if (uV.UserId != u.Id)
            {
              player.SendNotification("~r~Du darfst dieses Fahrzeug nicht parken.");
              return;
            }
          }
          else if (sV is FactionVehicle fV)
          {
            if (!fV.GetOwners().Contains(u.FactionId ?? 0) || !u.FactionLeader)
            {
              player.SendNotification("~r~Du darfst dieses Fahrzeug nicht parken.");
              return;
            }
          }
          else if (sV is GroupVehicle gV)
          {
            if (gV.GroupId != u.Group.Id || u.GroupRank < GroupRank.MANAGER)
            {
              player.SendNotification("~r~Du darfst dieses Fahrzeug nicht parken.");
              return;
            }
          }
          else if (sV is JobVehicle)
          {
            player.SendNotification("~r~Du darfst dieses Fahrzeug nicht parken.");
            return;
          }
          else if (sV is SchoolVehicle)
          {
            player.SendNotification("~r~Du darfst dieses Fahrzeug nicht parken.");
            return;
          }

          Vector3 pos = v.Position;

          sV.PositionX = pos.X;
          sV.PositionY = pos.Y;
          sV.PositionZ = pos.Z;
          sV.Heading = v.Heading;

          player.SendNotification("~g~Das Fahrzeug wurde geparkt.");

          dbContext.SaveChanges();
        }
      }
    }

    [RemoteEvent("VehicleMenu_ToggleSingleDoor")]
    public void VehicleMenuToggleSingleDoorEvent(Player player, int door)
    {
      if (!player.IsInVehicle) return;
      GTANetworkAPI.Vehicle veh = player.Vehicle;

      DoorID doorId = (DoorID)door;

      DoorState state = VehicleStreaming.GetDoorState(veh, doorId);

      VehicleStreaming.SetDoorState(veh, doorId, state == DoorState.DoorOpen ? DoorState.DoorClosed : DoorState.DoorOpen);
    }

    [RemoteEvent("VehicleMenu_OpenAllDoors")]
    public void VehicleMenuOpenAllDoorsEvent(Player player)
    {
      if (!player.IsInVehicle) return;
      GTANetworkAPI.Vehicle veh = player.Vehicle;

      foreach (DoorID doorId in Enum.GetValues(typeof(DoorID)))
      {
        VehicleStreaming.SetDoorState(veh, doorId, DoorState.DoorOpen);
      }
    }

    [RemoteEvent("VehicleMenu_CloseAllDoors")]
    public void VehicleMenuCloseAllDoorsEvent(Player player)
    {
      if (!player.IsInVehicle) return;
      GTANetworkAPI.Vehicle veh = player.Vehicle;

      foreach (DoorID doorId in Enum.GetValues(typeof(DoorID)))
      {
        VehicleStreaming.SetDoorState(veh, doorId, DoorState.DoorClosed);
      }
    }
  }
}
