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

public class NPC : PoolableObject
{
    public enum NPCState
    {
        INVISIBLE,
        NEUTRAL,
        BONUS,
        CHEERS,
        GRUMP,
        STARTUP
    }

    public NPCState myNPCState = NPCState.NEUTRAL;

    bool touched = false;

    public bool simulateLerp = false;
    bool manualLerp = false;

    static float moveSpeed = -1.8f;

    public static Color grumpColor = new Color(226f / 255f, 142f / 255f, 142f / 255f);
    public static Color cheersColor = new Color(132f / 255f, 224f / 255f, 111f / 255f);
    public static Color neutralColor = new Color(142f / 255f, 150f / 255f, 226f / 255f);
    public static Color invisibleColor = new Color(142f / 255f, 150f / 255f, 226f / 255f, 0);
    public static Color startupColor = new Color(183f / 255f, 95f / 255f, 238f / 255f);
    public static Color bonusColor = new Color(221f / 255f, 199f / 255f, 75f / 255f);

    static float lerpSpeed = .25f;

    public void Spawn(NPCState newNPCType, Vector3 newPosition)
    {
        touched = false;
        this.myNPCState = newNPCType;
        switch (this.myNPCState)
        {
            case NPCState.INVISIBLE:
                this.mainSprite.color = invisibleColor;
                this.mainAnimator.Play("Neutral");
                break;
            case NPCState.CHEERS:
                this.mainSprite.color = cheersColor;
                this.mainAnimator.Play("Cheers");
                break;
            case NPCState.GRUMP:
                this.mainSprite.color = grumpColor;
                this.mainAnimator.Play("Grump");
                break;
            case NPCState.NEUTRAL:
                this.mainSprite.color = neutralColor;
                this.mainAnimator.Play("Neutral");
                break;
            case NPCState.STARTUP:
                this.mainSprite.color = startupColor;
                this.mainAnimator.Play("Neutral");
                break;
            case NPCState.BONUS:
                this.mainSprite.color = bonusColor;
                this.mainAnimator.Play("Neutral");
                break;
        }
        this.transform.position = newPosition;
        if (!GlobalVariables.paused) this.mainRigidbody.velocity = new Vector2(moveSpeed, 0);
        base.Spawn();
    }
    
    void OnGameTitleExited()
    {
        if (this.myNPCState == NPCState.INVISIBLE && this != null)
        {
            StartCoroutine(LerpColor(invisibleColor, neutralColor, .25f, false));
            this.myNPCState = NPCState.NEUTRAL;
        }
    }

    void OnGameInitiated()
    {
        if (this.myNPCState == NPCState.STARTUP)
        {
            touched = true;
            mainAnimator.Play("Cheers");
            StartCoroutine(LerpColor(startupColor, cheersColor, .25f, false));
        }
    }

    void Awake()
    {
        if (this.myNPCState == NPCState.INVISIBLE)  Observer.gameTitleExitedHandler += OnGameTitleExited;
        if (this.myNPCState == NPCState.STARTUP) Observer.gameInitiatedHandler += OnGameInitiated;
            switch (this.myNPCState)
        {
            case NPCState.INVISIBLE:
                this.mainSprite.color = invisibleColor;
                break;
            case NPCState.CHEERS:
                this.mainSprite.color = cheersColor;
                break;
            case NPCState.GRUMP:
                this.mainSprite.color = grumpColor;
                break;
            case NPCState.NEUTRAL:
                this.mainSprite.color = neutralColor;
                break;
            case NPCState.STARTUP:
                this.mainSprite.color = startupColor;
                break;
            case NPCState.BONUS:
                this.mainSprite.color = bonusColor;
                break;
        }
    }

    IEnumerator LerpColor(Color from, Color to, float ttChange, bool backAgain)
    {
        float elapsed = 0.0f;
        while (elapsed < ttChange)
        {
            elapsed += Time.deltaTime;
            this.mainSprite.color = Color.Lerp(from, to, (elapsed / ttChange));
            yield return null;
        }
        if (backAgain)
            yield return StartCoroutine(LerpColor(to, Color.Lerp(to, from, 0.25f), ttChange, false));
        else
            yield return null;
    }

    public override void Despawn()
    {
        base.Despawn();
    }

    public void FixedUpdate()
    {
        float camRatio = Camera.main.orthographicSize / GlobalVariables.minSize;
        if (!GlobalVariables.paused) this.mainRigidbody.velocity = new Vector2(moveSpeed * camRatio, 0);
        if (manualLerp != simulateLerp)
        {
            manualLerp = simulateLerp;
            StartCoroutine(LerpColor(neutralColor, cheersColor, lerpSpeed, true));
        }
    }

    public void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            if (touched)
            {
                switch (this.myNPCState)
                {
                    case NPCState.NEUTRAL:
                    case NPCState.STARTUP:
                    case NPCState.BONUS:
                    case NPCState.CHEERS:
                        StartCoroutine(LerpColor(this.mainSprite.color, cheersColor, lerpSpeed, true));
                        break;
                }
                return;
            }
            switch (this.myNPCState)
            {
                case NPCState.GRUMP:
                    Observer.OnGrumpTouched(this);
                    touched = true;
                    Observer.OnGameOver();
                    break;
                case NPCState.NEUTRAL:
                case NPCState.STARTUP:
                    Observer.OnNeutralTouched(this);
                    this.mainAnimator.Play("Cheers");
                    this.myNPCState = NPCState.CHEERS;
                    StartCoroutine(LerpColor(this.mainSprite.color, cheersColor, lerpSpeed, true));
                    touched = true;
                    break;
                case NPCState.BONUS:
                    Observer.OnBonusTouched(this);
                    this.mainAnimator.Play("Cheers");
                    this.myNPCState = NPCState.CHEERS;
                    StartCoroutine(LerpColor(this.mainSprite.color, bonusColor, lerpSpeed, false));
                    touched = true;
                    break;
            }
        }
        if (collision.gameObject.tag == "GrumpShot")
        {
            touched = false;
            myNPCState = NPCState.GRUMP;
            this.mainAnimator.Play("Grump");
            StartCoroutine(LerpColor(this.mainSprite.color, grumpColor, lerpSpeed, false));
        }
        if (collision.gameObject.tag == "Shot")
        {
            if (touched) return;
            switch (this.myNPCState)
            {
                case NPCState.GRUMP:
                case NPCState.NEUTRAL:
                    Observer.OnNeutralTouched(this);
                    this.mainAnimator.Play("Cheers");
                    this.myNPCState = NPCState.CHEERS;
                    StartCoroutine(LerpColor(this.mainSprite.color, startupColor, lerpSpeed, false));
                    touched = true;
                    break;
                case NPCState.BONUS:
                    Observer.OnBonusTouched(this);
                    this.mainAnimator.Play("Cheers");
                    this.myNPCState = NPCState.CHEERS;
                    StartCoroutine(LerpColor(this.mainSprite.color, bonusColor, lerpSpeed, false));
                    touched = true;
                    break;
            }
        }
        if (collision.gameObject.tag == "Bonus")
        {
            if (touched) return;
            switch (this.myNPCState)
            {
                case NPCState.GRUMP:
                case NPCState.NEUTRAL:
                    Observer.OnNeutralTouched(this);
                    this.mainAnimator.Play("Cheers");
                    this.myNPCState = NPCState.CHEERS;
                    StartCoroutine(LerpColor(this.mainSprite.color, bonusColor, lerpSpeed, false));
                    touched = true;
                    break;
                case NPCState.BONUS:
                    Observer.OnBonusTouched(this);
                    this.mainAnimator.Play("Cheers");
                    this.myNPCState = NPCState.CHEERS;
                    StartCoroutine(LerpColor(this.mainSprite.color, bonusColor, lerpSpeed, false));
                    touched = true;
                    break;
            }

        }
        if (collision.gameObject.tag == "NPCEater")
        {
            this.Despawn();
        }
    }
}
