using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;

namespace HookahPlace;

class HookahBehaviour : NetworkBehaviour
{
	public Transform? smokePosition;
	public GameObject? smokePrefab;

    public Color[] Palette = [];

    private Color? ApplyLaterSmokeColor = null;
    private LocalVolumetricFog? ApplyLaterSmokeVolumetricFog;

    // Hookah smoke animation emits an event that invokes this method.
    // The prefab that it spawns self-destructs at the end of its animation.
    //
    // The fog works through LocalVolumetricFog components.
    // Inside the ship and under any roof outdoors there are placed FogExclusionZone objects,
    // with Blending set to Override which essentially removes the fog in those zones.
    //
    // The solution is to set your Hookah smoke blending to Additive (to preserve seamless transitions when fading out),
    // but crank up priority to something unreasonably high like 9001, so that it adds to that Override layer.
    public void SpawnSmoke()
    {
        if (smokePosition == null || smokePrefab == null)
        {
            return;
        }
        var ship = transform.parent.parent;
		var smoke = Instantiate(smokePrefab, smokePosition.position, Quaternion.identity, ship);
        var fog = smoke.GetComponentInChildren<LocalVolumetricFog>();
        // Randomize smoke color.
        // Clients set a client-side random color just in case, but it should be overridden by server rpc shortly.
        var index = Random.RandomRangeInt(0, Palette.Length);
        Color randomColor = Palette[index];
        if (IsServer)
        {
            SetSmokeColorClientRpc(randomColor);
            ApplySmokeColor(fog, randomColor);
        }
        else if (ApplyLaterSmokeColor is { } serverColor)
        {
            ApplySmokeColor(fog, serverColor);
            ApplyLaterSmokeColor = null;
        }
        else
        {
            // color has not arrived from server (yet), for now set local random color
            ApplySmokeColor(fog, randomColor);
            ApplyLaterSmokeVolumetricFog = fog;
        }
    }

    [Rpc(SendTo.NotServer)]
    public void SetSmokeColorClientRpc(Color color)
    {
        if (ApplyLaterSmokeVolumetricFog is { } fog)
        {
            ApplySmokeColor(fog, color);
            ApplyLaterSmokeVolumetricFog = null;
        }
        else
        {
            // smoke has not been spawned (yet), remember the color for later.
            ApplyLaterSmokeColor = color;
        }
    }

    private static void ApplySmokeColor(LocalVolumetricFog fog, Color color)
    {
        var parameters = fog.parameters;
        parameters.albedo = color;
        fog.parameters = parameters;
    }
}
