using UnityEngine;

public class EyeBall : BallBase
{
    private static float reorientationAngleDegrees = 3f;

    private Bounds boardBounds;

    private Collider2D selfCollider;

    private bool hasBoardBounds = false;

    private float magnetBounceDuration = 0.35f;

    private float magnetCenterLeeway = 0.12f;

    private MagnetBounceAxisState xMagnetBounceState;

    private MagnetBounceAxisState yMagnetBounceState;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        animator = GetComponent<Animator>();
        selfCollider = GetComponent<Collider2D>();
        speed = new Vector2(Random.Range(-0.05f, 0.05f), Random.Range(-0.05f, 0.05f));

        hasBoardBounds = TryCacheGameBoardBounds(out boardBounds);

        audioSource.PlayOneShot(spawnSound);
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);

        // Adjust eye ball direction based on the player's bar if active.
        var barSegments = GameObject.FindGameObjectsWithTag("Bar");

        if (barSegments.Length > 0)
        {
            // For simplicity, just take the first bar segment found.
            var barSegment = barSegments[0];
            Vector3 directionToBar = (barSegment.transform.position - transform.position).normalized;
            float currentSpeed = speed.magnitude;

            if (currentSpeed > 0f)
            {
                float signedAngle = Vector2.SignedAngle(speed.normalized, (Vector2)directionToBar);
                float clampedAngle = Mathf.Clamp(signedAngle, -reorientationAngleDegrees, reorientationAngleDegrees);
                Vector2 smoothDirection = (Vector2)(Quaternion.Euler(0f, 0f, clampedAngle) * speed.normalized);
                speed = smoothDirection * currentSpeed; // Maintain current speed magnitude
            }
        }

        if (stateInfo.IsName("EyeBallMove")) {
            transform.Translate(speed);

            if (affectedByMagnet && hasBoardBounds)
            {
                Vector3 currentPosition = transform.position;

                currentPosition.x = ApplyMagnetBounceAxis(
                    currentPosition.x,
                    boardBounds.min.x,
                    boardBounds.max.x,
                    magnetActiveLeftRight,
                    ref xMagnetBounceState,
                    selfCollider != null ? selfCollider.bounds.extents.x : 0.0f,
                    magnetBounceDuration,
                    magnetCenterLeeway
                );

                currentPosition.y = ApplyMagnetBounceAxis(
                    currentPosition.y,
                    boardBounds.min.y,
                    boardBounds.max.y,
                    magnetActiveTopBottom,
                    ref yMagnetBounceState,
                    selfCollider != null ? selfCollider.bounds.extents.y : 0.0f,
                    magnetBounceDuration,
                    magnetCenterLeeway
                );

                transform.position = currentPosition;
            }
        }
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        // EyeBall only bounces off walls, not other balls
        if (collision.gameObject.CompareTag("Wall"))
        {
            ContactPoint2D contact = collision.GetContact(0);
            speed = Vector2.Reflect(speed, contact.normal);
        }
        else
        {
            Physics2D.IgnoreCollision(collision.collider, GetComponent<Collider2D>(), true);
        }
    }
}
