using System.Linq;
using GTANetworkAPI;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
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 - Event Login (Login.cs)
* @author VegaZ, aviate
* @copyright (c) 2008 - 2018 Life of German
*/

namespace ReallifeGamemode.Server.Events
{
  public class Login : Script
  {
    [RemoteEvent("CLIENT:Login_LoginRequest")]
    public void OnPlayerLogin(Player player, string password)
    {
      string username = player.Name;

      using (var dbContext = new DatabaseContext())
      {
        var user = dbContext.Users
            .Include(u => u.Group)
            .Include(u => u.BankAccount)
            .SingleOrDefault(b => b.Name == username);

        if (user == null)
        {
          player.TriggerEvent("SERVER:Login_Error", "Der Benutzer existiert nicht! Registriere dich zuerst!");
        }
        else
        {
          if (user.SocialClubName != player.SocialClubName && user.Password == NAPI.Util.GetHashSha256(password))
          {
            player.TriggerEvent("SERVER:Login_Error", "Dieser Benutzer gehört dir nicht!");
            //TODO ?? Log einbauen für den bösen Bub.
            player.Kick();
            return;
          }

          if (user.Password != NAPI.Util.GetHashSha256(password))
          {
            player.TriggerEvent("SERVER:Login_Error", "Passwort inkorrekt!");
          }
          else
          {
            player.Name = username;
            player.TriggerEvent("SERVER:Login_Success");
            player.TriggerEvent("CLIENT:StopSound");
            player.SetData("isLoggedIn", true);
            player.SetSharedData("isLoggedIn", JsonConvert.SerializeObject(true));
            player.SetData("spec", true);
            player.SetData("duty", false);
            player.SetData("Adminduty", false);
            player.TriggerEvent("SERVER:SET_HANDMONEY", user.Handmoney, 0);
            Gangwar.Gangwar.loadPlayer(player);
            if (user.FactionLeader)
            {
              player.TriggerEvent("CLIENT:Turf_LoadLeaderBlip");
            }
            if (user.IsAdmin(AdminLevel.HEADADMIN))
            {
              player.SetData("editmode", false);
              player.SetData("quicksavemode", "none");
            }

            var userBankAccount = user.BankAccount;
            userBankAccount.Balance = userBankAccount.Balance;

            user.Wanteds = user.Wanteds;

            if (user.Group != null)
            {
              string msg = $"{player.Name} ist wieder online.";
              ChatService.BroadcastGroup(msg, user.Group);
            }

            if (GlobalHelper.CustomJoinMessages.ContainsKey(player.SocialClubName))
            {
              ChatService.BroadcastAdmin("!{#FFFF00}*** " + GlobalHelper.CustomJoinMessages[player.SocialClubName] + " [ID: " + player.Handle.Value + "] (" + user.AdminLevel.GetName() + ")", AdminLevel.MAPPING);
            }
            else if (user.IsAdmin(AdminLevel.MAPPING))
            {
              ChatService.BroadcastAdmin("!{#FFFF00}*** " + user.Name + " [ID: " + player.Handle.Value + "]" + " hat sich als " + user.AdminLevel.GetName() + " eingeloggt!", AdminLevel.MAPPING);
            }

            var userItems = dbContext.UserItems.Where(u => u.UserId == user.Id).ToList();
            player.SetData("items", userItems);

            switch (user.FactionId)
            {
              case null:
                player.SetSharedData("blipColor", 0);
                break;

              case 8:
                player.SetSharedData("blipColor", 83);
                break;

              case 7:
                player.SetSharedData("blipColor", 52);
                break;

              case 4:
                player.SetSharedData("blipColor", 5);
                break;
            }

            if (user.CharacterId == null)
            {
              var currentPlayerCreatorDimension = (uint)NAPI.Data.GetWorldData("playerCreatorDimension");
              currentPlayerCreatorDimension++;
              NAPI.Data.SetWorldData("playerCreatorDimension", currentPlayerCreatorDimension);
              player.Dimension = NAPI.Data.GetWorldData("playerCreatorDimension");
              player.Position = new Vector3(402.8664, -996.4108, -99.00027);
              player.Rotation = new Vector3(0, 0, 180);
              player.TriggerEvent("toggleCreator");
            }
            else
            {
              CharacterCreator.ApplyCharacter(player);
              UpdateCharacterCloth.LoadCharacterDefaults(player);
              if (user.JailTime <= 0)
              {
                NAPI.Player.SpawnPlayer(player, new Vector3(user.PositionX, user.PositionY, user.PositionZ), 0);
              }
              else
              {
                Jail.Check_PutBehindBars(player);
              }
            }

            player.TriggerEvent("draw", player.Name, player.Handle.Value);
            if (user.Dead == true)
            {
              if (user.IsAdmin(AdminLevel.ADMIN) == true)
              {
                player.TriggerEvent("startDeathTimer", true);
                player.Health = 0;
              }
              else
              {
                player.TriggerEvent("startDeathTimer", false);
                player.Health = 0;
              }
              player.SetData("isDead", true);
            }
            else
            {
              player.SetData("isDead", false);
            }
          }
        }
      }
    }
  }
}
