using System;
using System.Collections.Generic;
using System.Linq;
using GTANetworkAPI;
using Newtonsoft.Json;
using ReallifeGamemode.Database.Entities.Saves;
using ReallifeGamemode.Database.Models;

namespace ReallifeGamemode.Server.Managers
{
  public class PedManager : Script
  {
    private List<PedData> pedDatas = new List<PedData>();
    public static List<SavedPed> serverPeds = new List<SavedPed>();
    private static Dictionary<Player, List<PedData>> dataDict = new Dictionary<Player, List<PedData>>();
    private void GetPedsFromDatabase()
    {
      using (var dbContext = new DatabaseContext())
      {
        serverPeds = dbContext.Peds.Where(x => x.HashModel != null).ToList();
      }
    }

    private List<PedData> FindDataThroughPlayer(Player player)
    {
      if (!dataDict.ContainsKey(player)) return null;
      return dataDict[player];
    }

    [ServerEvent(Event.PlayerConnected)]
    public void LoadServerPedForPlayer(Player player)
    {
      if (serverPeds.Count == 0)
        GetPedsFromDatabase();
      List<Vector3> vector3s = new List<Vector3>();
      List<float> headings = new List<float>();
      List<string> hashes = new List<string>();
      List<int> dimensions = new List<int>();
      pedDatas = new List<PedData>();
      foreach (var s in serverPeds)
      {
        if (!s.Active) continue;
        Vector3 vector3 = new Vector3(s.PositionX, s.PositionY, s.PositionZ);
        pedDatas.Add(new PedData(player, (DataType)s.Type, vector3, s.Heading, s.HashModel));

        vector3s.Add(vector3);
        headings.Add(s.Heading);
        hashes.Add(s.HashModel);
        dimensions.Add(s.Dimension);
      }
      dataDict[player] = pedDatas;
      Console.WriteLine($"[DEBUG] DATA ADDED - PED Data registered :{dataDict.Count}");

      player.TriggerEvent("SERVER:CreateStaticPeds", JsonConvert.SerializeObject(vector3s.ToArray()), JsonConvert.SerializeObject(headings.ToArray()), JsonConvert.SerializeObject(hashes.ToArray()), JsonConvert.SerializeObject(dimensions.ToArray()));
    }

    [ServerEvent(Event.PlayerDisconnected)]
    public void RemovePlayerPedDataOnDc(Player player, DisconnectionType type, string reason)
    {
      List<PedData> data = FindDataThroughPlayer(player);
      if (data == null) return;
      dataDict.Remove(player);
      Console.WriteLine($"[DEBUG] DATA REMOVED - PED Data left :{dataDict.Count}");
    }
  }

  public enum DataType : int
  {
    WeponDealPed,
    DepartmentPed,
    PrisonPed
  }

  public class PedData
  {
    private DataType type;
    public Player player;
    public Vector3 vector3;
    public float heading;
    public string HashModel;

    public PedData(Player player, DataType type, Vector3 vector3, float heading, string HashModel)
    {
      this.player = player;
      this.type = type;
      this.vector3 = vector3;
      this.heading = heading;
      this.HashModel = HashModel;
    }

    public DataType getType()
    {
      return type;
    }
  }
}
