using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using DSharpPlus;
using DSharpPlus.CommandsNext;
using DSharpPlus.CommandsNext.Attributes;
using DSharpPlus.Entities;
using DSharpPlus.Interactivity;

namespace CSharp.Modules
{
    [Group]
    public class DiscordModule : BaseCommandModule
    {
        [Command]
        public async Task Assets(CommandContext ctx)
        {
            var assets = await ctx.Client.CurrentApplication.GetAssetsAsync();

            var (a, b, c) = (
                DiscordEmoji.FromGuildEmote(ctx.Client, 594249301295890463),
                DiscordEmoji.FromGuildEmote(ctx.Client, 452529445899730945),
                DiscordEmoji.FromGuildEmote(ctx.Client, 452529446214172692)
            );

            var mq = new DiscordMessageQueue(ctx.Channel);
            var state = null as DiscordMessage;
            var stream = null as MemoryStream;
            var downloader = new ApplicationAssetsDownloader(assets);
            var error = false;
            
            downloader.DownloadStartedAsync += async e =>
            {
                mq *= state = await ctx.RespondAsync($"{ctx.User.Mention} {a} Asset **{e.Name}** (`{e.Id}`)...");
            };

            downloader.DownloadFailedAsync += async e =>
            {
                if (!error) error = true;

                await state?.ModifyAsync($"{ctx.User.Mention} {c} Asset **{e.Name}** (`{e.Id}`) failed to download.");
            };

            downloader.DownloadCompletedAsync += async e =>
            {
                await state?.ModifyAsync($"{ctx.User.Mention} {b} Asset **{e.Name}** (`{e.Id}`) saved to archive.");
            };

            stream = await downloader.DownloadAsync();

            using (downloader)
            using (stream)
            {
                mq *= await ctx.RespondAsync($"{ctx.User.Mention} <:issueclosed:527890674822021137> Assets loaded" + (error ? " with errors." : "."));
                var w = await ctx.RespondAsync($"{ctx.User.Mention} <:issue:527890675182731274> Uploading archive.");
                await ctx.RespondWithFileAsync("assets.zip“", stream, ctx.User.Mention);
            }

            await mq.CleanupAsync();
            mq = null;
            stream = null;
            downloader = null;
            assets = null;
            state = null;
            error = default;
        }
    }
}