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.Inventory;
using ReallifeGamemode.Server.Inventory.Interfaces;
using ReallifeGamemode.Server.Managers;
using ReallifeGamemode.Server.Services;
using ReallifeGamemode.Server.Types;
using ReallifeGamemode.Server.Util;
using ReallifeGamemode.Server.Wanted;

/**
* @overview Life of German Reallife - Events Death (Death.cs)
* @author VegaZ
* @copyright (c) 2008 - 2018 Life of German
*/

namespace ReallifeGamemode.Server.Events
{
  public class Death : Script
  {
    [ServerEvent(Event.PlayerDeath)]
    public void OnPlayerDeath(Player player, Player killer, uint reason)
    {
      if (!player.IsLoggedIn()) player.Kick();
      player.SetData("isDead", true);

      //TODO: Zum Full Release entfernen
      ChatService.SendMessage(player, "Du bist durch " + (killer?.Name ?? "Niemanden") + " gestorben: " + reason.ToString());

      int? killerId;
      float killerPosX;
      float killerPosY;
      float killerPosZ;
      float killerHeading;

      if (killer == null || killer.IsNull)
      {
        killerId = null;
        killerPosX = -1;
        killerPosY = -1;
        killerPosZ = -1;
        killerHeading = -1;
      }
      else
      {
        killerId = killer.GetUser().Id;
        killerPosX = killer.Position.X;
        killerPosY = killer.Position.Y;
        killerPosZ = killer.Position.Z;
        killerHeading = killer.Heading;
        if (player.HasData("inGangWar") && killer.HasData("inGangWar"))
        {
          Gangwar.Gangwar.GangwarKill(killer, player);
        }

        if (player != killer)
        {
          Autowanted.Check_AutoWanted(killer, player);
          string message = "~y~[HINWEIS]: " + killer.Name + " hat " + player.Name + " getötet (" + Managers.WeaponManager.GetCauseOfDeathByHash(reason) + ")";
          ChatService.BroadcastAdmin(message, AdminLevel.ADMIN);
        }
      }

      User user = player.GetUser();
      if (user.JailTime <= 0)
      {
        //MEDIC AUFTRAG
        MedicTask reviveTask = new MedicTask()
        {
          Victim = player.Name,
          Position = player.Position,
          CauseOfDeath = reason.ToString(),
          Caller = null,
          Description = "Gestorben",
          Time = DateTime.Now,
          Type = MedicTaskType.REVIVE,
          MedicName = "none"
        };
        Medic.AddTaskToList(reviveTask);

        if (player.GetUser().IsAdmin(AdminLevel.ADMIN) == true)
        {
          player.TriggerEvent("startDeathTimer", true);
        }
        else
        {
          player.TriggerEvent("startDeathTimer", false);
        }

        //TODO PICTURE NOTIFICATION + SOUND für Medics

        player.ClearAttachments();

        using (var userDeath = new DatabaseContext())
        {
          List<UserItem> fItem = userDeath.UserItems.Where(u => u.UserId == user.Id).ToList();
          foreach (var item in fItem)
          {
            IItem iItem = InventoryManager.GetItemById(item.ItemId);
            if (iItem is IWeaponDealItem obj)
            {
              int amount = item.Amount;

              Vector3 dropPosition = PlayerExtension.GetPositionFromPlayer(player, 0.6f, 0);
              //new Vector3(player.Position.X, player.Position.Y, player.Position.Z - 0.8f);
              Random r = new Random();
              GTANetworkAPI.Object grndObject;
              Vector3 textPos = dropPosition;

              dropPosition.Z -= 1.05f;
              grndObject = NAPI.Object.CreateObject(3666746839, dropPosition, new Vector3(0, 0, r.Next(0, 360)), 255, 0);

              GroundItem grndItem = new GroundItem { ItemId = iItem.Id, Amount = amount, Position = dropPosition };
              TextLabel grndTxtLbl = NAPI.TextLabel.CreateTextLabel(iItem.Name + " ~s~(~y~" + amount + "~s~)", textPos, 5, 0.5f, 4, new Color(255, 255, 255), false, 0);
              GroundItem.AddGroundItem(grndItem, grndObject, grndTxtLbl);

              userDeath.Remove(item);
            }
          }

          var dead = new Database.Entities.Logs.Death
          {
            VictimId = player.GetUser().Id,
            KillerId = killerId,
            KillerPositionX = killerPosX,
            KillerPositionY = killerPosY,
            KillerPositionZ = killerPosZ,
            KillerHeading = killerHeading,
            VictimPositionX = player.Position.X,
            VictimPositionY = player.Position.Y,
            VictimPositionZ = player.Position.Z,
            VictimHeading = player.Heading,
            CauseOfDeath = reason.ToString()
          };
          userDeath.DeathLogs.Add(dead);
          userDeath.SaveChanges();
        }
      }
      Job.JobBase job = Managers.JobManager.GetJob(player.GetUser().JobId ?? -1);
      if (job != null)
      {
        //ChatService.SendMessage(player, "Debug1");
        if (job.GetUsersInJob().Contains(player))
        {
          //ChatService.SendMessage(player, "Debug2");
          if (player.Vehicle != null)
          {
            //ChatService.SendMessage(player, "Debug3");
            /*if (player.Vehicle.GetData<bool>("timerJobVehicleRespawn") == true)
            {*/
            if (player.Vehicle.GetServerVehicle() is JobVehicle vehJ)
            {
              //ChatService.SendMessage(player, "Debug4");
              player.Vehicle.ResetData("timerJobVehicleRespawn");
              ServerVehicle sVeh = Managers.VehicleManager.GetServerVehicleFromVehicle(player.Vehicle);
              ServerVehicleExtensions.Spawn(sVeh, player.Vehicle);
            }
            else
            {
              //ChatService.SendMessage(player, "Debug5");
            }
            //}
          }
          if (Managers.JobManager.playerTimersJobVehicleRespawn.ContainsKey(player))
          {
            //ChatService.SendMessage(player, "Debug6");
            Managers.JobManager.playerTimersJobVehicleRespawn[player].Stop();
          }
          //ChatService.SendMessage(player, "Debug7");
          player.ResetData("PilotenBase");
          job.StopJob(player);
          ChatService.SendMessage(player, $"~y~[JOB]~s~ Du hast deinen Job ~o~{job.Name}~s~ beendet.");
          if (player.GetData<bool>("HatRoute") == true)
          {
            //ChatService.SendMessage(player, "Debug8");
            CheckPointHandle.DeleteCheckpoints(player);
            player.ResetData("HatRoute");
          }
          else
          {
            //ChatService.SendMessage(player, "Debug9");
          }
        }
        else
        {
          //ChatService.SendMessage(player, "Debug10");
        }
      }

      //JailTime.cs
      Jail.Check_PutBehindBars(player);
    }

    [RemoteEvent("RespawnPlayerAtHospital")]
    public void RespawnPlayerAtHospital(Player player)
    {
      player.SetData("isDead", false);
      player.RemoveAllWeapons();
      NAPI.Player.SpawnPlayer(player, new Vector3(-495.45, -336.33, 34.5), -98.36f);

    }
  }
}
