using System;
using System.Collections.Generic;
using System.Text;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Util;
using ReallifeGamemode.Server.Services;
using System.Linq;
using GTANetworkAPI;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Managers;

namespace ReallifeGamemode.Server.DrivingSchool
{
  class DrivingSchool : Script
  {
    private static TextLabel informationLabel;
    private static Marker marker;
    private static ColShape _colShape;
    public static Vector3 Position { get; }

    private readonly IReadOnlyCollection<Vector3> BikeRoute = new List<Vector3>
      {
        new Vector3(-741.98, -1283.46, 4.17),
        new Vector3(-702.49, -1246.57, 8.89),
        new Vector3(-659.88, -1506.23, 9.94),
        new Vector3(-423.72, -1770.7, 19.13),
        new Vector3(-265.74, -1453.66, 29.74),
        new Vector3(51.22, -1370.96, 27.84),
        new Vector3(161.51, -1246.64, 36.5),
        new Vector3(702.39, -1247.82, 33.98),
        new Vector3(779.54, -1245.7, 25.08),
        new Vector3(719.58, -1153.01, 31.75),
        new Vector3(-233.65, -1133.09, 21.52),
        new Vector3(-511.5, -1079.99, 21.37),
        new Vector3(-707.52, -1239.48, 8.91),
       }.AsReadOnly();

    private readonly IReadOnlyCollection<Vector3> StopBike = new List<Vector3>
      {
        new Vector3(-813.57, -1290.37, 4.59),
       }.AsReadOnly();
    private readonly IReadOnlyCollection<Vector3> DrivingRoute = new List<Vector3>
      {
        //BEGIN
        new Vector3(-745.6191, -1285.735, 3.947221),
        new Vector3(-704.5242, -1246.765, 8.885977),
        new Vector3(-673.0675, -1266.652, 9.29717),
        new Vector3(-646.1747, -1293.238, 9.28384),
        new Vector3(-510.7098, -916.9164, 24.10735),
        new Vector3(-492.6284, -860.5167, 28.89526),
        new Vector3(-450.3232, -841.7007, 29.3698),
        new Vector3(17.09636, -973.2763, 28.01929),
        new Vector3(76.66012, -999.568, 27.97918),
        //SLALOM
        new Vector3(-12.64976, -1751.287, 27.91913),
        new Vector3(6.008641, -1767.067, 27.91265),
        new Vector3(12.80635, -1752.094, 27.91877),
        new Vector3(26.71735, -1747.96, 27.92006),
        new Vector3(28.67053, -1733.492, 27.91953),
        new Vector3(42.68731, -1728.767, 27.92002),
        new Vector3(44.33229, -1714.426, 27.9193),
        new Vector3(37.25899, -1723.924, 27.92041),
        new Vector3(34.591, -1738.211, 27.92125),
        new Vector3(21.28996, -1742.563, 27.91987),
        new Vector3(18.46534, -1756.87, 27.92011),
        new Vector3(4.841759, -1761.316, 27.91519),
        new Vector3(44.69115, -1805.247, 24.07369),
        new Vector3(111.6519, -1822.466, 25.03703),
        //AUTOBAHN-ENDE
        new Vector3(-46.37, -1808.27, 26.25),
        new Vector3(-255.55, -1419.48, 30.75),
        new Vector3(-369.08, -1415.37, 27.68),
        new Vector3(-114.48, -1251.43, 35.59),
        new Vector3(59.22, -1261.71, 27.84),
        new Vector3(39.12, -1165.28, 27.87),
        new Vector3(-307.52, -1200.85, 35.79),
        new Vector3(-441.79, -1251.67, 44.37),
        new Vector3(-463.77, -1405.07, 27.71),
        new Vector3(-617.66, -1259.34, 9.82),
        new Vector3(-758.35, -1285.03, 3.48),
      }.AsReadOnly();
    private readonly IReadOnlyCollection<Vector3> StopCar = new List<Vector3>
      {
      new Vector3(-788.66, -1278.75, 4),
      }.AsReadOnly();


    public static void Setup()
    {
      informationLabel = NAPI.TextLabel.CreateTextLabel("Fahrschule\n~y~Auto ~s~- $~g~2500\n~y~Motorrad ~s~- $~g~3500", new Vector3(-813.17, -1354.5, 5.14), 20.0f, 1.3f, 0, new Color(255, 255, 255));
      marker = NAPI.Marker.CreateMarker(MarkerType.VerticalCylinder, new Vector3(-813.17, -1354.5, 4.14), new Vector3(), new Vector3(), 1f, new Color(255, 255, 255));

      _colShape = NAPI.ColShape.CreateSphereColShape(new Vector3(-813.17, -1354.5, 5.14), 3f);
      _colShape.OnEntityEnterColShape += EntityEnterBusinessColShape;
      _colShape.OnEntityExitColShape += EntityExitBusinessColShape;
      NAPI.Blip.CreateBlip(545, new Vector3(-813.17, -1354.5, 5.14), 1.0f, 4, "Fahrschule", shortRange: true);
    }

    private static void EntityEnterBusinessColShape(ColShape colShape, Player client)
    {
      if (client.IsInVehicle || !client.IsLoggedIn()) return;

      client.TriggerEvent("drivingSchoolMenu");
    }

    private static void EntityExitBusinessColShape(ColShape colShape, Player client)
    {
      client.TriggerEvent("removeDrivingSchoolMenu");
    }

    [RemoteEvent("startDrivingSchool")]
    public void StartDrivingSchool(Player client)
    {
      User user = client.GetUser();
      if (user.DriverLicenseVehicle || client.HasData("ActiveSchool"))
        return;

      if (user.Handmoney < 2500)
      {
        client.SendNotification("~r~Du brauchst ~g~$2500~r~ auf der Hand um die Prüfung zu starten.", true);
        return;
      }

      using (var dbContext = new DatabaseContext())
      {
        User payer = client.GetUser(dbContext);
        payer.Handmoney -= 2500;
        client.TriggerEvent("SERVER:SET_HANDMONEY", payer.Handmoney);
        dbContext.SaveChanges();
      }

      client.SetData("ActiveSchool", 0);
      client.TriggerEvent("renderTextOnScreen", "Sie haben die Führerscheinprüfung gestartet. Steigen Sie in eines der Fahrschulautos ein.");
      client.TriggerEvent("waitPlayerEntersVehicle");
    }

    [RemoteEvent("timerCheckVehicle")]
    public void TimerCheckVehicle(Player user)
    {
      Vehicle veh = user.Vehicle;

      if (veh.GetServerVehicle() is SchoolVehicle schoolVehicle)
      {
        if (schoolVehicle.SchoolId == 0 && user.IsInVehicle)
        {
          user.TriggerEvent("renderTextOnScreen", "Gut nun kann die Prüfung losgehen.");
          user.TriggerEvent("stopTimer");
          CheckPointHandle.StartCheckPointRoute(user, DrivingRoute, 0, 1, 7, "drivingSchoolEvent");
        }
        if (schoolVehicle.SchoolId == 2 && user.IsInVehicle)
        {
          user.TriggerEvent("renderTextOnScreen", "Gut nun kann die Prüfung losgehen.");
          user.TriggerEvent("stopTimer");
          CheckPointHandle.StartCheckPointRoute(user, BikeRoute, 0, 1, 7, "bikeSchoolEvent");
        }
      }
    }

    [RemoteEvent("drivingSchoolEventEnd")]
    public void DrivingSchoolEventEnd(Player user, int checkpoint)
    {
      user.TriggerEvent("renderTextOnScreen", "Du hast den Führerschein bestanden. Glückwunsch!");
      user.ResetData("ActiveSchool");
      using (var dbContext = new DatabaseContext())
      {
        User drivingUser = user.GetUser(dbContext);
        drivingUser.DriverLicenseVehicle = true;
        dbContext.SaveChanges();
      }

      Vehicle veh = user.Vehicle;
      user.WarpOutOfVehicle();
      ServerVehicle sVeh = VehicleManager.GetServerVehicleFromVehicle(veh);
      VehicleStreaming.SetEngineState(veh, false);
      VehicleStreaming.SetLockStatus(veh, false);
      NAPI.Entity.SetEntityVelocity(veh.Handle, new Vector3(0, 0, 0));
      veh.Position = sVeh.Position;
      veh.Rotation = new Vector3(0, 0, sVeh.Heading);

      user.Position = new Vector3(-813.17, -1354.5, 4.14);
    }


    [RemoteEvent("drivingSchoolEvent")]
    public void DrivingSchoolEvent(Player user, int checkpoint)
    {
      if (checkpoint == 0)
      {
        user.TriggerEvent("renderTextOnScreen", "Sollten Sie aus dem Fahrzeug aussteigen fallen Sie durch.");
      }

      else if (checkpoint == 9)
      {
        user.TriggerEvent("renderTextOnScreen", "Fahre zwischen den Laternen Slalom.");
      }
      else if (checkpoint == 20)
      {
        user.TriggerEvent("renderTextOnScreen", "Verlasse nun den Parkplatz.");
      }
      else if (checkpoint == 32)
      {
        user.TriggerEvent("renderTextOnScreen", "Parke nun das Auto an der markierten Stelle.");
        CheckPointHandle.StartCheckPointRoute(user, StopCar, 5000, 1, 7, "drivingSchoolEventEnd");
      }
    }



    [RemoteEvent("startBikeSchool")]
    public void StartBikeSchool(Player client)
    {
      User user = client.GetUser();
      if (user.DriverLicenseBike || client.HasData("ActiveSchool"))
        return;

      if (user.Handmoney < 3500)
      {
        client.SendNotification("~r~Du brauchst ~g~$3500~r~ auf der Hand um die Prüfung zu starten.", true);
        return;
      }

      using (var dbContext = new DatabaseContext())
      {
        User payer = client.GetUser(dbContext);
        payer.Handmoney -= 3500;
        client.TriggerEvent("SERVER:SET_HANDMONEY", payer.Handmoney);
        dbContext.SaveChanges();
      }

      client.SetData("ActiveSchool", 2);
      client.TriggerEvent("renderTextOnScreen", "Sie haben die Führerscheinprüfung gestartet. Steigen Sie in eines der Fahrschulmotorräder ein.");
      client.TriggerEvent("waitPlayerEntersVehicle");
    }


    [RemoteEvent("bikeSchoolEventEnd")]
    public void bikeSchoolEventEnd(Player user, int checkpoint)
    {
      user.TriggerEvent("renderTextOnScreen", "Du hast den Führerschein bestanden. Glückwunsch!");
      user.ResetData("ActiveSchool");
      using (var dbContext = new DatabaseContext())
      {
        User drivingUser = user.GetUser(dbContext);
        drivingUser.DriverLicenseBike = true;
        dbContext.SaveChanges();
      }

      Vehicle veh = user.Vehicle;
      user.WarpOutOfVehicle();
      ServerVehicle sVeh = VehicleManager.GetServerVehicleFromVehicle(veh);
      VehicleStreaming.SetEngineState(veh, false);
      VehicleStreaming.SetLockStatus(veh, false);
      NAPI.Entity.SetEntityVelocity(veh.Handle, new Vector3(0, 0, 0));
      veh.Position = sVeh.Position;
      veh.Rotation = new Vector3(0, 0, sVeh.Heading);

      user.Position = new Vector3(-813.17, -1354.5, 4.14);
    }


    [RemoteEvent("bikeSchoolEvent")]
    public void bikeSchoolEvent(Player user, int checkpoint)
    {
      if (checkpoint == 0)
      {
        user.TriggerEvent("renderTextOnScreen", "Sollten Sie aus dem Fahrzeug aussteigen fallen Sie durch.");
      }
      else if (checkpoint == 12)
      {
        user.TriggerEvent("renderTextOnScreen", "Parke nun das Auto an der markierten Stelle.");
        CheckPointHandle.StartCheckPointRoute(user, StopBike, 5000, 1, 7, "bikeSchoolEventEnd");
      }
    }

  }
}
