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;
using ReallifeGamemode.Server.Managers;
using ReallifeGamemode.Server.Util;

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

    private static Vector3 JailIn_Point = new Vector3(1690.754, 2591.0464, 45.914402);
    private static int JailIn_Range = 3;
    private static Vector3 JailOut_Point = new Vector3(1848.3097, 2585.9036, 45.67201);

    private static List<Vector3> prisonCells = new List<Vector3>() {
      new Vector3(1629.2026, 2569.8057, 45.564846),
      new Vector3(1642.7831, 2570.2622, 45.56483),
      new Vector3(1651.512, 2570.2249, 45.564907)
    };

    public static void Check_PutBehindBars(User user, JailInLocations positionInJail)
    {
      user.SetBlipAndNametagColor();
      Player player = user.Player;
      PositionManager.cuffPoints.Remove(player);
      if (user.JailTime > 0)
      {
        player.RemoveAllWeapons();
        player.ClearAttachments();
        player.ClearAnimation();
        player.SafeSetHealth(100);
        player.Armor = 0;

        Vector3 position = null;

        if (positionInJail == JailInLocations.InCell)
        {
          Random rnd = new Random();
          int rndInt = rnd.Next(1, 3);
          position = prisonCells[rndInt];

        }
        else if (positionInJail == JailInLocations.Outside)
        {
          position = new Vector3(1691.42, 2562.77, 45.56);
        }

        player.SafeTeleport(position, 0, true);

        Jailtime[user.Id] = user.JailTime; // 54 sec for each wanted star -> in total 45min for 50 Wanteds
        int timeMinutes;

        if ((user.JailTime / 60) <= 1 && user.JailTime != 0)
        {
          timeMinutes = 1;
        }
        else
        {
          timeMinutes = user.JailTime / 60;
        }
        player.TriggerEvent("jailTime", timeMinutes);
      }
    }

    /*
    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()
    {
      using var dbContext = new DatabaseContext();
      foreach (var player in NAPI.Pools.GetAllPlayers())
      {
        if (player.Position.DistanceTo(JailIn_Point) > JailIn_Range)
        {
          continue;
        }

        User user = player.GetUser(dbContext);

        if (user != null && user.Wanteds > 0 && !Jailtime.ContainsKey(user.Id))
        {
          foreach (var copPlayer in NAPI.Pools.GetAllPlayers().Where(u => u.IsLoggedIn() && u.IsDuty() && u.IsAlive()))
          {
            User copUser = copPlayer.GetUser(dbContext);
            if (copUser.FactionId == 1 || copUser.FactionId == 3)
            {
              if (player.Position.DistanceTo(copPlayer.Position) < 5)
              {
                user.SetJailTime(false, dbContext);
                user.SetBlipAndNametagColor();
                user.AnnouncePlayerJailedIn();
                dbContext.SaveChanges();
                //HERE: Freilauf
                Check_PutBehindBars(user, JailInLocations.Outside);
                break;
              }
            }
          }
        }
      }
    }

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

            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.SafeSetHealth(100);
          }
        }
      }
      dbContext.SaveChanges();
    }

    [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.SafeSetHealth(100);
        player.SafeTeleport(JailOut_Point);

        ChatService.HQMessage("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)
    {
      using var dbContext = new DatabaseContext();
      User user = target.GetUser(dbContext);
      if (Jailtime.ContainsKey(user.Id))
      {
        Jailtime.Remove(user.Id);

        user.JailTime = 0;
        dbContext.SaveChanges();

        target.SafeSetHealth(100);
        target.SafeTeleport(JailOut_Point);

        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);
      }
    }

    public static void BreakOut(Player player)
    {
      if (player.IsTSupport()) return;
      User user = player.GetUser();      
      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);
      }
    }

    [RemoteEvent("SERVER:BreakOutIfInPrison")]
    public void breakOutIfInPrison(Player player)
    {
      if (player.IsTSupport()) return;
      User user = player.GetUser();
      using (var dbContext = new DatabaseContext())
      {
        if (Jailtime.ContainsKey(user.Id))
        {
          user = player.GetUser(dbContext);
          user.JailTime = 0;
          user.GiveWanteds(null, 50, "Knast-Ausbruch");
          player.TriggerEvent("jailTime", 0);
          dbContext.SaveChanges();
          Jailtime.Remove(user.Id);
        }
      }
    }
  }
}
