
using UdonSharp;
using UnityEngine;
using VRC.SDK3.UdonNetworkCalling;
using VRC.Udon.Common.Interfaces;
using VRC.SDKBase;
using System.Linq;

public enum MusicEventType
{
	None,
	WhereInTheWorld,
	RockapellaIdent
}

public enum SFXEventType
{
	None,
	Buzzer
}

[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class GameManager : UdonSharpBehaviour
{
	[Header("Player Data")]
	public PlayerPodium[] PlayerPodiums;

	[Header("Audio")]
	[SerializeField] private AudioClip BuzzerSound = null;

	[SerializeField] private AudioClip WhereInTheWorld = null;
	[SerializeField] private AudioClip RockapellaIdent = null;

	[SerializeField] private AudioSource MusicPlayer = null;
	[SerializeField] private AudioSource SFXPlayer = null;

	[UdonSynced] private bool BuzzInAllowed = true;
	[UdonSynced] private bool[] PlayerBuzzInAllowed;
	[UdonSynced] private int _BuzzedInPlayer = -1;

	void Start()
	{
		PlayerBuzzInAllowed = new bool[PlayerPodiums.Length];
	}


	[NetworkCallable]
	public void PlayerBuzzedIn(int PlayerNumber)
	{
		int PlayerIndex = PlayerNumber - 1;
		if (!BuzzInAllowed || !PlayerBuzzInAllowed[PlayerIndex]) { return; }

		// Prevent new buzz-ins and store which player is currently buzzed in.
		BuzzInAllowed = false;
		PlayerBuzzInAllowed[PlayerIndex] = false;
		_BuzzedInPlayer = PlayerNumber;
		RequestSerialization();

		NetworkCalling.SendCustomNetworkEvent(
			(IUdonEventReceiver)PlayerPodiums[PlayerIndex],
			NetworkEventTarget.All,
			"EnableBuzzInEffect", true);

		// Play the buzzer sound globally.
		SendCustomNetworkEvent(NetworkEventTarget.All, nameof(PlaySFX), SFXEventType.Buzzer);
	}
	public void CancelPlayerBuzzIn() {
		BuzzInAllowed = true;
		NetworkCalling.SendCustomNetworkEvent(
			(IUdonEventReceiver)PlayerPodiums[_BuzzedInPlayer - 1],
			NetworkEventTarget.All,
			"EnableBuzzInEffect", false);
		_BuzzedInPlayer = -1;
		RequestSerialization();
	}


	public void ResetBuzzers()
	{
		BuzzInAllowed = true;
		for (int i = 0; i < PlayerPodiums.Length; i++) { PlayerBuzzInAllowed[i] = true; }
		_BuzzedInPlayer = -1;
	}


	public void PlayWhereInTheWorld()
	{
		SendCustomNetworkEvent(NetworkEventTarget.All, nameof(PlayMusic), MusicEventType.WhereInTheWorld);
	}

	public void PlayRockapellaIdent()
	{
		SendCustomNetworkEvent(NetworkEventTarget.All, nameof(PlayMusic), MusicEventType.RockapellaIdent);
	}

	[NetworkCallable]
	public void PlayMusic(MusicEventType MusicEvent)
	{
		MusicPlayer.Stop();

		switch (MusicEvent)
		{
			case MusicEventType.WhereInTheWorld:	MusicPlayer.clip = WhereInTheWorld;	break;
			case MusicEventType.RockapellaIdent:	MusicPlayer.clip = RockapellaIdent;	break;
			default:								MusicPlayer.clip = null;			break;
		}

		if (MusicPlayer.clip != null)
			MusicPlayer.Play();
	}


	[NetworkCallable]
	public void PlaySFX(SFXEventType SFXEvent)
	{
		SFXPlayer.Stop();

		switch (SFXEvent)
		{
			case SFXEventType.Buzzer:	SFXPlayer.clip = BuzzerSound;	break;
			default:					SFXPlayer.clip = null;			break;
		}

		if (SFXPlayer.clip != null)
			SFXPlayer.Play();
	}
}
