using System.Collections.Generic;
using System.Linq;
using GTANetworkAPI;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Types;

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

namespace ReallifeGamemode.Server.Managers
{
  public class DoorManager : Script
  {
    private static Dictionary<int, NetHandle> _doorColShapes = new Dictionary<int, NetHandle>();

    public static void LoadDoors()
    {
      using (var dbContext = new DatabaseContext())
      {
        foreach (Door door in dbContext.Doors)
        {
          _doorColShapes[door.Id] = NAPI.ColShape.CreateSphereColShape(door.Position, door.AlwaysOpen ? 200f : 30f);
        }
      }
    }

    public static void ReloadDoors()
    {
      foreach (var doorPair in _doorColShapes)
      {
        doorPair.Value.Entity<ColShape>().Delete();
      }
      _doorColShapes.Clear();
      LoadDoors();
    }

    public static void ChangeDoorState(Player player)
    {
      var user = player.GetUser();

      using (var dbContext = new DatabaseContext())
      {
        List<Door> NearDoors = dbContext.Doors.ToList().Where(d => d.Position.DistanceTo(player.Position) <= d.Radius).ToList();
        foreach (Door d in NearDoors)
        {
          if (d != null)
          {
            if (!user.IsAdmin(AdminLevel.ADMIN) && (d.FactionId != user.FactionId || d.FactionId == null))
            {
              string lockState = "~r~Du hast kein Recht diese T\u00fcr " + (d.Locked == true ? "auf" : "ab") + "zuschlie\u00dfen!";
              player.SendNotification(lockState, true);
              continue;
            }

            d.Locked = !d.Locked;

            string notStr = d.Name + " " + (d.Locked == false ? "~g~auf" : "~r~ab") + "geschlossen";

            player.SendNotification(notStr, true);

            NAPI.Pools.GetAllPlayers().ForEach(p => UpdateDoorState(p, d));
          }
        }
        dbContext.SaveChanges();
      }
    }

    [ServerEvent(Event.PlayerEnterColshape)]
    public void DoorManagerPlayerEnterColShapeEvent(ColShape colShape, Player player)
    {
      if (_doorColShapes.ContainsValue(colShape.Handle))
      {
        int doorId = _doorColShapes.Where(d => d.Value.Value == colShape.Handle.Value).FirstOrDefault().Key;

        using (var dbContext = new DatabaseContext())
        {
          Door door = dbContext.Doors.Where(d => d.Id == doorId).First();
          UpdateDoorState(player, door);
        }
      }
    }

    private static void UpdateDoorState(Player player, Door door)
    {
      player.TriggerEvent("changeDoorState", door.Model, door.X, door.Y, door.Z, (door.Locked || door.AlwaysOpen ? 1 : 0), 0.0f, 0.0f, door.AlwaysOpen ? 1.0f : 0.0f);
    }
  }
}
