using System;
using UniRx;
using UniRx.Triggers;
using UnityEngine;

public class KitchenView : MonoBehaviour
{
    // blue
    private static readonly int Normal = Animator.StringToHash("Normal");
    private static readonly int Tired = Animator.StringToHash("Tired");
    private static readonly int Flame = Animator.StringToHash("Flame");
    // pink
    private static readonly int Walk = Animator.StringToHash("Walk");
    private static readonly int Stay = Animator.StringToHash("Stay");
    private static readonly int Sleep = Animator.StringToHash("Sleep");
    private static readonly int Vitality = Animator.StringToHash("Vitality");
    [SerializeField] private Animator blueBrotherAnimator;
    [SerializeField] private Animator pinkBrotherAnimator;
    [SerializeField] private Transform pinkTransform;
    [SerializeField] private float pinkWalkSpeed = .8f;
    [SerializeField] private float pinkLivelySpeed = .8f;
    private readonly (int trigger, Vector2 wayPoint, float wait)[] pinkMoves =
    {
        (Walk, new Vector2(3.28f,0.726f), 0f),
        // (Stay, new Vector2(3.28f,0.726f), 2f),
        (Walk, new Vector2(0f,0.726f), 0f),
        (Stay, new Vector2(0f,0.726f), 3f),
        (Walk, new Vector2(-3.28f,0.726f), 0f),
        // (Stay, new Vector2(-3.28f,0.726f), 2f),
        (Walk, new Vector2(0f,0.726f), 0f),
        (Stay, new Vector2(0f,0.726f), 3f),
    };
    
    private readonly (int trigger, Vector2 wayPoint, float wait)[] livelyPinkMoves =
    {
        (Vitality, new Vector2(3.28f,0.726f), 0f),
        (Vitality, new Vector2(-3.28f,0.726f), 0f),
    };

    private int moveIndex;
    private Vector2 wayPoint;
    private float durationDelta;
    private float completedDuration;
    private bool isLively;
    private (int trigger, Vector2 wayPoint, float wait)[] selectedMoves;
    
    private void Start()
    {
        this.UpdateAsObservable().Subscribe(_ =>
        {
            var pinkSpeed = isLively ? pinkLivelySpeed : pinkWalkSpeed;
            var localPosition = pinkTransform.localPosition;
            localPosition = Vector2.MoveTowards(localPosition, wayPoint, pinkSpeed * Time.deltaTime);
            pinkTransform.localPosition = localPosition;
            if (Vector2.Distance(localPosition, wayPoint) < .01f)
            {
                if (durationDelta < completedDuration)
                {
                    durationDelta += Time.deltaTime;
                    return;
                }
                durationDelta = 0;
                moveIndex++;
                if (moveIndex >= selectedMoves.Length)
                {
                    moveIndex = 0;
                }
                SetPinkMove();
            }
        }).AddTo(this);
    }

    public void Initialize()
    {
        moveIndex = 0;
    }

    private void ChangeAnimation()
    {
        moveIndex = 0;
        selectedMoves = isLively ? livelyPinkMoves : pinkMoves;
    }

    private void SetPinkMove()
    {
        var move = selectedMoves[moveIndex];
        wayPoint = move.wayPoint;
        completedDuration = move.wait;
        pinkBrotherAnimator.SetTrigger(move.trigger);
        if (Vector2.Distance(wayPoint, pinkTransform.localPosition.ToVector2()) < .01f)
        {
            // nop
        } else if ((wayPoint - pinkTransform.localPosition.ToVector2()).x > 0)
        {
            pinkTransform.localRotation = Quaternion.Euler(Vector3.up * 180);
        }
        else
        {
            pinkTransform.localRotation = Quaternion.Euler(Vector3.zero);
        }
    }

    public void SetNormalAnimation()
    {
        isLively = false;
        ChangeAnimation();
        SetPinkMove();
        blueBrotherAnimator.SetTrigger(Normal);
    }

    public void SetLivelyAnimation()
    {
        isLively = true;
        ChangeAnimation();
        SetPinkMove();
        blueBrotherAnimator.SetTrigger(Flame);
    }

    public void SetActive(bool active)
    {
        blueBrotherAnimator.transform.SetLocalScale(active ? 1f : 0f);
        pinkBrotherAnimator.transform.SetLocalScale(active ? 1f : 0f);
    }
}
