using Godot;
using Godot.Collections;

namespace Cirno.Scripts.UI;

public partial class OptionsMenu : MenuBase
{
    [Export] public Array<Vector2I> Resolutions =
    [
        new(320, 160),
        new(512, 256),
        new(640, 320),
        new(1024, 512),
        new(1280, 640),
        new(1920, 1080),
    ];

    [Export] public OptionButton ResolutionsList { get; private set; }
    
    [Export] public CheckBox VSyncToggle { get; private set; }
    [Export] public CheckBox FullScreenToggle { get; private set; }
    
    //[Export] public HSlider MusicVolumeSlider { get; private set; }

    protected override void _on_back_button_pressed()
    {
        SaveSettings();
        
        base._on_back_button_pressed();
    }

    protected void _on_discard_button_pressed()
    {
        LoadSettings();
        base._on_back_button_pressed();
    }
    
    public override void _Ready()
    {
        //LoadSettings();
        foreach (var resolution in Resolutions)
        {
            ResolutionsList.AddItem($"{resolution.X}x{resolution.Y}");
        }

        ResolutionsList.ItemSelected += ResolutionsListOnItemSelected;

        VSyncToggle.SetPressed(DisplayServer.WindowGetVsyncMode() == DisplayServer.VSyncMode.Enabled);
        
        VSyncToggle.Toggled += VSyncToggleOnToggled;
        
        FullScreenToggle.SetPressed(DisplayServer.WindowGetMode() is DisplayServer.WindowMode.ExclusiveFullscreen);
        
        FullScreenToggle.Toggled += FullScreenToggleOnToggled;
    }

    private void FullScreenToggleOnToggled(bool toggledon)
    {
        switch (toggledon)
        {
            case true:
                DisplayServer.WindowSetMode(DisplayServer.WindowMode.ExclusiveFullscreen);
                break;
            case false:
                DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed);
                break;
        }
    }

    private void VSyncToggleOnToggled(bool toggledOn)
    {
        if (toggledOn)
        {
            DisplayServer.WindowSetVsyncMode(DisplayServer.VSyncMode.Enabled);
        }
        else
        {
            DisplayServer.WindowSetVsyncMode(DisplayServer.VSyncMode.Disabled);
        }
    }

    private void ResolutionsListOnItemSelected(long index)
    {
        GD.Print($"Selected index: {index} {Resolutions[(int)index]}");
        DisplayServer.WindowSetSize(Resolutions[(int)index]);
    }

    private void SaveSettings()
    {
        var config = new ConfigFile();
        
        config.SetValue("Screen","FullScreenMode", (int)DisplayServer.WindowGetMode());
        config.SetValue("Screen", "VSyncMode", (int)DisplayServer.WindowGetVsyncMode());
        
        config.SetValue("Audio", "Master", AudioServer.GetBusVolumeLinear(AudioServer.GetBusIndex("Master")));
        config.SetValue("Audio", "Music", AudioServer.GetBusVolumeLinear(AudioServer.GetBusIndex("Music")));
        config.SetValue("Audio", "Effects", AudioServer.GetBusVolumeLinear(AudioServer.GetBusIndex("Effects")));
        config.SetValue("Audio", "Voice", AudioServer.GetBusVolumeLinear(AudioServer.GetBusIndex("Voice")));
        
        config.SetValue("Language", "Language", TranslationServer.GetLocale());
        
        config.Save("user://Settings.cfg");
    }

    public static void LoadSettings()
    {
        var config = new ConfigFile();
        Error err = config.Load("user://Settings.cfg");

// If the file didn't load, ignore it.
        if (err != Error.Ok)
        {
            GD.PrintErr($"Error loading settings: {err}");
            return;
        }
        
        DisplayServer.WindowSetMode((DisplayServer.WindowMode) config.GetValue("Screen", "FullScreenMode", (int)DisplayServer.WindowGetMode()).AsInt32());
        
        DisplayServer.WindowSetVsyncMode((DisplayServer.VSyncMode)config.GetValue("Screen", "VSyncMode", (int)DisplayServer.WindowGetVsyncMode()).AsInt32());
        
        AudioServer.SetBusVolumeLinear(AudioServer.GetBusIndex("Master"), config.GetValue("Audio", "Master", AudioServer.GetBusVolumeLinear(AudioServer.GetBusIndex("Master"))).AsSingle());
        
        AudioServer.SetBusVolumeLinear(AudioServer.GetBusIndex("Effects"), config.GetValue("Audio", "Effects", AudioServer.GetBusVolumeLinear(AudioServer.GetBusIndex("Effects"))).AsSingle());
        
        AudioServer.SetBusVolumeLinear(AudioServer.GetBusIndex("Music"), config.GetValue("Audio", "Music", AudioServer.GetBusVolumeLinear(AudioServer.GetBusIndex("Music"))).AsSingle());
        
        AudioServer.SetBusVolumeLinear(AudioServer.GetBusIndex("Voice"), config.GetValue("Audio", "Voice", AudioServer.GetBusVolumeLinear(AudioServer.GetBusIndex("Voice"))).AsSingle());
        
        TranslationServer.SetLocale(config.GetValue("Language", "Language", "en").ToString());
        
        // Scale mouse

        GlobalState.Instance.ResizeCursor();
    }
}