using Discord.WebSocket;
using Discord;
using Discord.Commands;
using Discord.Net.Providers.WS4Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using System.IO;
using System.Text.RegularExpressions;

namespace KoogenBot
{
    class Program
    {
        private readonly DiscordSocketClient client;
        private readonly CommandService commands = new CommandService();
        public string compiledmsg, messagestr;
        private IServiceProvider services;
        static void Main(string[] args)
        {
            new Program().AsyncMain().GetAwaiter().GetResult();
        }

        private Program()
        {
            client = new DiscordSocketClient(new DiscordSocketConfig
            {
                LogLevel = LogSeverity.Info,
                WebSocketProvider = WS4NetProvider.Instance
            });
        }
        private async Task AsyncMain()
        {
            // Subscribe the logging handler.
            client.Log += Logger;
            commands.Log += Logger;

            // Login and connect.
            string tokenstart = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            string tokenpath = tokenstart + "\\conf\\token.txt";
            string token = System.IO.File.ReadAllText(tokenpath);
            await client.LoginAsync(TokenType.Bot, token);
            await client.StartAsync();

            await commands.AddModulesAsync(Assembly.GetEntryAssembly());
            //await commands.AddModuleAsync<AudioModule>();

            ConfigureServices();

            // Wait infinitely so your bot actually stays connected.
            await Task.Delay(-1);
        }

        private IServiceProvider ConfigureServices()
        {
            client.MessageReceived += MessageReceived;
            return services = new ServiceCollection()
                // Base
                .AddSingleton(client)
                .AddSingleton<CommandService>()
                //.AddSingleton<AudioService>()
                // Add additional services here...
                .BuildServiceProvider();
        }

        private async Task MessageReceived(SocketMessage message)
        {
            
            if (message.Content.StartsWith("Koogen ") || message.Content.StartsWith("koogen "))
            {
                messagestr = message.ToString().Remove(0, 7);
                compiledmsg = StripPunctuation(messagestr);
                //await message.Channel.SendMessageAsync(compiledmsg);
                Console.WriteLine(message.Author + " Said " + messagestr);
                if (File.Exists(compiledmsg.ToLower() + ".txt"))
                {
                    await message.Channel.SendMessageAsync(File.ReadAllText(compiledmsg + ".txt"));
                }
                else
                {
                    await message.Channel.SendMessageAsync("I don't know what '" + messagestr + "' Means. Tell me by typing how you'd respond to that message with a % in front of it!");
                    await message.Channel.SendMessageAsync("Example for 'How are you?': %I'm great today, thanks!");
                }
            }
            if (message.Content.StartsWith("%"))
            {
                string definition = message.ToString().Remove(0, 1);
                System.IO.StreamWriter file = new System.IO.StreamWriter(compiledmsg + ".txt");
                file.WriteLine(definition);
                file.Close();
                await message.Channel.SendMessageAsync("Alright, I'll respond with " + definition + " when someone says " + messagestr + " to me from now on.");
            }

            if (message.Content.Equals("!help"))
            {
                await message.Channel.SendMessageAsync("Fuck off, cunt.");
            }

            if (message.Content.Equals("!realhelp"))
            {
                await message.Channel.SendMessageAsync("`KOOGENBOT V. 1.1`");
                await message.Channel.SendMessageAsync("Made by (you guessed it!) Koogen");
                await message.Channel.SendMessageAsync("Next planned feature: Multiuser support and moods!");
                await message.Channel.SendMessageAsync("P.S. Fuck off, cunt.");
            }
        }

        public static string StripPunctuation(string s)
        {
            s = Regex.Replace(s, @"\s", "");
            var sb = new StringBuilder();
            foreach (char c in s)
            {
                if (!char.IsPunctuation(c))
                    sb.Append(c);
            }
            return sb.ToString();
        }

        private static Task Logger(LogMessage lmsg)
        {
            var cc = Console.ForegroundColor;
            switch (lmsg.Severity)
            {
                case LogSeverity.Critical:
                case LogSeverity.Error:
                    Console.ForegroundColor = ConsoleColor.Red;
                    break;
                case LogSeverity.Warning:
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    break;
                case LogSeverity.Info:
                    Console.ForegroundColor = ConsoleColor.White;
                    break;
                case LogSeverity.Verbose:
                case LogSeverity.Debug:
                    Console.ForegroundColor = ConsoleColor.DarkGray;
                    break;
            }
            string Log = $"{DateTime.Now,-19} [{lmsg.Severity,8}] {lmsg.Source}: {lmsg.Message}: {lmsg.Exception}";
            Console.WriteLine(Log);
            File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "log.txt", Log + Environment.NewLine);
            Console.ForegroundColor = cc;
            return Task.CompletedTask;
        }
    }
}