using UnityEngine;

namespace Saltosion.OneWeapon.Effects {
    public class DebrisParticle : MonoBehaviour {
        public LayerMask StickyLayers;

        public SpriteRenderer Renderer;

        public Vector2 LaunchForce = new Vector2();
        public bool Settled = false;
        public bool GetsStuck = true;
        public Sprite[] Sprites;

        private Rigidbody2D CurrentlyStuckOn = null;
        private Vector2 Velocity;

        private void Start() {
            transform.localScale = new Vector2(0.02f, 0.02f) + Random.value * new Vector2(0.10f, 0.10f);
            Velocity = LaunchForce + new Vector2(Random.value - 0.5f, Random.value - 0.5f);
            if (Sprites.Length > 0) {
                Renderer.sprite = Sprites[(int)(Random.value * int.MaxValue) % Sprites.Length];
                Renderer.flipX = Random.value < 0.5;
                Renderer.flipY = Random.value < 0.5;
            }
        }

        private void FixedUpdate() {
            Velocity *= 1.0f - Time.fixedDeltaTime * 20.0f;
            if (CurrentlyStuckOn != null) {
                bool IsStatic = CurrentlyStuckOn.bodyType == RigidbodyType2D.Static;
                Velocity *= 1.0f - Time.fixedDeltaTime * (IsStatic ? 50.0f : 15.0f);
            }
            if (Velocity.magnitude < 0.1) {
                if (CurrentlyStuckOn != null && GetsStuck) {
                    transform.parent = CurrentlyStuckOn.transform;
                    GetComponentInChildren<SpriteRenderer>().sortingLayerName = "Blood Particles (On characters)";
                    if (transform.parent.tag == "Player" && Random.value < 0.5) {
                        // Half of all blood particles are "drippy" so they drip away over time on the floor
                        gameObject.AddComponent(typeof(BloodDripper));
                    }
                }
                Destroy(GetComponent<BoxCollider2D>());
                Destroy(this);
            }

            Vector2 AppliedMovement = Velocity * Time.fixedDeltaTime;

            RaycastHit2D Hit = Physics2D.Raycast(transform.position, AppliedMovement, AppliedMovement.magnitude, StickyLayers);
            if (Hit.rigidbody != null && Hit.rigidbody.gameObject == Hit.collider.gameObject) {
                bool IsStatic = Hit.rigidbody.bodyType == RigidbodyType2D.Static;
                Velocity = Velocity.normalized * Mathf.Min(IsStatic ? 15.0f : 60.0f, Velocity.magnitude);
                CurrentlyStuckOn = Hit.rigidbody;
                AppliedMovement = Velocity * Time.fixedDeltaTime;
            } else if (CurrentlyStuckOn != null) {
                CurrentlyStuckOn = null;
            }

            Vector2 NewPosition = (Vector2)transform.position + AppliedMovement;

            transform.position = NewPosition;
        }
    }
}
