using System;
using Core.Domain;
using Core.Domain.Status.Effects;
using KBCore.Refs;
using UnityEngine;

namespace Infrastructure.Unity
{
    public class PowerUpViewAdapter : MonoBehaviour
    {
        [SerializeField] private PowerUpType type;
        [SerializeField] private float duration = 10f;
        [SerializeField] private ParticleSystem pickupVfx;

        [Self][SerializeField] private MeshRenderer meshRenderer;

        private MaterialPropertyBlock _propBlock;
        private static readonly int ColorProperty = Shader.PropertyToID("_BaseColor");

        public event Action<PowerUpType> OnCollected;

        private void Awake()
        {
            _propBlock = new MaterialPropertyBlock();
            ConfigureVisuals();
        }

        private void ConfigureVisuals()
        {
            switch (type)
            {
                case PowerUpType.LightFooted:
                    SetColor(EffectColors.LightFootedColor);
                    break;
                case PowerUpType.SpeedBoost:
                    SetColor(EffectColors.SpeedBoostColor);
                    break;
                case PowerUpType.TimeSlow:
                    SetColor(EffectColors.TimeSlowColor);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private void OnTriggerEnter(Collider other)
        {
            if (other.TryGetComponent<PlayerController>(out var player))
            {
                ApplyEffect(player);
                OnCollected?.Invoke(type);

                if (pickupVfx)
                {
                    var vfx = Instantiate(pickupVfx, transform.position, Quaternion.identity);
                    var main = vfx.main;
                    
                    meshRenderer.GetPropertyBlock(_propBlock);
                    var currentColor = _propBlock.GetColor(ColorProperty);
                    main.startColor = currentColor;
                    
                    Destroy(vfx.gameObject, 2f);
                }

                Destroy(gameObject);
            }
        }

        private void ApplyEffect(PlayerController player)
        {
            switch (type)
            {
                case PowerUpType.LightFooted:
                    player.Status.AddEffect(new LightFootedEffect(duration));
                    break;
                case PowerUpType.SpeedBoost:
                    player.Status.AddEffect(new SpeedBoostEffect(duration, 1.5f));
                    break;
                case PowerUpType.TimeSlow:
                    // Handled globally
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        public void Configure(PowerUpType newType)
        {
            type = newType;
            ConfigureVisuals();
        }

        private void SetColor(Color color)
        {
            meshRenderer.GetPropertyBlock(_propBlock);
            _propBlock.SetColor(ColorProperty, color);
            meshRenderer.SetPropertyBlock(_propBlock);
        }
    }
}