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

namespace ReallifeGamemode.Server.Gangwar
{
  public class Gangwar : Script
  {
    public static Turf[] _loadedTurfs;
    private static List<Turfs> turfs;

    public static void loadTurfs()
    {
      _loadedTurfs = null;
      using (var context = new DatabaseContext())
      {
        turfs = context.Turfs.Select(t => t).ToList();
        List<Turf> turfing = new List<Turf>();
        foreach (var t in turfs)
        {
          Turf newTurf = new Turf(t.Id, t.Name, t.Color, t.Owner);
          turfing.Add(newTurf);
        }
        _loadedTurfs = turfing.ToArray();
      }
    }

    public static void loadPlayer(Player client)
    {
      client.TriggerEvent("GangAreas:Create", JsonConvert.SerializeObject(turfs.ToArray()));
    }

    public static void loadTurfs_ToAllPlayers()
    {
      NAPI.ClientEvent.TriggerClientEventForAll("GangAreas:Create", JsonConvert.SerializeObject(turfs.ToArray()));
      foreach(var l in NAPI.Pools.GetAllPlayers())
      {
        if (!l.IsLoggedIn() && !l.GetUser().FactionLeader)
          return;

        l.TriggerEvent("CLIENT:Turf_LoadLeaderBlip");
        
      }
    }

    public static void GangwarKill(Player killer, Player victim)
    {
      if (killer.HasData("GotInsideOfTurf") && victim.HasData("GotInsideOfTurf"))
      {
        foreach (var turf in getTurfs())
        {
          if (turf.getId() == victim.GetData<int>("inGangWar"))
          {
            turf.setKill(victim.GetUser().Faction.Name);
            return;
          }
        }
      }
    }

    public static Turf[] getTurfs()
    {
      return _loadedTurfs;
    }

    [RemoteEvent("Gangarea:Enter")]
    public void RmtEvent_TurfEnter(Player client, string jsonId)
    {
      int id = JsonConvert.DeserializeObject<int>(jsonId);

      foreach (var turf in getTurfs())
      {
        if (turf.getId() == id)
        {
          turf.enter(client);
          return;
        }
      }
    }

    [RemoteEvent("Gangarea:Leave")]
    public void RmtEvent_TurfLeave(Player client, string jsonId)
    {
      int id = JsonConvert.DeserializeObject<int>(jsonId);

      foreach (var turf in getTurfs())
      {
        if (turf.getId() == id)
        {
          turf.leave(client);
          return;
        }
      }
    }
    
    [RemoteEvent("SERVER:SetTurf")]
    public void RmtEvent_SetTurf(Player client, string jsonX, string jsonY, string jsonRot, string jsonRange, string Name)
    {
      float pX = JsonConvert.DeserializeObject<float>(jsonX);
      float pY = (float)JsonConvert.DeserializeObject<float>(jsonY);
      float Rot = (float)JsonConvert.DeserializeObject<float>(jsonRot);
      float Range = (float)JsonConvert.DeserializeObject<float>(jsonRange);

      var newTurf = new Turfs
      {
        Name = Name,
        X = pX,
        Y = pY,
        Rotation = Rot,
        Range = Range,
        Owner = "Neutral",
        Color = 0,
        Vector = null      
      };
      using (var dbContext = new DatabaseContext())
      {
        dbContext.Turfs.Add(newTurf);
        dbContext.SaveChanges();
      }
      loadTurfs();
      loadTurfs_ToAllPlayers();
    }

    [RemoteEvent("SERVER:DeleteTurf")]
    public void RmtEvent_DeleteTurf(Player client, string jsonId)
    {
      int id = JsonConvert.DeserializeObject<int>(jsonId);
      if (id == -1)
      {
        ChatService.ErrorMessage(client, "Du befindest dich in keinem Gebiet");
        return;
      }
      using (var dbContext = new DatabaseContext())
      {
        Turfs dturf = dbContext.Turfs.Where(t => t.Id == id).FirstOrDefault();
        if (dturf != null)
        {
          dbContext.Turfs.Remove(dturf);
          dbContext.SaveChanges();
          loadTurfs();
          loadTurfs_ToAllPlayers();
        }
      }
    }

    [RemoteEvent("SERVER:Turf_SetNewLeaderPoint")]
    public void RmtEvent_SetNewLeaderPoint(Player client, string vector, string jsonId) {
      int id = JsonConvert.DeserializeObject<int>(jsonId);
      if (id == -1)
      {
        ChatService.ErrorMessage(client, "Du befindest dich in keinem Gebiet");
        return;
      }
      using (var dbContext = new DatabaseContext())
      {
        Turfs dturf = dbContext.Turfs.Where(t => t.Id == id).FirstOrDefault();
        if (dturf != null)
        {
          dturf.Vector = vector;
          dbContext.SaveChanges();
          loadTurfs();
          loadTurfs_ToAllPlayers();
        }
      }
    }


    [RemoteEvent("SERVER:StartGangwar")]
    public void RmtEvent_StartGangwar(Player client)
    {
      if (!client.GetUser().FactionLeader)
        return;

      foreach (var turf in getTurfs())
      {
        if (turf.status == "attack")
        {
          ChatService.ErrorMessage(client,"Du kannst momentan kein Gangwar starten");
          return;
        }
      }
      if (client.GetUser().Faction.Name == "Ballas" || client.GetUser().Faction.Name == "Grove")
      {
        foreach (var turf in getTurfs())
        {
          foreach (var u in turf.playerInside)
          {
            if (u == client)
            {
              if (turf.Owner != client.GetUser().Faction.Name)
                turf.attack(client.GetUser().Faction.Name);
            }
          }
        }
      }

    }

  }
}
