using System.Collections.Generic;
using System.Linq;
using GTANetworkAPI;
using Newtonsoft.Json;
using ReallifeGamemode.Server.Classes;
using ReallifeGamemode.Server.Entities;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Factions.Medic;
using ReallifeGamemode.Server.Inventory;
using ReallifeGamemode.Server.Managers;
using ReallifeGamemode.Server.Models;
using ReallifeGamemode.Server.Services;
using ReallifeGamemode.Server.Util;
/**
* @overview Life of German Reallife - Event Key (Key.cs)
* @author VegaZ
* @copyright (c) 2008 - 2018 Life of German
*/

namespace ReallifeGamemode.Server.Events
{
    public class Key : Script
    {
        [RemoteEvent("keyPress:NUM2")]
        public void KeyPressNUM2(Client player)
        {
            if (!player.IsLoggedIn()) return;
            if (player.GetData("editmode") == true && player.GetUser().IsAdmin(AdminLevel.HEADADMIN) == true)
            {
                var saveMode = player.GetData("quicksavemode");
                switch (saveMode)
                {
                    case "none":
                        ChatService.SendMessage(player, "~r~Keinen Modus ausgewählt! ~y~/quicksavemode ~r~für mehr Infos!");
                        break;

                    case "blip":
                        TempBlip tempBlip = NAPI.Data.GetWorldData("blipTemplate");
                        SaveManager.OnSaveBlipData(player, tempBlip.Sprite.ToString(), tempBlip.Name, tempBlip.Scale.ToString(), tempBlip.Color.ToString(),
                            tempBlip.Transparency.ToString(), 200.ToString(), tempBlip.ShortRange.ToString(), 0.ToString(), 0.ToString());
                        player.SendNotification("~y~Blip~s~ erstellt!", false);
                        break;
                    case "atm":
                        SaveManager.OnSaveBlipData(player, "500", "Geldautomat", 0.7.ToString(), "11",
                            "0", "200", true.ToString(), 0.ToString(), 0.ToString());
                        player.SendNotification("~y~ATM~s~ erstellt!", false);
                        break;
                }
            }

            GroundItem.PickUpGroundItem(player);
        }

        [RemoteEvent("keyPress:UP_ARROW")]
        public void KeyPressUpArrow(Client player)
        {
            if (!player.IsLoggedIn()) return;
            if (player.HasData("nearATM"))
            {
                ATMManager.ShowAtmUi(player, player.GetData("nearATM"));
            }
        }

        [RemoteEvent("keyPress:LEFT_ARROW")]
        public void KeyPressLeftArrow(Client player)
        {
            if (!player.IsLoggedIn()) return;
            List<Client> nearbyPlayers = NAPI.Player.GetPlayersInRadiusOfPlayer(3, player);

            if (nearbyPlayers.Count > 1)
            {
                List<string> nearbyPlayerList = new List<string>();
                foreach (Client nearPlayer in nearbyPlayers)
                {
                    if (nearPlayer.Name != player.Name)
                    {
                        nearbyPlayerList.Add(nearPlayer.Name);
                    }
                    else
                    {
                        continue;
                    }
                }
                player.TriggerEvent("showPlayerInteraction", JsonConvert.SerializeObject(nearbyPlayerList));
            }
        }

        [RemoteEvent("keyPress:RIGHT_ARROW")]
        public void KeyPressRightArrow(Client player)
        {
            if (!player.IsLoggedIn()) return;
            User user = player.GetUser();
            switch (user.FactionId)
            {
                //LSFD
                case 2:
                    player.TriggerEvent("showFactionInteraction", user.FactionId, player.GetData("duty"), user.Faction.Name, user.FactionLeader, Medic.ReviveTasks.Count.ToString(), Medic.HealTasks.Count.ToString(), Medic.FireTasks.Count.ToString());
                    break;
            }
        }

        [RemoteEvent("keyPress:DOWN_ARROW")]
        public void KeyPressDownArrow(Client player)
        {
            User u = player.GetUser();
            if (u == null) return;

            var accountData = new
            {
                regDate = u.RegistrationDate.ToShortDateString(),
                adminLevel = u.AdminLevel.GetName(),
                faction = u.Faction?.Name ?? "Zivilist",
                factionRank = u.GetFactionRank().RankName,
                group = u.Group?.Name ?? "Keine",
                groupRank = u.GroupRank.GetName(),
                job = JobManager.GetJob(u.JobId ?? 0)?.Name ?? "Keiner"
            };

            string faction = u.FactionLeader ? u.Faction.Name : null;
            string group = u.Group != null && u.GroupRank >= GroupRank.MANAGER ? u.Group.Name : null;
            bool factionInvite = player.HasData("accept_faction_invite");
            bool groupInvite = player.HasData("accept_group_invite");

            player.TriggerEvent("SERVER:InteractionMenu_OpenMenu", JsonConvert.SerializeObject(accountData), faction, group, factionInvite, groupInvite);
        }

        [RemoteEvent("keyPress:E")]
        public void KeyPressE(Client player)
        {
            if (!player.IsLoggedIn()) return;
            var user = player.GetUser();
            if (user?.FactionId != null)
            {
                DutyPoint nearest = PositionManager.DutyPoints.Find(d => d.Position.DistanceTo(player.Position) <= 1.5 && d.FactionId == user.FactionId);
                if (nearest == null) return;
                var nameTagColor = new Color(0, 0, 0);
                var factionId = user.FactionId;

                if (player.GetData("duty") == false)
                {
                    player.SetData("duty", true);
                    player.SendNotification("Du bist nun ~g~im Dienst.");
                    if (player.GetUser().FactionId == 2) //Fire Department
                    {
                        int medicCount = 0;
                        foreach (Client c in NAPI.Pools.GetAllPlayers())
                        {
                            if ((c.GetUser()?.Faction.Id ?? 0) == 2)
                            {
                                medicCount++;
                            }
                        }
                        NAPI.ClientEvent.TriggerClientEventForAll("updateDutyMedics", medicCount);
                    }
                    switch (factionId)
                    {
                        //LSPD
                        case 1:
                            nameTagColor = new Color(28, 134, 238);
                            break;
                    }
                    player.NametagColor = nameTagColor;
                    using (var context = new DatabaseContext())
                    {
                        List<CharacterCloth> clothes = context.CharacterClothes.Where(u => u.UserId == user.Id && u.Duty == true).ToList();

                        foreach (var cloth in clothes)
                        {
                            if (cloth.SlotType == 0)
                            {
                                player.SetClothes(cloth.SlotId, cloth.ClothId, 0);
                            }
                            else
                            {
                                if (cloth.ClothId != -1)
                                {
                                    player.SetAccessories(cloth.SlotId, cloth.ClothId, 0);
                                }
                                else
                                {
                                    player.ClearAccessory(cloth.SlotId);
                                }
                            }
                        }
                    }
                }
                else
                {
                    player.SetData("duty", false);
                    player.SendNotification("Du bist nun ~r~außer Dienst.");
                    NAPI.ClientEvent.TriggerClientEventForAll("updateDutyMedics", false);
                    player.NametagColor = new Color(255, 255, 255);
                    UpdateCharacterCloth.LoadCharacterDefaults(player);
                }
            }
        }

        [RemoteEvent("keyPress:I")]
        public void KeyPressI(Client player)
        {
            if (!player.IsLoggedIn()) return;
            InventoryManager.GetUserItems(player);
        }

        [RemoteEvent("keyPress:O")]
        public void KeyPressJ(Client player)
        {
            if (!player.IsLoggedIn()) return;
            List<Client> players = NAPI.Pools.GetAllPlayers();
            var listPlayers = players.Select(p => new
            {
                Id = p.Handle.Value,
                p.Name,
                p.Ping
            });
            player.TriggerEvent("fetchPlayerList", JsonConvert.SerializeObject(listPlayers));
        }

        [RemoteEvent("keyPress:K")]
        public void KeyPressK(Client player)
        {
            if (!player.IsLoggedIn()) return;
            var user = player.GetUser();
            if (user?.FactionId != null)
            {
                DutyPoint nearest = PositionManager.DutyPoints.Find(d => d.Position.DistanceTo(player.Position) <= 1.5);
                if (nearest == null) return;
                if (player.Position.DistanceTo(nearest.Position) <= 1.5 && nearest.FactionId == user.FactionId)
                {
                    List<string> hats = new List<string>();
                    List<string> tops = new List<string>();
                    List<string> legs = new List<string>();
                    List<string> shoes = new List<string>();

                    using (var context = new DatabaseContext())
                    {
                        List<DutyCloth> clothes = context.DutyClothes.ToList().FindAll(c => c.FactionId == user.FactionId && c.Gender == user.GetCharacter().Gender);
                        foreach (var cloth in clothes)
                        {
                            if (cloth.SlotType == 1)
                            {
                                if (cloth.ClothId != -1)
                                {
                                    hats.Add(cloth.ClothId.ToString());
                                }
                                else
                                {
                                    hats.Add("Keinen");
                                }
                                continue;
                            }

                            switch (cloth.SlotId)
                            {
                                case 11:
                                    tops.Add(cloth.ClothId.ToString());
                                    break;
                                case 4:
                                    legs.Add(cloth.ClothId.ToString());
                                    break;
                                case 6:
                                    shoes.Add(cloth.ClothId.ToString());
                                    break;
                            }
                        }
                    }
                    player.TriggerEvent("showDutyClothMenu", hats.ToArray(), tops.ToArray(), legs.ToArray(), shoes.ToArray());
                }
            }

        }

        [RemoteEvent("keyPress:L")]
        public void KeyPressL(Client player)
        {
            if (!player.IsLoggedIn()) return;
            DoorManager.ChangeDoorState(player);
        }

        [RemoteEvent("keyPress:N")]
        public void KeyPressN(Client player)
        {
            if (!player.IsLoggedIn()) return;
        }

        [RemoteEvent("keyPress:X")]
        public void KeyPressX(Client player)
        {
            if (!player.IsLoggedIn()) return;
            if (player.IsInVehicle && player.VehicleSeat == -1)
            {
                ServerVehicle veh = player.Vehicle.GetServerVehicle();
                if (veh != null)
                {
                    if (veh is FactionVehicle fV && fV.FactionId != player.GetUser()?.FactionId && (!player.GetUser()?.IsAdmin(AdminLevel.ADMIN3) ?? false))
                    {
                        return;
                    }
                    else if (veh is ShopVehicle)
                    {
                        return;
                    }
                }
                player.TriggerEvent("ToggleVehicleMenu");
            }
        }
    }
}
