using System;
using System.Collections;
using Cute;
using UnityEngine;

namespace Wizard;

public class ChatOpenCloseAnimation : MonoBehaviour
{
	public enum eState
	{
		CLOSED,
		OPENED,
		CLOSING,
		OPENING
	}

	public const float CLOSE_HEIGHT = 0f;

	[SerializeField]
	private GameObject _animationObj;

	[SerializeField]
	private bool _isActiveUpdate;

	[SerializeField]
	private float _openPositionY;

	[SerializeField]
	private float _closePositionY = -60f;

	[SerializeField]
	private float _openAnimationTime = 0.3f;

	[SerializeField]
	private float _closeAnimationTime = 0.2f;

	private Coroutine _coroutinAnimation;

	public eState State { get; private set; }

	public bool IsOpen
	{
		get
		{
			if (State != eState.OPENED)
			{
				return State == eState.OPENING;
			}
			return true;
		}
	}

	public bool IsMoving { get; private set; }

	public float CurrentPosHeight => _animationObj.transform.localPosition.y - _closePositionY;

	public float OpenHeight => _openPositionY - _closePositionY;

	public float AnimationTime
	{
		get
		{
			if (!IsOpen)
			{
				return _closeAnimationTime;
			}
			return _openAnimationTime;
		}
	}

	public bool IsAnimationStartFromOpenedOrClosed
	{
		get
		{
			if (State != eState.OPENING || !Mathf.Approximately(CurrentPosHeight, 0f))
			{
				if (State == eState.CLOSING)
				{
					return Mathf.Approximately(CurrentPosHeight, OpenHeight);
				}
				return false;
			}
			return true;
		}
	}

	public void Init(bool isOpenedDefault)
	{
		ChangeOpenedClosedState(isOpenedDefault);
	}

	public void ToggleStateAndStartAnimation()
	{
		switch (State)
		{
		case eState.CLOSED:
		case eState.CLOSING:
			StartOpenAnimation();
			break;
		case eState.OPENED:
		case eState.OPENING:
			StartCloseAnimation();
			break;
		}
	}

	public void StartCloseAnimation(Action onAnimationEndCallBack = null)
	{
		if (IsOpen)
		{
			if (_coroutinAnimation != null)
			{
				StopCoroutine(_coroutinAnimation);
			}
			_coroutinAnimation = StartCoroutine(CloseAnimation(onAnimationEndCallBack));
		}
	}

	public void StartOpenAnimation()
	{
		if (!IsOpen)
		{
			if (_coroutinAnimation != null)
			{
				StopCoroutine(_coroutinAnimation);
			}
			_animationObj.SetActive(value: true);
			_coroutinAnimation = StartCoroutine(OpenAnimation());
		}
	}

	private IEnumerator OpenAnimation()
	{
		State = eState.OPENING;
		Vector3 basePos = _animationObj.transform.localPosition;
		IsMoving = true;
		float durationTime = _openAnimationTime * (1f - CurrentPosHeight / OpenHeight);
		CustomEasing easing = new CustomEasing(CustomEasing.eType.outQuad, basePos.y, _openPositionY, durationTime);
		while (easing.IsMoving)
		{
			yield return null;
			float curVal = easing.GetCurVal(Time.deltaTime);
			_animationObj.transform.localPosition = new Vector3(basePos.x, curVal, basePos.z);
			if (State != eState.OPENING)
			{
				yield break;
			}
		}
		IsMoving = false;
		ChangeOpenedClosedState(isOpened: true);
	}

	private IEnumerator CloseAnimation(Action onAnimationEndCallBack)
	{
		State = eState.CLOSING;
		Vector3 basePos = _animationObj.transform.localPosition;
		IsMoving = true;
		float durationTime = _closeAnimationTime * CurrentPosHeight / OpenHeight;
		CustomEasing easing = new CustomEasing(CustomEasing.eType.outQuad, basePos.y, _closePositionY, durationTime);
		while (easing.IsMoving)
		{
			yield return null;
			float curVal = easing.GetCurVal(Time.deltaTime);
			_animationObj.transform.localPosition = new Vector3(basePos.x, curVal, basePos.z);
			if (State != eState.CLOSING)
			{
				yield break;
			}
		}
		IsMoving = false;
		ChangeOpenedClosedState(isOpened: false);
		onAnimationEndCallBack.Call();
	}

	private void ChangeOpenedClosedState(bool isOpened)
	{
		State = (isOpened ? eState.OPENED : eState.CLOSED);
		Vector3 localPosition = _animationObj.transform.localPosition;
		float y = (isOpened ? _openPositionY : _closePositionY);
		_animationObj.transform.localPosition = new Vector3(localPosition.x, y, localPosition.z);
		if (_isActiveUpdate)
		{
			_animationObj.SetActive(isOpened);
		}
	}
}
