using GTANetworkAPI;
using ReallifeGamemode.Server.Entities;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Models;
using ReallifeGamemode.Server.Util;
using System;
using System.Collections.Generic;
using System.Text;

namespace ReallifeGamemode.Server.Events
{
    public class VehicleMenu : Script
    {
        [RemoteEvent("VehicleMenu_ToggleEngine")]
        public void VehicleMenuToggleEngineEvent(Client player)
        {
            if (player.IsInVehicle && player.VehicleSeat == -1)
            {
                Vehicle v = player.Vehicle;

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

                if (NAPI.Entity.GetEntityVelocity(v).Length() > 1)
                {
                    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.FactionId != u.FactionId && !state && !u.IsAdmin(AdminLevel.ADMIN3))
                        {
                            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.GetJob().GetUsersInJob().Contains(player) && !u.IsAdmin(AdminLevel.ADMIN3))
                        {
                            player.SendNotification("~r~Du hast keinen Schlüssel.");
                            return;
                        }
                    }
                }
                VehicleStreaming.SetEngineState(v, !state);
            }
        }

        [RemoteEvent("VehicleMenu_LockCar")]
        public void VehicleMenuLockCarEvent(Client player)
        {
            if (player.IsInVehicle && player.VehicleSeat == -1)
            {
                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.FactionId != u.FactionId)
                        {
                            return;
                        }
                    }
                    else if (sV is UserVehicle uV)
                    {
                        if (uV.UserId != u.Id)
                        {
                            return;
                        }
                    }
                }
                state = !state;
                VehicleStreaming.SetLockStatus(v, state);
                string msg = "Fahrzeug ";
                msg += state ? "~g~abgeschlossen" : "~r~aufgeschlossen";
                player.SendNotification(msg);
            }
        }

        [RemoteEvent("CLIENT:VehicleMenu_ParkCar")]
        public void VehicleMenuParkCarEvent(Client player)
        {
            if (player.IsInVehicle && player.VehicleSeat == -1)
            {
                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.FactionId != u.FactionId || !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;
                        }
                    }

                    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(Client player, int door)
        {
            if (!player.IsInVehicle) return;
            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(Client player)
        {
            if (!player.IsInVehicle) return;
            Vehicle veh = player.Vehicle;

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

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

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