using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BossHandler : MonoBehaviour {
    public GameObject bossObject;

    float yBoundaryPosition = 1.5f;
    float yOffscreenPosition = -2.65f;
    float xPosition = 2.6f;

    public float currentPositionY = 2.65f;

    float scale = 4f;

    float bossShotScale = 1f;

    bool bossLoop = false;

    public int baseHealth = 3;
    int health = 3;
    Color originalColor;

    public Animator bossAnimator;

    SpriteRenderer mainRenderer;

    bool hurt = false;
    Color hurtStartColor;

    float hurtTimer = 0f;
    float hurtTime = .5f;

    private void Awake()
    {
        Observer.bossApproachesHandler += BossApproaches;
        Observer.bossReadyHandler += BossReady;
        Observer.bossDeadHandler += BossDead;
        Observer.bossCleanupHandler += BossCleanup;
        Observer.bossHitHandler += BossHit;
    }

    void Start()
    {
        mainRenderer = (SpriteRenderer)this.GetComponentInChildren<SpriteRenderer>(true);
        originalColor = mainRenderer.color;
    }

    private void FixedUpdate()
    {
        float cameraScale = Camera.main.orthographicSize / GlobalVariables.minSize;
        this.bossObject.transform.localPosition = new Vector3(xPosition * cameraScale, currentPositionY * cameraScale, 0f);
        this.bossObject.transform.localScale = new Vector3(scale * cameraScale * bossShotScale, scale * cameraScale * bossShotScale, scale * cameraScale * bossShotScale);
    }

    void BossCleanup()
    {
        bossObject.gameObject.SetActive(false);
    }

    void BossApproaches()
    {
        bossObject.gameObject.SetActive(true);
        currentPositionY = yOffscreenPosition;
        StartCoroutine(BossMove(currentPositionY, 0f, 12f, false));
        bossAnimator.Play("bossAnimation");
    }

    IEnumerator BossMove(float originalPosition, float destinationPosition, float moveTime, bool endBoss)
    {
        float t = 0f;
        while (t < moveTime)
        {
            t += Time.deltaTime;
            currentPositionY = Mathf.Lerp(originalPosition, destinationPosition, t / moveTime);
            yield return null;
        }
        if (endBoss)
            Observer.OnBossCleanup();
        yield return null;
    }

    IEnumerator BossLoop()
    {
        float attackTimer = 0f;
        float TTAttack = 5f;
        while (bossLoop)
        {
            attackTimer += Time.deltaTime;
            if (!hurt) mainRenderer.color = Color.Lerp(originalColor, Color.red, attackTimer / TTAttack);
            else
            {
                mainRenderer.color = Color.Lerp(hurtStartColor, Color.white, hurtTimer / hurtTime);
                if (hurtTimer < hurtTime)
                {
                    hurtTimer += Time.deltaTime;
                    if (hurtTimer >= hurtTime)
                    {
                        hurt = false;
                        hurtTimer = 0f;
                    }
                }
            }
            bossShotScale = Mathf.Lerp(1f, 1.5f, attackTimer / TTAttack);
            if (attackTimer >= TTAttack)
            {
                attackTimer = 0f;
                Observer.OnGrumpShot(this.bossObject.transform.position);
            }
            currentPositionY = Mathf.PingPong(Time.time, yBoundaryPosition * 2) - yBoundaryPosition;
            yield return null;
        }
        yield return null;
    }
    
    void BossHit()
    {
        if (bossLoop && health > 0)
        {
            health--;
            Observer.OnBossDamage(health);
            if (health <= 0)
            {
                hurt = true;
                hurtStartColor = this.mainRenderer.color;
                Observer.OnBossDead();
                bossAnimator.Play("bossAnimationDeath");
            }
        }
    }

    void BossReady()
    {
        this.health = baseHealth;
        currentPositionY = 0f;
        bossLoop = true;
        StartCoroutine(BossLoop());
    }

    void BossDead()
    {
        bossLoop = false;
        StartCoroutine(BossMove(currentPositionY, yOffscreenPosition, 4f, true));
    }
}
