using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;

public class MultiEyedOpponent : Opponent
{
    [SerializeField]
    private float _eyeMaxDistance = 2.0f;
    [SerializeField]
    private float _eyeSpeed = 3.0f;
    [SerializeField]
    private GameObject[] _eyes;

    private int _eyeLossHpInterval;
    private List<GameObject> _remainingEyes = new List<GameObject>();

    // tuple: (eye instance, start position, distance to end of arc, point to stop mid arc, start angle, modulated speed)
    private List<(GameObject eye ,float startX, float distance, float destination, float angle, float speed)> _dyingEyes = 
        new List<(GameObject eye, float startX, float distance, float destination, float angle, float speed)>();

    public override void Start()
    {
        base.Start();

        _remainingEyes.AddRange(_eyes);
        _eyeLossHpInterval = Hp / _eyes.Length;
    }

    public override void Update()
    {
        base.Update();

        // Check if Hp threshold for eye loss is reached
        if (_remainingEyes.Count > Hp / _eyeLossHpInterval)
        {
            int i = Random.Range(0, _remainingEyes.Count);
            var removedEye = _remainingEyes[i];

            var dyingEye = Instantiate(removedEye, transform);

            // Render in front of units
            var renderer = dyingEye.GetComponent<SpriteRenderer>();
            renderer.sortingLayerName = "Unit";
            renderer.sortingOrder = 100;

            // Setup launch params
            float startX = dyingEye.transform.position.x;
            float distance = Mathf.Sign(Random.Range(-1.0f, 1.0f)) * Random.Range(_eyeMaxDistance / 5, _eyeMaxDistance);
            float destination = Random.Range(distance / 2, distance);
            float angle = Random.Range(30.0f, 80.0f);
            float speed = Mathf.Sqrt(90 * 90 - angle * angle) / 90 * _eyeSpeed;
            _dyingEyes.Add((dyingEye, startX, distance, destination, angle, speed));

            // Remove from remaining eyes
            _remainingEyes.RemoveAt(i);
            removedEye.SetActive(false);
        }

        // Update dying eyes position
        foreach (var entry in _dyingEyes)
        {
            var eye = entry.eye;
            if (!eye) continue;

            // Get tuple launch params
            float startX = entry.startX;
            float distance = entry.distance;
            float destination = entry.destination;
            float angle = entry.angle;
            float speed = entry.speed;

            // Arc function
            float k = Mathf.Sign(distance) * Mathf.Tan(angle * Mathf.Deg2Rad);
            float a = -1.0f / distance;
            float x = (eye.transform.position.x - startX) + Mathf.Sign(distance) * speed * Time.deltaTime;
            float y = k * (a * x * x + x);

            // Check if reached destination
            if (Mathf.Abs(x) > Mathf.Abs(destination))
            {
                eye.GetComponent<Animator>().SetTrigger("Destroy");
                continue;
            }

            // Apply movement if not in destruction animation
            Vector2 newPos = new Vector2(startX + x, transform.position.y + y);
            eye.transform.position = newPos;
        }
    }
}
