using System.Runtime.CompilerServices;
using GraphicsManager.Enums;
using GraphicsManager.Interfaces;
using GraphicsManager.Objects;
using Luski.GUI.MainScreen.Interfaces;
using Luski.net.Structures.Public;
using Luski.Shared.PublicServers.V1.Enums;
using OpenTK.Mathematics;

namespace Luski.GUI.MainScreen.UI.PublicServers;

public class ChannelSelector : FlowLayout, IChannelAdder
{
    public SocketCategory CurrentCategory { get; }
    private readonly List<Category> cc = new();
    private readonly List<Channel> LoadedChannels = new();
    public Channel? Selected;

    private ChannelSelector(SocketCategory Cat)
    {
        CurrentCategory = Cat;
        Cat.Server.MessageReceived += ServerOnMessageReceived;
    }

    public static async Task<ChannelSelector> MakeSelector(SocketCategory Cat)
    {
        ChannelSelector cs = new(Cat);
        if (await Cat.Server.User.HasAccessToCategory(Cat, ServerPermission.CreateChannels))
        {
            LuskiContextMenu lcm = new();
            Label l = lcm.AddLabel("Create Channel");
            l.Clicked += cs.LOnClicked;
            cs.ContextMenu = lcm;
        }

        return cs;
    }

    private async Task LOnClicked(IRenderObject arg)
    {
        Globals.ms.Controls.Add(new AddChannel(this, CurrentCategory));
        TryDraw();
    }

    private async Task ServerOnMessageReceived(SocketMessage arg)
    {
        if (Selected is null || arg.ChannelID != Selected.CurrentChannel.ID) return;
        bool u = Globals.ms.pc.MessageFlow.MaxScrollValue == Globals.ms.pc.MessageFlow.ScrollValue;
        await Globals.ms.pc.AddMessage(arg, u);
       
    }

    public async Task Load(SocketChannel currentchannel, List<SocketCategory> parents)
    {
        IChannelAdder b = this;
        SocketChannel[] chanspp = await b.CurrentCategory.GetChannels();
        foreach (SocketChannel v in chanspp)
        { 
            Channel f = await b.AddChannel(v);
            if (v.ID == currentchannel.ID)
            {
                await f.ToggleSelected();
            }
        }
        SocketCategory[] cats = await b.CurrentCategory.GetCategories();
        foreach (SocketCategory v in cats)
        {
            await b.AddCategory(v);
            Globals.ms.DrawFrame();
        }
        foreach (SocketCategory par in parents)
        {
            b.Extended = true;
            b = await b.AddCategory(par);
            Globals.ms.DrawFrame();
            chanspp = await par.GetChannels();
            foreach (SocketChannel v in chanspp)
            { 
                Channel f = await b.AddChannel(v);
                if (v.ID == currentchannel.ID)
                {
                    await f.ToggleSelected();
                }
            }
            cats = await par.GetCategories();
            foreach (SocketCategory v in cats)
            {
                await b.AddCategory(v);
                Globals.ms.DrawFrame();
            }
        }
        
    }
    
    public async Task<Channel> AddChannel(SocketChannel chan)
    {
        Channel[] tc = LoadedChannels.Where(s => s.CurrentChannel.ID == chan.ID).ToArray();
        if (tc.Length > 0)
        {
            Channel cat23 = tc[0];
            if (!Controls.Contains(cat23))
            {
                Controls.Add(cat23);
            }
                
            return cat23;
        }
        Channel cat2 = await Channel.MakeChannel(chan, this);
        LoadedChannels.Add(cat2);
        cat2.BackgroundColor = BackgroundColor;
        Controls.Add(cat2);
        return cat2;
    }

    public bool Extended { get; set; } = true;
    
    public async Task<Category> AddCategory(SocketCategory Cat, DateTime? dt = null)
    {
        Category[] tc = cc.Where(s => s.CurrentCategory.ID == Cat.ID).ToArray();
        if (tc.Length > 0)
        {
            Category cat23 = tc[0];
            if (!Controls.Contains(cat23))
            {
                Controls.Add(cat23);
            }
                
            return cat23;
        }
        Category cat = await Category.MakeCat(Cat, this);
        cc.Add(cat);
        cat.BackgroundColor = BackgroundColor;
        cat.tmp.BackgroundColor = BackgroundColor;
        cat.Members.BackgroundColor = BackgroundColor;
        Controls.Add(cat);
        return cat;
    }
}