using System;
using System.Collections.Generic;
using System.Linq;
using GTANetworkAPI;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Factions.Medic;
using ReallifeGamemode.Server.Services;
using ReallifeGamemode.Services;
using System.Diagnostics;
using Newtonsoft.Json;

namespace ReallifeGamemode.Server.Wanted
{
  public class Jail : Script
  {
    private static Dictionary<int, int> Jailtime { get; set; } = new Dictionary<int, int>(); //time in seconds


    public static void Check_PutBehindBars(Player client, bool announceHq = true)
    {
      User user = client.GetUser();
      if (user.JailTime > 0)
      {
        client.RemoveAllWeapons();
        client.Health = 100;
        client.Armor = 0;
        Random rnd = new Random();
        int rndInt = rnd.Next(1, 3);
        if (rndInt == 1)
          NAPI.Player.SpawnPlayer(client, new Vector3(458.9842, -997.2126, 24.91485)); //send client to jail
        if (rndInt == 2)
          NAPI.Player.SpawnPlayer(client, new Vector3(459.696, -994.3766, 24.91486)); //send client to jail
        if (rndInt == 3)
          NAPI.Player.SpawnPlayer(client, new Vector3(458.3372, -1001.258, 24.91485)); //send client to jail
        Jailtime[user.Id] = user.JailTime; // 54 sec for each wanted star -> in total 45min for 50 Wanteds
        int timeMinutes = 0;

        if (((int)(user.JailTime / 60)) <= 1 && user.JailTime != 0)
        {
          timeMinutes = 1;
        }
        else
        {
          timeMinutes = (int)(user.JailTime / 60);
        }
        client.TriggerEvent("jailTime", timeMinutes);
        return;
      }
      if (user.Wanteds <= 0)
        return;
      using (var dbContext = new DatabaseContext())
      {
        foreach (var copPlayer in NAPI.Pools.GetAllPlayers())
        {
          if (!copPlayer.IsLoggedIn()) continue;
          User cop = copPlayer.GetUser();
          if (cop?.FactionId == 1 || cop?.FactionId == 3)
          {
            int jailTime = user.Wanteds * 54;
            if (cop.GetData<bool>("duty") && copPlayer.Position.DistanceTo2D(client.Position) <= 200 && (!copPlayer.HasData("isDead") || copPlayer.GetData<bool>("isDead") != true))
            {
              if (!client.HasData("isDead") || client.GetData<bool>("isDead") == false)
              {
                jailTime /= 2;
              }

              client.GetUser(dbContext).JailTime = jailTime;
              Jailtime[user.Id] = jailTime; // 54 sec for each wanted star -> in total 45min for 50 Wanteds

              client.GetUser(dbContext).Wanteds = 0;
              client.SetData("isDead", false);
              client.RemoveAllWeapons();
              client.SetSharedData("blipColor", 0);
              Random rnd = new Random();
              int rndInt = rnd.Next(1, 3);
              if (rndInt == 1)
                NAPI.Player.SpawnPlayer(client, new Vector3(458.9842, -997.2126, 24.91485)); //send client to jail
              if (rndInt == 2)
                NAPI.Player.SpawnPlayer(client, new Vector3(459.696, -994.3766, 24.91486)); //send client to jail
              if (rndInt == 3)
                NAPI.Player.SpawnPlayer(client, new Vector3(458.3372, -1001.258, 24.91485)); //send client to jail

              client.TriggerEvent("onPlayerRevived");
              MedicTask task = Medic.ReviveTasks.FirstOrDefault(t => t.Victim == client.Name);
              Medic.RemoveTaskFromList(task);
              client.Health = 100;

              int timeMinutes = 0;

              if (((int)(client.GetUser().JailTime / 60)) <= 1 && client.GetUser().JailTime != 0)
              {
                timeMinutes = 1;
              }
              else
              {
                timeMinutes = (int)(client.GetUser().JailTime / 60);
              }

              client.TriggerEvent("jailTime", JsonConvert.SerializeObject(timeMinutes));
              ChatService.SendMessage(client, "!{#FF614A}* Du bist nun im Gefängnis für " + timeMinutes + " Minute/n.");

              if (announceHq)
              {
                ChatService.BroadcastFaction("!{#8181E9}HQ: " + user.Name + " wurde ins Gefängnis geliefert.", new List<int>() { 1, 3 });
              }

              switch (user.FactionId)
              {
                case null:
                  client.SetSharedData("blipColor", 0);
                  break;
                case 8:
                  client.SetSharedData("blipColor", 83);
                  break;
                case 7:
                  client.SetSharedData("blipColor", 52);
                  break;
                case 4:
                  client.SetSharedData("blipColor", 5);
                  break;

              }
            }
            else
            {
              ChatService.BroadcastFaction("!{#8181E9}HQ: Der Verdächtigte " + user.Name + " wurde soeben ins Krankenhaus eingeliefert.", new System.Collections.Generic.List<int>() { 1, 3 });
            }
          }
        }

        dbContext.SaveChanges();
      }
    }

    /*
    public static void JailTimer()
    {
      System.Timers.Timer timer = new System.Timers.Timer(60000);
      System.Timers.Timer brakeOut = new System.Timers.Timer(10000);
      System.Timers.Timer jailIn = new System.Timers.Timer(2500);
      timer.Start();
      brakeOut.Start();
      jailIn.Start();
      //timer.Elapsed += Timer_Elapsed;
      //brakeOut.Elapsed += BrakeOut_Elapsed;
      //jailIn.Elapsed += JailIn_Elapsed;
    }
    */

    public static void JailIn_Elapsed()
    {
      foreach (var player in NAPI.Pools.GetAllPlayers())
      {
        User user = player.GetUser();
        if (user != null && !Jailtime.ContainsKey(user.Id))
        {
          foreach (var copPlayer in NAPI.Pools.GetAllPlayers())
          {
            if (!copPlayer.IsLoggedIn()) return;
            User cop = copPlayer.GetUser();
            if (cop.GetData<bool>("duty") && copPlayer.Position.DistanceTo2D(player.Position) <= 500 && (!copPlayer.HasData("isDead") || copPlayer.GetData<bool>("isDead") != true))
            {
              if (player.Position.DistanceTo2D(new Vector3(458.9842, -997.2126, 24.91485)) <= 7)
              {
                if (player.Position.DistanceTo2D(copPlayer.Position) < 5)
                {
                  Check_PutBehindBars(player);
                }
              }
            }
          }
        }
      }
    }

    public static void BrakeOut_Elapsed()
    {
      foreach (var player in NAPI.Pools.GetAllPlayers())
      {
        User user = player.GetUser();

        if (user != null && player.Position.DistanceTo2D(new Vector3(458.9842, -997.2126, 24.91485)) > 7 && Jailtime.ContainsKey(user.Id))
        {
          using (var dbContext = new DatabaseContext())
          {
            user = player.GetUser(dbContext);
            user.JailTime = 0;
            user.GiveWanteds(null, 50, "Knast-Ausbruch");
            player.TriggerEvent("jailTime", 0);
            dbContext.SaveChanges();
            Jailtime.Remove(user.Id);
          }
        }
      }
    }

    public static void JailOut_Elapsed()
    {
      foreach (var player in NAPI.Pools.GetAllPlayers())
      {
        User user = player.GetUser();
        if (user != null && Jailtime.ContainsKey(user.Id))
        {
          if (user.JailTime <= 0)
          {
            Jailtime.Remove(user.Id);
            player.Position = new Vector3(461.7256, -988.6035, 24.91487);
            player.TriggerEvent("jailTime", 0);
            return;
          }
          if (user.JailTime > 0)
          {
            using (var dbContext = new DatabaseContext())
            {
              player.GetUser(dbContext).JailTime -= 60;
              dbContext.SaveChanges();
            }

            int timeMinutes = 0;

            if (((int)(user.JailTime / 60)) == 0 && user.JailTime != 0)
            {
              timeMinutes = 1;
            }
            else
            {
              timeMinutes = (int)(user.JailTime / 60);
            }

            player.TriggerEvent("jailTime", timeMinutes);
            player.Health = 100;
          }
        }
      }
    }

    [RemoteEvent("setPrisonerFree")]
    public void Release_Jail(Player cop, string client)
    {
      Player player = PlayerService.GetPlayerByNameOrId(client);
      if (player == null)
        return;

      User user = player.GetUser();
      if (Jailtime.ContainsKey(user.Id))
      {
        Jailtime.Remove(user.Id);
        using (var dbContext = new DatabaseContext())
        {
          player.GetUser(dbContext).JailTime = 0;
          dbContext.SaveChanges();
        }
        player.Health = 100;
        player.Position = new Vector3(461.7256, -988.6035, 24.91487);

        ChatService.HQMessage("!{#8181E9}HQ: Beamter " + cop.Name + " hat " + user.Name + " aus dem Knast entlassen.");
        ChatService.SendMessage(player, "!{#8181E9}Der Beamte " + cop.Name + " hat dich aus dem Knast entlassen");
        player.TriggerEvent("jailTime", 0);
      }
    }

    public static void Release_Jail_Admin(Player admin, Player target)
    {
      User user = target.GetUser();
      if (Jailtime.ContainsKey(user.Id))
      {
        Jailtime.Remove(user.Id);
        using (var dbContext = new DatabaseContext())
        {
          target.GetUser(dbContext).JailTime = 0;
          dbContext.SaveChanges();
        }
        target.Health = 100;
        target.Position = new Vector3(461.7256, -988.6035, 24.91487);

        ChatService.HQMessage(" Admin " + admin.Name + " hat " + user.Name + " aus dem Knast entlassen.");
        ChatService.SendMessage(target, "!{#8181E9}Admin " + admin.Name + " hat dich aus dem Knast entlassen");
        ChatService.SendMessage(admin, "!{#8181E9}Du hast " + user.Name + " administrativ aus dem Knast entlassen");
        target.TriggerEvent("jailTime", 0);
      }
    }
  }
}
