using System;
using System.IO;
using System.Threading;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Collections.Generic;

using FilterAPI;
using FilterAPI.External;

using FilterDiscord.Commands;
using FilterDiscord.LocalHandlers;
using FilterDiscord.LocalNetworking;

using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.EventArgs;
using DSharpPlus.Net.WebSocket;

namespace FilterDiscord
{
    internal class Program
    {
        private static DiscordClient DClient;

        public static Authentication Auth;
        public static Database SQL;

        public static LocalClient LocalClient;
        public static LocalHandlerLoader LocalHandlers;

        private static String CommandPrefix = "&";

        private static void Main()
        {
            Auth = new Authentication();
            SQL = new Database(Auth);

                        Program.LocalHandlers = new LocalHandlerLoader();
            Program.LocalClient = new LocalClient();

            var AsyncProgram = new Program();
            AsyncProgram.RunBotAsync().GetAwaiter().GetResult();
        }

        public async Task RunBotAsync()
        {
            var DConfig = new DiscordConfiguration
            {
                Token = Encryption.DecryptText("9vWzGi5YcbRZAokVJ0MQWYo62gfkH0ThZBaxaw+JyG3mbs+FqpXTc55p5MO6p/mexMg0NxNfhSWR51FLP52tPQ==", "KGDQIN5B42lY2HoLQrusdehnyCcMoM4Xo2EZIiL0B96nhNo7sAIAtkrHwXNJ8Gk3"),
                TokenType = TokenType.Bot,

                AutoReconnect = true,
                LogLevel = LogLevel.Debug,
                UseInternalLogHandler = true
            };

            DClient = new DiscordClient(DConfig);
            DClient.SetWebSocketClient<WebSocketSharpClient>();
            DClient.Ready += DClient_Ready;
            DClient.MessageCreated += DClient_MessageCreated;

            await DClient.ConnectAsync();
            await Task.Delay(-1);
        }

        private async Task DClient_MessageCreated(MessageCreateEventArgs Args)
        {
            if (Args.Message.Channel.IsPrivate && Args.Author.Id != DClient.CurrentUser.Id && Args.Message.Content.StartsWith(CommandPrefix))
            {
                List<UInt64> DiscordAdminIDs = new List<UInt64>();

                foreach (String Line in File.ReadAllLines(String.Format("{0}DiscordAdminIDs.txt", AppDomain.CurrentDomain.BaseDirectory))) { DiscordAdminIDs.Add(Convert.ToUInt64(Line)); }

                if (DiscordAdminIDs.Contains(Args.Author.Id))
                {
                    String[] MessageSplit = Args.Message.Content.TrimStart(CommandPrefix.ToCharArray()[0]).Split(' ');

                    switch (MessageSplit[0].ToLower())
                    {
                        case "disconnectplayer":
                        case "dp":
                            {
                                new DisconnectPlayer().HandleCommand(CommandPrefix, Args, MessageSplit);

                                break;
                            }
                        case "deleteskill":
                        case "ds":
                            {
                                new DeleteSkill().HandleCommand(CommandPrefix, Args, MessageSplit);

                                break;
                            }
                    }
                }
                else { await Args.Channel.SendMessageAsync("Sorry you are not authorized to use any of my private commands."); }
            }
            else if (Args.Message.Channel.IsPrivate && Args.Author.Id != DClient.CurrentUser.Id) { await Args.Channel.SendMessageAsync("Sorry I have no idea what to do with what you have asked me."); }
        }

        private static async Task DClient_Ready(ReadyEventArgs Args)
        {
            Thread NewThread = new Thread(async delegate ()
            {
                while (true)
                {
                    using (SqlCommand Command = SQL.Connection.CreateCommand())
                    {
                        Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..{1}", Auth.ConfigValues["AccountDB"], Auth.ConfigValues["AccountTable"]);

                        Int32 AccountCount = Convert.ToInt32(Command.ExecuteScalar());

                        Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tCharacter", Auth.ConfigValues["CharacterDB"]);

                        Int32 CharacterCount = Convert.ToInt32(Command.ExecuteScalar());

                        Command.CommandText = String.Format("SELECT COUNT(*) FROM {0}..tGuild", Auth.ConfigValues["CharacterDB"]);

                        Int32 GuildCount = Convert.ToInt32(Command.ExecuteScalar());

                        Int32 OnlineCount = SQL.GetOnlineCount();

                        DiscordGuild DGuild = await DClient.GetGuildAsync(Convert.ToUInt64(File.ReadAllLines(String.Format("{0}DiscordServerID.txt", AppDomain.CurrentDomain.BaseDirectory))[0]));

                        foreach (DiscordChannel DChannel in DGuild.Channels) { await DChannel.ModifyAsync(DChannel.Name, DChannel.Position, String.Format("{0} stats || {1} Online || {2} Accounts || {3} Characters || {4} Guilds", Auth.ConfigValues["ServerName"], OnlineCount, AccountCount, CharacterCount, GuildCount)); }
                    }

                    Thread.Sleep(20000);
                }
            });

            NewThread.Start();
        }
    }
}
