using Godot;
using Sfs3.Client.Entities.Audio;
using Sfs3.Client.Entities.Managers;
using Sfs3.Client.Entities.Managers.Audio;
using Sfs3.Client.Entities.Variables;
using System;
using System.Collections.Generic;

public partial class ProfileConfigurator : Control
{
	[Export]
	public PopupDialog profilePanel;

	[Export]
	public Label externalNameLabel;

	[Export]
	public Label internalNameLabel;

	[Export]
	public Label stateLabel;

	[Export]
	public CheckButton onlineCheck;

	[Export]
	public LineEdit nicknameInput;

	[Export]
	public LineEdit yearInput;

	[Export]
	public LineEdit moodInput;

	[Export]
	public OptionButton stateSelect;

	[Export]
	public OptionButton captureDeviceSelect;

	[Export]
	public OptionButton playbackDeviceSelect;

	[Export]
	public Button refreshDevicesButton;

	private IAudioManager audioManager;
	private Dictionary<string, AudioDevice> captureDevices = [];
    private Dictionary<string, AudioDevice> playbackDevices = [];
	private Action<bool> onlineChangeAction;
	private Action<string, object> buddySettingChangeAction;

	public Action<bool> OnlineChangeAction
	{
		get => onlineChangeAction;
		set => onlineChangeAction = value;
    }

	public Action<string, object> BuddySettingChangeAction
	{
		get => buddySettingChangeAction;
		set => buddySettingChangeAction = value;
	}

    public void DisplayUserName(string name)
    {
		externalNameLabel.Text = name;
		internalNameLabel.Text = "Name: " + name;
    }

	public void DisplayUserState(string state)
	{
		stateLabel.Text = "[" + state + "]";
	}
	
	/**
     * Show the profile settings related to the Buddy List system.
     */
	public void InitBuddyProfile(IBuddyManager sfsBuddyManager)
    {
        // User online/offline state
        onlineCheck.Disabled = false;
        onlineCheck.ButtonPressed = sfsBuddyManager.MyOnlineState;
        EnableBuddyControls(sfsBuddyManager.MyOnlineState);

        // User nickname
        nicknameInput.Text = sfsBuddyManager.MyNickname ?? "";

		// Available states and current user state
		stateSelect.Clear();

		int selectedIndex = -1;
		for (int i = 0; i < sfsBuddyManager.BuddyStates.Count; i++)
		{
			string state = sfsBuddyManager.BuddyStates[i];
			stateSelect.AddItem(state);

			if (state == sfsBuddyManager.MyState)
				selectedIndex = i;
		}
		stateSelect.Select(selectedIndex);

        // Buddy variable: user birth year
        var yearVar = sfsBuddyManager.GetMyVariable(LobbyController.BUDDYVAR_YEAR);
        yearInput.Text = (yearVar != null && !yearVar.IsNull) ? yearVar.IntValue.ToString() : "";

        // Buddy variable: user mood
        var moodVar = sfsBuddyManager.GetMyVariable(LobbyController.BUDDYVAR_MOOD);
        moodInput.Text = (moodVar != null && !moodVar.IsNull) ? moodVar.StringValue : "";
    }

	public void InitAudioControls(IAudioManager audioManager)
	{
		this.audioManager = audioManager;

		UpdateDevices();

		captureDeviceSelect.Disabled = false;
		playbackDeviceSelect.Disabled = false;
		refreshDevicesButton.Disabled = false;
	}

	private void EnableBuddyControls(bool enable)
	{
		nicknameInput.Editable = enable;
		stateSelect.Disabled = !enable;
		yearInput.Editable = enable;
		moodInput.Editable = enable;
	}

	private void UpdateDevices()
    {
		var devices = audioManager.Devices;
		var captureDevice = audioManager.CaptureDevice;
		var playbackDevice = audioManager.PlaybackDevice;

		captureDeviceSelect.Clear();
		captureDevices = [];

		foreach (AudioDevice d in devices.CaptureDevices)
		{
			captureDevices.Add(d.Name, d);
			captureDeviceSelect.AddItem(d.Name, d.Id);

			if (d.Name == captureDevice.Name)
				captureDeviceSelect.Select(captureDeviceSelect.GetItemIndex(d.Id));
		}

		playbackDeviceSelect.Clear();
		playbackDevices = [];

		foreach (AudioDevice d in devices.PlaybackDevices)
		{
			playbackDevices.Add(d.Name, d);
			playbackDeviceSelect.AddItem(d.Name, d.Id);

			if (d.Id == playbackDevice.Id)
				playbackDeviceSelect.Select(playbackDeviceSelect.GetItemIndex(d.Id));
		}
    } 

	// -------------------------------------------------------------------

	public void OnProfileButtonClick()
	{
		profilePanel.Show();
	}
	
	public void OnOnlineToggle(bool isOn)
    {
		onlineChangeAction?.Invoke(isOn);
		
		// Enable/disable controls
        EnableBuddyControls(isOn);
    }
	
	public void OnNicknameSubmit(string nickname)
	{
		buddySettingChangeAction?.Invoke(ReservedBuddyVariables.BV_NICKNAME, nickname);
    }
	
	public void OnNicknameFocusExit()
	{
		OnNicknameSubmit(nicknameInput.Text);
    }
	
	public void OnYearSubmit(string year)
	{
		bool isInteger = int.TryParse(year, out int value);

		buddySettingChangeAction?.Invoke(LobbyController.BUDDYVAR_YEAR, isInteger ? value : null);

		if (!isInteger)
			yearInput.Text = "";
    }
	
	public void OnYearFocusExit()
	{
		OnYearSubmit(yearInput.Text);
    }
	
	public void OnMoodSubmit(string mood)
	{
		buddySettingChangeAction?.Invoke(LobbyController.BUDDYVAR_MOOD, mood);
    }
	
	public void OnMoodFocusExit()
	{
		OnMoodSubmit(moodInput.Text);
    }
	
	public void OnStateSelected(int index)
	{
		buddySettingChangeAction?.Invoke(ReservedBuddyVariables.BV_STATE, stateSelect.GetItemText(index));
    }

    public void OnCaptureDeviceSelected(long index)
    {
        string deviceName = captureDeviceSelect.GetItemText((int)index);
        
        if (captureDevices.TryGetValue(deviceName, out AudioDevice device))
            audioManager.CaptureDevice = device;
    }

    public void OnPlaybackDeviceSelected(long index)
    {
        string deviceName = playbackDeviceSelect.GetItemText((int)index);
        
        if (playbackDevices.TryGetValue(deviceName, out AudioDevice device))
            audioManager.PlaybackDevice = device;
    }

    public void OnRefreshDevicesPressed()
    {
        UpdateDevices();
    }
}
