using System;
using System.Collections;
using Oculus.Platform.Models;
using UnityEngine;
using UnityEngine.Assertions.Must;
using Random = UnityEngine.Random;

namespace Breakout
{
    public class BreakableCube : MonoBehaviour
    {
        public Vector3 speed;
        public bool spawnBall;
        public GameObject ballPrefab;
        public float fadeTime = 2f;
        
        private bool _hasSpawnedBall;
        private static readonly int Dissolve = Shader.PropertyToID("Vector1_b97048ce40a9495091dbb3eb2c84769e"); // From Dissolve Shader Graph

        private void Awake()
        {
            Events.OnBreakoutEndGame += EventDestroyCube;
            Events.OnBreakoutSetSpeed += SetSpeed;
            _hasSpawnedBall = false;
        }

        private void EventDestroyCube()
        {
            DestroyCube(false);
        }

        private void OnDestroy()
        {
            Events.OnBreakoutEndGame -= EventDestroyCube;
            Events.OnBreakoutSetSpeed -= SetSpeed;
        }

        private void Update()
        {
            transform.position += (speed * Time.deltaTime);
        }
    
        private void OnCollisionEnter(Collision other)
        {
            BreakoutBall ball = other.gameObject.GetComponent<BreakoutBall>();

            if (ball == null) return;
            DestroyCube(true);
        }

        private void DestroyCube(bool allowBallSpawn)
        {

            if (spawnBall & !_hasSpawnedBall & allowBallSpawn)
            {
                _hasSpawnedBall = true;
                var ball = Instantiate(ballPrefab, transform.position, Quaternion.identity, null);
        
                ball.GetComponent<Rigidbody>().AddForce(
                    new Vector3(
                        Random.Range(-2.0f, 2.0f), 
                        Random.Range(-2.0f, 2.0f), 
                        Random.Range(-2.0f, 2.0f)
                    ));
                
                Events.AddBalls();
            }
            
            speed.x = 0;
            
            StartCoroutine(FadeMaterial(GetComponent<MeshRenderer>().material, fadeTime));
            
            //Destroy(gameObject, Time.maximumDeltaTime);
        }

        private void SetSpeed(float newspeed)
        {
            speed.x = newspeed;
        }

        private IEnumerator FadeMaterial(Material material, float fadeTime)
        {
            while (material.GetFloat(Dissolve) < 0.9)
            {
                var newDissolve = Mathf.MoveTowards(material.GetFloat(Dissolve), 1, fadeTime * Time.deltaTime);
                material.SetFloat(Dissolve, newDissolve);
                yield return null;
            }
            
            Destroy(gameObject);
        }
    }
}