using GraphicsManager.Enums;
using GraphicsManager.Interfaces;
using GraphicsManager.Objects;
using GraphicsManager.Objects.Core;
using Luski.net.Enums;
using Luski.net.Structures.Public;
using Luski.Shared.PublicServers.V1.Enums;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common.Input;

namespace Luski.GUI.MainScreen.UI.PublicServers;

public class Channel : UserControl
{
    private ChannelSelector CS;
    public SocketChannel CurrentChannel { get; set; }

    private Channel(Stream UserIcon, ChannelSelector cs, SocketChannel chan)
        : base(Globals.ms.TextureManager.GetTextureResource("RoundedRectangle.png"))
    {
        CS = cs;
        CurrentChannel = chan;
        base.Size = new(307.ScaleInt(), 34.ScaleInt());

        TextureDisplay = TextureDisplay.HorizontalCenter;
        Shader = Rectangle.DefaultAlphaShader[Globals.ms.Context];
        int i = 4.ScaleInt();
        r = new Rectangle(Globals.ms.TextureManager.GetAlphaCircle()) 
        {
            Location = new(i,i,0),
            Size = new (32.ScaleInt()),
            IgnoreHover = true
        };
        Texture tex;
        tex = Globals.ms.TextureManager.AddTexture(UserIcon);
        GC.Collect();
        UserIcon.Dispose();
        tex.Unit = TextureUnit.Texture1;
        r.Textures.Add(tex);
        r.Shader = Rectangle.DefaultAlphaTextureShader[Globals.ms.Context];
        Controls.Add(r);
        ChannelName = new Label(Globals.DefaultFont)
        {
            Text = chan.Name,
            Color = chan.Color.ToColor4(),
            IgnoreHover = true
        };
        Controls.Add(ChannelName);
        Clicked += AllOnClicked;
        ChannelName.Location = new(40.ScaleInt(),
            ((base.Size.Y - ChannelName.Size.Y) / 2)
            , 0);
        base.HoverMouse = MouseCursor.Hand;
    }
    
    private Channel(ChannelSelector cs, SocketChannel chan)
        : base(Globals.ms.TextureManager.GetTextureResource("RoundedRectangle.png"))
    {
        CS = cs;
        CurrentChannel = chan;
        base.Size = new(307.ScaleInt(), 34.ScaleInt());

        TextureDisplay = TextureDisplay.HorizontalCenter;
        Shader = Rectangle.DefaultAlphaShader[Globals.ms.Context];
        int i = 4.ScaleInt();
        GC.Collect();
        ChannelName = new Label(Globals.DefaultFont)
        {
            Text = chan.Name,
            Color = chan.Color.ToColor4(),
            IgnoreHover = true
        };
        Controls.Add(ChannelName);
        Clicked += AllOnClicked;
        ChannelName.Location = new(i,
            ((base.Size.Y - ChannelName.Size.Y) / 2)
            , 0);
        base.HoverMouse = MouseCursor.Hand;
    }

    public bool Selected { get; private set; }

    public async Task ToggleSelected()
    {
        try
        {
            Color4 bc = new(141,151,165,51);
            if (Selected)
            {
                bc = CS.BackgroundColor;
            }
            
            BlockDraw = true;
            Selected = !Selected;

            if (CS.Selected is not null && CS.Selected != this)
            {
                await CS.Selected.ToggleSelected();
            }
            BackgroundColor = bc;
            Task? mm = null;
            if (Selected)
            {
                CS.Selected = this;
                IReadOnlyList<SocketMessage> m;
                    m = await CurrentChannel.GetMessages(CancellationToken.None, Globals.Settings.LoadPerChannel);
                Globals.ms.pc.ClearChat();
                await Globals.ms.pc.LoadChannel(CurrentChannel);
                mm = Globals.ms.pc.AddMessages(m);
            }

            if (mm is not null)
            {
                Console.WriteLine("Waiting");
                Task.WaitAll(mm);
                Globals.ms.pc.MessageFlow.ForceScrollUpdate();
                if (Globals.ms.pc.MessageFlow.Controls.Length > 1 && Globals.ms.pc.MessageFlow.Controls[Globals.ms.pc.MessageFlow.Controls.Length - 1].Location.Y + Globals.ms.pc.MessageFlow.Controls[Globals.ms.pc.MessageFlow.Controls.Length - 1].Size.Y > Globals.ms.pc.MessageFlow.Size.Y)
                    Globals.ms.pc.MessageFlow.ScrollToBottom();
                else Globals.ms.pc.MessageFlow.ScrollToTop();
                Console.WriteLine("Done");
            }
            BlockDraw = false;
            TryDraw();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
    public Label ChannelName;
    public Rectangle r;

    public static async Task<Channel> MakeChannel(SocketChannel chan, ChannelSelector cs)
    {
        Channel c;
        if (chan.PictureType == PictureType.none) c = new(cs, chan);
        else c = new(await chan.GetPicture(CancellationToken.None), cs, chan);
        return c;
    }

    private Task EditChannelButtonOnClicked(IRenderObject arg)
    {
        arg.ContextMenu!.HideContext(Window!);
        return Task.CompletedTask;
    }

    private Task ExportKeysButtonOnClicked(IRenderObject arg)
    {
        //_ = CurrentChannel.SendKeysToUsers(CancellationToken.None);
        ContextMenu!.HideContext(Window!);
        return Task.CompletedTask;
    }
    
    private async Task AllOnClicked(IRenderObject arg)
    {
        if (!Selected) await ToggleSelected();
        //if (ClickCon is not null) _ = ClickCon.Invoke(this);
    }

    //public event Func<Channel, Task>? ClickCon;
}