using System.Numerics;
using System.Reflection;
using GraphicsManager.Enums;
using GraphicsManager.Objects;
using Luski.Classes;
using Luski.Classes.Attribs;
using Luski.Classes.Attribs.NumberSlider;
using Luski.Enums.Strings;
using Luski.GUI.MainScreen.UI.LuskiControls;
using Luski.GUI.MainScreen.UI.LuskiControls.SettingsMenuBase.Core;
using OpenTK.Mathematics;

namespace Luski.GUI.MainScreen.UI.LuskiSettings.Pages;

public class Generic : PageFlow
{
    public Generic(string Name, byte code, bool LoadEnums = true, bool LoadBools = true, bool LoadNumberSelectors = true)
    {
        PageName = Name;
        foreach (PropertyInfo prop in typeof(Settings).GetProperties())
        {
            if (!prop.TryGetAnyAttribute(out SettingInfoAttribute? p)) continue;
            if (p.Page != code) continue;
            object PropVal = prop.GetValue(Globals.Settings)!;
            Type PropType = prop.PropertyType;
            
            if (LoadEnums && PropType.IsEnum)
            {
                IEnumerable<Enum> values = Enum.GetValues(PropType).Cast<Enum>();
                foreach (var val in values)
                {
                    try
                    {
                        Globals.AddBool(this, PropType, val, ((Enum)PropVal).HasFlag(val), bb =>
                        {
                            long va = Convert.ToInt64(val);
                            long v = Convert.ToInt64(PropVal);
                            object e;
                            if (bb) e = Enum.Parse(PropType, (v + va).ToString());
                            else e = Enum.Parse(PropType, (v - va).ToString());
                            PropVal = e;
                            prop.SetValue(Globals.Settings, e);
                            Globals.Settings.SaveSettings(Path.Combine(Globals.LuskiPath, "Settings.json"), SettingsContext.Default.Settings);
                        });
                    }
                    catch
                    {
                        //ignore
                    }
                }
                continue;
            }
            
            if (LoadBools && PropType.FullName == typeof(bool).FullName)
            {
                try
                {
                    Globals.AddBool(this, prop, (bool)PropVal, b =>
                    {
                        prop.SetValue(Globals.Settings, b);
                        Globals.Settings.SaveSettings(Path.Combine(Globals.LuskiPath, "Settings.json"), SettingsContext.Default.Settings);
                    });
                }
                catch
                {
                    // ignored
                }
                continue;
            }

            if (LoadNumberSelectors && prop.TryGetAnyAttribute(out NumberSelectorAttribute? typeinfo))
            {
                if (typeinfo.Kind.FullName == typeof(uint).FullName)
                {
                    Globals.AddNumberSlider(this, prop, (uint)PropVal, b =>
                    {
                        prop.SetValue(Globals.Settings, b);
                        Globals.Settings.SaveSettings(Path.Combine(Globals.LuskiPath, "Settings.json"), SettingsContext.Default.Settings);
                    });
                }
                
                if (typeinfo.Kind.FullName == typeof(double?).FullName)
                {
                    double? pv = (double?)PropVal;
                    Globals.AddNullNumberSlider(this, prop, pv, b =>
                    {
                        prop.SetValue(Globals.Settings, b);
                        Globals.Settings.SaveSettings(Path.Combine(Globals.LuskiPath, "Settings.json"), SettingsContext.Default.Settings);
                    });
                }
            }
        }
    }
}