using GraphicsManager.Enums;
using GraphicsManager.Interfaces;
using GraphicsManager.Objects;
using GraphicsManager.Objects.Core;
using Luski.Classes;
using Luski.GUI.MainScreen.UI.LuskiControls;
using Luski.Interfaces;
using Luski.net;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.GraphicsLibraryFramework;
using Rectangle = GraphicsManager.Objects.Rectangle;

namespace Luski.GUI.MainScreen.UI;

public class ServerLoginOverlay : UserControl, IServerOverlay
{
    private UserControl Form, btn;
    private DropDown<VersionDropButton> version;

    public AccountButton? Selected { get; set; }
    public UserControl page { get; set; }
    private TextBox? UserName, Password, DisplayName, tb;
    
    private Rectangle? rec;
    
    public ServerLoginOverlay(string address)
    {
        base.Size = Globals.ms.ClientSize;
        base.BackgroundColor = new(0, 0, 0, 130);
        Anchor = ObjectAnchor.All;

        
        
        Form = new(Globals.ms.TextureManager.GetTextureResource("RoundedRectangle.png"))
        {
            Size = new(350.ScaleInt(), 347.ScaleInt()),
            BackgroundColor = new(32,32,32,255),
            Shader = Rectangle.DefaultAlphaShader[Globals.ms.Context],
            TextureDisplay = TextureDisplay.Center
        };
        Label t;
        Form.Controls.Add(t=new Label(Globals.DefaultFont) { Scale = 1.6f, Text = "Server Login", Color = Globals.DodgerBlue });
        t.Location = new((Form.Size.X / 2) - (t.Size.X / 2), t.Location.Y, 0);
        
        #region Server Loc
        Label? ll = new Label(Globals.DefaultFont)
        {
            Text = net.API.DefaultVersion,
            Color = Color4.DarkGray,
            IgnoreHover = true
        };
        Vector2i s =new((int)(ll.Size.X * 1.6f),27.ScaleInt());
        ll = null;
        
        Rectangle line = new Rectangle()
        {
            Size = new Vector2i(1.ScaleInt()),
            BackgroundColor = Globals.DodgerBlue
        };

        tb = new()
        {
            Location = new(10.ScaleInt(),50.ScaleInt(), 0),
            Size = s,
            Text = address,
            WatermarkText = "Server Address",
            TextLocation = TextLocation.LineCenter,
            AllowMultiLine = false
        };
        tb.Textures[0] = Globals.ms.TextureManager.GetTextureResource("Textbox.png");
        tb.KeyPress += args =>
        {
            Texture t;
            Texture good = Globals.ms.TextureManager.GetTextureResource("Textbox.png");
            if ((args.Key == Keys.Backspace || args.Key == Keys.Delete) && string.IsNullOrWhiteSpace(tb.Text))
            {
                t = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
            }
            else
            {
                t = good;
            }

            if (tb.Textures[0].handel != t.handel)
            {
                tb.Textures[0] = t;
                if (t.handel == good.handel &&
                    UserName!.Textures[0].handel == good.handel &&
                    Password!.Textures[0].handel == good.handel &&
                    (rec is null || rec.Textures.Count > 1) &&
                    btn!.Textures[0].handel != good.handel &&
                    tb.Textures[0].handel == good.handel)
                {
                    if (Selected!.l.Text != "Login")
                    {
                        if (DisplayName!.Textures[0].handel == good.handel) btn.Textures[0] = good;
                    }
                    else btn.Textures[0] = good;
                }
                else if (t.handel != good.handel &&
                         (UserName!.Textures[0].handel != good.handel ||
                          Password!.Textures[0].handel != good.handel ||
                          (rec is not null && rec!.Textures.Count == 1) ||
                          btn!.Textures[0].handel == good.handel || 
                          tb.Textures[0].handel != good.handel || 
                          (DisplayName is not null && DisplayName.Textures[0].handel != good.handel)))
                {
                    btn!.Textures[0] = t;
                }
                Globals.ms.TryDraw();
            }

            return Task.CompletedTask;
        };
        tb.Size = new(Form.Size.X - tb.Location.X - tb.Location.X - tb.Location.X - s.X, tb.Size.Y);
        
        Form.Controls.Add(tb);
        
        version = new DropDown<VersionDropButton>(Form.Textures[0], line)
        {
            DropDownParentOverride = Form,
            Size = s,
            BackgroundColor = new(255,20,20,255),
            TextureDisplay = TextureDisplay.HorizontalCenter,
            Shader = Form.Shader,
            Location = new(tb.Location.X + tb.Size.X + tb.Location.X, tb.Location.Y, 0)
        };
        foreach (string v in Globals.Luski.SupportedVersions)
        {
            VersionDropButton option = new VersionDropButton(s, v)
            {
                LoadDisplay = () =>
                {
                    try
                    {
                        Label ll2 = new Label(Globals.DefaultFont)
                        {
                            Text = v,
                            Color = Color4.DarkGray,
                            IgnoreHover = true,

                        };
                        ll2.Location = new((version.Size.X / 2) - (ll2.Size.X / 2),
                            ((version.Size.Y - ll2.Size.Y) / 2)
                            , 0);
                        version.Controls.Add(ll2);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                }
            };
            version.AddOption(option);
            if (v == net.API.DefaultVersion)
            {
                version.SetSelected(option);
            }
        }
        
        version.OpenStatusChanged += VersionOnOpenStatusChanged;
        version.OptionSelected += VersionOnOptionSelected;
        
        
        version.DropDownContainer.Textures.Add(Globals.ms.TextureManager.GetTextureResource("RoundedRectangleBottom.png"));
        version.DropDownContainer.TextureDisplay = TextureDisplay.Center;
        version.DropDownContainer.Shader = Rectangle.DefaultAlphaShader[Globals.ms.Context];
        version.DropDownContainer.BackgroundColor = version.BackgroundColor;
        version.OpenStatusChanged += b =>
        {
            BlockDraw = true;
            if (b)
            {
                version.Textures[0] = Globals.ms.TextureManager.GetTextureResource("RoundedRectangleTop.png");
            }
            else
            {
                version.Textures[0] = Globals.ms.TextureManager.GetTextureResource("RoundedRectangle.png");
            }

            BlockDraw = false;
            return Task.CompletedTask;
        };
        
        
        #endregion

        #region Buttons

        AccountButton ca = new AccountButton("Create Account", this)
        {
            Location = new(tb.Location.X, tb.Location.Y + tb.Location.X + tb.Size.Y, 0),
            OnPageLoad = () =>
            {
                btn.Textures[0] = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                page!.Controls.Add(UserName = new()
                {
                    Location = new(0, 10.ScaleInt(), 0),
                    Size = new(page.Size.X, 30.ScaleInt()),
                    WatermarkText = "Username",
                    TextLocation = TextLocation.LineCenter,
                    AllowMultiLine = false
                });
                UserName.Textures[0] = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                UserName.KeyPress += args =>
                {
                    Texture t;
                    Texture good = Globals.ms.TextureManager.GetTextureResource("Textbox.png");
                    if ((args.Key == Keys.Backspace || args.Key == Keys.Delete || args.Alt || args.Shift || args.Control || args.Key == Keys.Enter || args.Key == Keys.KeyPadEnter || args.Key== Keys.Space) && string.IsNullOrWhiteSpace(UserName.Text))
                    {
                        t = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                    }
                    else
                    {
                        t = good;
                    }

                    if (UserName.Textures[0].handel != t.handel)
                    {
                        UserName.Textures[0] = t;
                        if (t.handel == good.handel &&
                            Password!.Textures[0].handel == good.handel &&
                            DisplayName!.Textures[0].handel == good.handel &&
                            rec!.Textures.Count > 1 &&
                            btn!.Textures[0].handel != good.handel &&
                            tb.Textures[0].handel == good.handel)
                        {
                            btn.Textures[0] = good;
                        }
                        else if (t.handel != good.handel &&
                                 (Password!.Textures[0].handel != good.handel ||
                                  DisplayName!.Textures[0].handel != good.handel ||
                                  rec!.Textures.Count == 1 ||
                                  btn!.Textures[0].handel == good.handel || tb.Textures[0].handel != good.handel))
                        {
                            btn!.Textures[0] = t;
                        }
                        Globals.ms.TryDraw();
                    }

                    return Task.CompletedTask;
                };
                
                page.Controls.Add(Password = new()
                {
                    Location = new(0, UserName.Location.Y + UserName.Size.Y + UserName.Location.Y + UserName.Location.Y, 0),
                    Size = new(page.Size.X, UserName.Size.Y),
                    WatermarkText = "Password",
                    TextLocation = TextLocation.LineCenter,
                    AllowMultiLine = false,
                    PasswordChar = '●'
                });
                Password.Textures[0] = UserName.Textures[0];
                Password.KeyPress += args =>
                {
                    Texture t;
                    Texture good = Globals.ms.TextureManager.GetTextureResource("Textbox.png");
                    if ((args.Key == Keys.Backspace || args.Key == Keys.Delete || args.Alt || args.Shift || args.Control || args.Key == Keys.Enter || args.Key == Keys.KeyPadEnter || args.Key== Keys.Space) && string.IsNullOrWhiteSpace(Password.Text))
                    {
                        t = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                    }
                    else
                    {
                        t = good;
                    }

                    if (Password.Textures[0].handel != t.handel)
                    {
                        Password.Textures[0] = t;
                        if (t.handel == good.handel && UserName!.Textures[0].handel == good.handel && DisplayName!.Textures[0].handel == good.handel && rec!.Textures.Count > 1 && btn!.Textures[0].handel != good.handel && tb.Textures[0].handel == good.handel)
                        {
                            btn.Textures[0] = good;
                        }
                        else if (t.handel != good.handel && (UserName!.Textures[0].handel != good.handel || DisplayName!.Textures[0].handel != good.handel || rec!.Textures.Count == 1 || btn!.Textures[0].handel == good.handel || tb.Textures[0].handel != good.handel))
                        {
                            btn!.Textures[0] = t;
                        }
                        Globals.ms.TryDraw();
                    }

                    return Task.CompletedTask;
                };
                
                page.Controls.Add(rec = new(Globals.ms.TextureManager.GetAlphaCircle())
                {
                    Size = new(50.ScaleInt()),
                    BackgroundColor = Color4.Red,
                    Shader = Rectangle.DefaultAlphaShader[Globals.ms.Context],
                    IgnoreHover = false
                });
                rec.Location = new(page.Size.X - rec.Size.X, page.Size.Y - rec.Size.Y, 0);
                
                page.Controls.Add(DisplayName = new()
                {
                    Location = new(0, Password.Location.Y + Password.Size.Y + UserName.Location.Y + UserName.Location.Y, 0),
                    Size = new(page.Size.X- tb.Location.X - rec.Size.X, Password.Size.Y ),
                    WatermarkText = "Display Name",
                    TextLocation = TextLocation.LineCenter,
                    AllowMultiLine = false
                });
                DisplayName.KeyPress += args =>
                {
                    Texture t;
                    Texture good = Globals.ms.TextureManager.GetTextureResource("Textbox.png");
                    if ((args.Key == Keys.Backspace || args.Key == Keys.Delete || args.Alt || args.Shift || args.Control || args.Key == Keys.Enter || args.Key == Keys.KeyPadEnter || args.Key== Keys.Space) &&
                        string.IsNullOrWhiteSpace(UserName.Text))
                    {
                        t = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                    }
                    else
                    {
                        t = good;
                    }

                    if (DisplayName.Textures[0].handel != t.handel)
                    {
                        DisplayName.Textures[0] = t;
                        if (t.handel == good.handel && UserName!.Textures[0].handel == good.handel &&
                            Password!.Textures[0].handel == good.handel && rec!.Textures.Count > 1 &&
                            btn!.Textures[0].handel != good.handel && tb.Textures[0].handel == good.handel)
                        {
                            btn.Textures[0] = good;
                        }
                        else if (t.handel != good.handel && (UserName!.Textures[0].handel != good.handel ||
                                                             Password!.Textures[0].handel != good.handel ||
                                                             rec!.Textures.Count == 1 ||
                                                             btn!.Textures[0].handel == good.handel || tb.Textures[0].handel != good.handel))
                        {
                            btn!.Textures[0] = t;
                        }

                        Globals.ms.TryDraw();
                    }
                    return Task.CompletedTask;
                };
                rec.FilesDroped += RecOnFilesDroped;
                DisplayName.Textures[0] = UserName.Textures[0];
                rec.ForceDistanceUpdate(page);
                Globals.ms.TryDraw();
                Globals.ms.ForceUpdate(new(Size));
            }
        };
        ca.Size = new((Form.Size.X - tb.Location.X - tb.Location.X - (tb.Location.X / 2)) / 2, ca.Size.Y);
        ca.l.Location = new((ca.Size.X - ca.l.Size.X) / 2,
            ((ca.Size.Y - ca.l.Size.Y) / 2)
            , 0);
        ca.l.ForceDistanceUpdate(ca);
        Form.Controls.Add(ca);
        
        AccountButton lo = new AccountButton("Login", this)
        {
            Location = new(ca.Location.X + ca.Size.X + (tb.Location.X / 2),ca.Location.Y, 0),
            OnPageLoad = () =>
            {
                btn!.Textures[0] = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                page!.Controls.Add(UserName = new()
                {
                    Location = new(0, 22.ScaleInt(), 0),
                    Size = new(page.Size.X, 31.ScaleInt()),
                    WatermarkText = "Username",
                    TextLocation = TextLocation.LineCenter,
                    AllowMultiLine = false
                });
                UserName.Textures[0] = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                UserName.KeyPress += args =>
                {
                    Texture t;
                    Texture good = Globals.ms.TextureManager.GetTextureResource("Textbox.png");
                    if ((args.Key == Keys.Backspace || args.Key == Keys.Delete || args.Alt || args.Shift || args.Control || args.Key == Keys.Enter || args.Key == Keys.KeyPadEnter || args.Key== Keys.Space) && string.IsNullOrWhiteSpace(UserName.Text))
                    {
                        t = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                    }
                    else
                    {
                        t = good;
                    }

                    if (UserName.Textures[0].handel != t.handel)
                    {
                        UserName.Textures[0] = t;
                        if (t.handel == good.handel &&
                            Password!.Textures[0].handel == good.handel &&
                            btn!.Textures[0].handel != good.handel &&
                            tb.Textures[0].handel == good.handel)
                        {
                            btn.Textures[0] = good;
                        }
                        else if (t.handel != good.handel &&
                                 (Password!.Textures[0].handel != good.handel ||
                                  btn!.Textures[0].handel == good.handel || tb.Textures[0].handel != good.handel))
                        {
                            btn!.Textures[0] = t;
                        }
                        Globals.ms.TryDraw();
                    }

                    return Task.CompletedTask;
                };
                
                page.Controls.Add(Password = new()
                {
                    Location = new(0, UserName.Location.Y + UserName.Size.Y + UserName.Location.Y + UserName.Location.Y, 0),
                    Size = new(page.Size.X, UserName.Size.Y),
                    WatermarkText = "Password",
                    TextLocation = TextLocation.LineCenter,
                    AllowMultiLine = false,
                    PasswordChar = '●'
                });
                Password.Textures[0] = UserName.Textures[0];
                Password.KeyPress += args =>
                {
                    Texture t;
                    Texture good = Globals.ms.TextureManager.GetTextureResource("Textbox.png");
                    if ((args.Key == Keys.Backspace || args.Key == Keys.Delete || args.Alt || args.Shift || args.Control || args.Key == Keys.Enter || args.Key == Keys.KeyPadEnter || args.Key== Keys.Space) &&
                        string.IsNullOrWhiteSpace(Password.Text))
                    {
                        t = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                    }
                    else
                    {
                        t = good;
                    }

                    if (Password.Textures[0].handel != t.handel)
                    {
                        Password.Textures[0] = t;
                        if (t.handel == good.handel &&
                            UserName!.Textures[0].handel == good.handel &&
                            btn!.Textures[0].handel != good.handel &&
                            tb.Textures[0].handel == good.handel)
                        {
                            btn.Textures[0] = good;
                        }
                        else if (t.handel != good.handel &&
                                 (UserName!.Textures[0].handel != good.handel ||
                                  btn!.Textures[0].handel == good.handel || tb.Textures[0].handel != good.handel))
                        {
                            btn!.Textures[0] = t;
                        }

                        Globals.ms.TryDraw();
                    }

                    return Task.CompletedTask;
                };
                DisplayName = null!;
                rec = null!;
            }
        };
        lo.Size = ca.Size;
        lo.l.Location = new((lo.Size.X / 2) - (lo.l.Size.X / 2),
            ((lo.Size.Y - lo.l.Size.Y) / 2)
            , 0);
        lo.l.ForceDistanceUpdate(lo);
        Form.Controls.Add(lo);
        

        #endregion
        
        Form.Controls.Add(version);

        page = new()
        {
            Location = new(tb.Location.X, ca.Location.Y + ca.Size.Y + tb.Location.X, 0),
            BackgroundColor = Form.BackgroundColor
        };
        page.Size = new(Form.Size.X - tb.Location.X - tb.Location.X, Form.Size.Y - tb.Location.X - page.Location.Y - ca.Size.Y - tb.Location.X);
        Form.Controls.Add(page);

        btn = new(Globals.ms.TextureManager.GetTextureResource("BadTextbox.png"))
        {
            Location = new(page.Location.X, page.Location.Y + page.Size.Y + tb.Location.X, 0),
            Size = new(page.Size.X, ca.Size.Y),
            TextureDisplay = TextureDisplay.Center
        };
        _ = lo.ToggleSelected();
        Label sub = new(Globals.DefaultFont)
        {
            Text = "Submit",
            IgnoreHover = true
        };
        sub.Location = new((btn.Size.X / 2) - (sub.Size.X / 2),
            ((btn.Size.Y - sub.Size.Y) / 2)
            , 0);
        sub.ForceDistanceUpdate(btn);
        btn.Controls.Add(sub);
        Form.Controls.Add(btn);
        Form.Location = new((base.Size.X - Form.Size.X) / 2, (base.Size.Y - Form.Size.Y) / 2, 0);
        Controls.Add(Form);
        btn.Clicked += BtnOnClicked;
    }

    private async Task BtnOnClicked(IRenderObject arg)
    {
        if (btn.Textures[0].handel == Globals.ms.TextureManager.GetTextureResource("BadTextbox.png").handel)
            return;
        bool s = true;
        string d = tb!.Text;
        if (d.Contains("://"))
        {
            string[] a = d.Split("://");
            d = a[1];
            if (a[0] == "http") s = false;
        }
        ServerInfo si = new()
        {
            Domain = d,
            Version = version.SelectedOption.l.Text,
            Main = false,
            Secure = s
        };
        IEnumerable<PublicServer> sers = Globals.Luski.LoadedServers.Where(s => s.Domain == tb.Text);
        if (sers.Any())
        {
            bool g;
            PublicServer ps = sers.First();
            if (DisplayName is null)
            {
                g = await ps.Login(UserName!.Text, Password!.Text, CancellationToken.None);
            }
            else
            {
                g = await ps.CreateAccount(UserName!.Text, Password!.Text, DisplayName.Text, pfp,
                    CancellationToken.None);
            }
            if (!g)
            {
                Texture b = Globals.ms.TextureManager.GetTextureResource("BadTextbox.png");
                UserName!.Textures[0] = b;
                Password!.Textures[0] = b;
                btn.Textures[0] = b;
                _ = Globals.ms.LoadPublicServer(ps);
                Globals.ms.TryDraw();
                
                return;
            }

            
        }
        
        Globals.ms.Controls.Remove(this);
        Globals.ms.ForceUpdate(new(Size));
        Globals.ms.TryDraw();
    }

    private Task VersionOnOptionSelected(VersionDropButton arg)
    {
        return Task.CompletedTask;
    }

    private Task VersionOnOpenStatusChanged(bool arg)
    {
        return Task.CompletedTask;
    }

    private string pfp = "";
    
    private Task RecOnFilesDroped(string[] arg)
    {
        Console.WriteLine(arg[0]);
        if (!arg[0].ToLower().EndsWith("png")) return Task.CompletedTask;
        
        pfp = arg[0];
        if (rec!.Textures.Count() ==1 )
        {
            Texture good = Globals.ms.TextureManager.GetTextureResource("Textbox.png");
            if (UserName!.Textures[0].handel == good.handel &&
                Password!.Textures[0].handel == good.handel &&
                btn!.Textures[0].handel != good.handel && tb.Textures[0].handel == good.handel)
            {
                if (DisplayName is not null)
                {
                    if (Password!.Textures[0].handel == good.handel) btn.Textures[0] = good;
                }
                else btn.Textures[0] = good;
            }
            Texture tex = Globals.ms.TextureManager.AddTexture(File.OpenRead(arg[0]));
            tex.Unit = TextureUnit.Texture1;
            rec.Shader = Rectangle.DefaultAlphaTextureShader[Globals.ms.Context];
            rec.Textures.Add(tex);
        }
        else
        {
            rec.Textures[1] = Globals.ms.TextureManager.AddTexture(File.OpenRead(arg[0]));
            rec.Textures[1].Unit = TextureUnit.Texture1;
        }
        
        Window!.TryDraw();
        return Task.CompletedTask;
    }
}