using System;
using System.Linq;
using GTANetworkAPI;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Managers;
using ReallifeGamemode.Server.Services;
using ReallifeGamemode.Server.Types;

/**
* @overview Life of German Reallife - Event Login (Login.cs)
* @author VegaZ, xSprite, aviate
* @copyright (c) 2008 - 2018 Life of German
*/

namespace ReallifeGamemode.Server.Events
{
  internal class Connect : Script
  {
    private readonly TimeSpan LightModeTimeFrom = new TimeSpan(5, 30, 0);
    private readonly TimeSpan LightModeTimeTo = new TimeSpan(21, 00, 0);

    [ServerEvent(Event.PlayerConnected)]
    public void OnPlayerConnected(Player player)
    {
      player.TriggerEvent("CLIENT:StopSound");
      //player.SetSharedData("vehicleAdminSpeed2", 1.0);
      player.SetData("isLoggedIn", false);
      player.Position = new Vector3(-1883.736, -781.4911, -10);

      bool registered = false;

      var whitelistStatus = Managers.SVarManager.SVars.FirstOrDefault(v => v.Variable == "WhitelistStatus")?.Value ?? 0;

      using (var dbContext = new DatabaseContext())
      {
        registered = dbContext.Users.Where(u => u.Name == player.Name).Any();
        switch (whitelistStatus)
        {
          case 0: //Whitelist aus
            break;

          case 1: //Whitelist aktiv (Main-Server)
            if (dbContext.Users.FirstOrDefault(u => u.SocialClubName == player.SocialClubName).AdminLevel < AdminLevel.MAPPING)
            {
              NAPI.Util.ConsoleOutput(player.Name + " versucht sich einzuloggen während die Whitelist an ist. [STATUS 1]");
              player.Kick();
              return;
            }
            break;

          case 2: //Whitelist aktiv (Test-Server)
            if (!dbContext.WhitelistEntries.Any(w => w.SocialClubName == player.SocialClubName))
            {
              string msg2 = "~m~*** " + player.Name + "[" + player.SocialClubName + "] (" + player.Address + ") hat versucht, sich einzuloggen, steht aber nicht auf der Whitelist.";
              ChatService.BroadcastAdmin(msg2, AdminLevel.ADMIN);

              NAPI.Util.ConsoleOutput(player.Name + " tried to join without whitelist entry [STATUS 2]");

              ChatService.SendMessage(player, "~m~Du stehst nicht auf der Whitelist");

              player.Kick();
              return;
            }
            break;
        }
      }

      if (IsPlayerBanned(player)) return;

      NAPI.Task.Run(() =>
      {
        player.TriggerEvent("CLIENT:PlaySound", "music/login", "mp3", 15);
      }, delayTime: 1000);
      player.TriggerEvent("CLIENT:AddPed", 1, "s_m_y_garbage", 484.88934326171875, -2174.380615234375, 5.918273448944092, -29.673072814941406, 0, false, true, 0, "none", true, true, true);//Ped_Müllmann
      player.TriggerEvent("CLIENT:AddPed", 2, "player_two", 1706.76953125, 3277.220947265625, 41.1555061340332, -159.447998046875, 0, false, true, 0, "none", true, true, true);//Ped_Pilot Sandyshores
      player.TriggerEvent("CLIENT:AddPed", 3, "s_m_m_pilot_01", -1621.4542236328125, -3152.724365234375, 13.991769790649414, 50.73009490966797, 0, false, true, 0, "none", true, true, true);//Ped_Pilot LS Airport
      player.TriggerEvent("CLIENT:AddPed", 4, "u_m_o_finguru_01", -534.4425659179688, -2145.747314453125, 5.992100715637207, 53.96156692504883, 0, false, true, 0, "none", true, true, true);//Ped Busfahrer
      TimeSpan currentTime = TimeManager.CurrentTime;
      bool disableLightMode = currentTime > LightModeTimeFrom && currentTime < LightModeTimeTo;

      player.TriggerEvent("SERVER:Login_ShowBrowser", registered, disableLightMode);
      string msg = "~m~*** " + player.Name + " [" + player.SocialClubName + "] [ID: " + player.Handle.Value + "] (" + player.Address + ")";
      if(player.HasData("togip"))
      { 
        ChatService.SendMessage(player, msg);
      }
    }

    private bool IsPlayerBanned(Player player)
    {
      using (var dbContext = new DatabaseContext())
      {
        var user = dbContext.Users.SingleOrDefault(b => b.Name == player.Name);
        if (user == null)
        {
          return false;
        }
        if (user.BanId != null)
        {
          var dt = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
          var bannedUser = dbContext.Bans.SingleOrDefault(u => u.Id == user.BanId);
          if (bannedUser.Applied == bannedUser.UntilDateTime)
          {
            ChatService.SendMessage(player, "!{#FF4040}Du wurdest permanent gebannt! [" + bannedUser.Reason + "]");
            player.Kick();
            return true;
          }
          else
          {
            var timeStamp = bannedUser.UntilDateTime;
            int unixTimestamp = (int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

            if (timeStamp > unixTimestamp)
            {
              ChatService.SendMessage(player, "Du bist noch bis zum !{#FF4040}" + dt.AddSeconds(timeStamp).ToLocalTime() + " Uhr ~s~gebannt. [" + bannedUser.Reason + "]");
              player.Kick();
              return true;
            }
            else
            {
              user.BanId = null;
              dbContext.SaveChanges();
              return false;
            }
          }
        }
        return false;
      }
    }
  }
}
