using System.Collections;
using System.Linq;
using Cute;
using Spine;
using Spine.Unity;
using UnityEngine;

namespace Wizard.Battle.Player.ClassCharacter;

public class SpineObject
{
	protected readonly string ANIMATION_TRANSFORM_NAME = "AnimationTransform";

	public const float SPINE_CORRECTION_SCALE = 1.003125f;

	public const float SPINE_ORTHO_SCALE_Y = 1.1207f;

	protected readonly Vector3 SPINE_DEFAULT_SCALE = new Vector3(6.4f, 6.4f, 20.48f) * 1.003125f;

	protected readonly Vector3 SPINE_EVOLVE_ROTATION = new Vector3(-29f, 0f, 0f);

	protected readonly Vector3 OUT_OF_FRAME_POSITION = new Vector3(3f, 2f, -6f);

	public static readonly Vector3 BILLBOARD_ROTATE = new Vector3(-12f, 0f, 0f);

	public static readonly Vector3 BILLBOARD_ROTATE_REVERSE_VERTICAL = new Vector3(-12f, 0f, 180f);

	protected readonly Vector3 BILLBOARD_ROTATE_EVOLVE = new Vector3(-29f, 0f, 0f);

	protected readonly Vector3 SPINE_EVOLVE_SCALE = new Vector3(5.8f, 6.5f, 20.48f) * 1.003125f;

	public static readonly Vector3 OPPONENT_MECANIM_POSITION = new Vector3(0f, -0.2f, 0f);

	public GameObject _spineObject;

	protected Transform _animationTransform;

	protected SpriteRenderer _maskOutSprite;

	protected Material _spineMaterial;

	protected Material _maskMaterial;

	protected Vector3 _spineEvolveScale;

	protected ClassCharacterBase _character;

	public SkeletonMecanim _skeletonMecanim { get; private set; }

	public Animator _animator { get; private set; }

	public SpriteRenderer _maskSprite { get; protected set; }

	public bool IsBack { get; private set; }

	public bool IsNoEvolveShift { get; private set; }

	public bool IsOpponentReverse { get; private set; }

	private string MaskTextureName(string skinId)
	{
		if (_character is HighRankSpineClassCharacter)
		{
			return "tx_Encampment_" + skinId + "_mask";
		}
		if (Global.IsSnCollabSkin(int.Parse(skinId)))
		{
			return "tx_Encampment_sn_mask";
		}
		return "tx_encampment_mask";
	}

	private void SetMaterialInfo(MeshRenderer meshRenderer, int stencil)
	{
		_spineMaterial = Object.Instantiate(meshRenderer.material);
		_spineMaterial.SetInt("_Stencil", stencil);
		meshRenderer.material = _spineMaterial;
		for (int i = 0; i < meshRenderer.materials.Length; i++)
		{
			Material material = meshRenderer.materials[i];
			if (material != null && material.GetInt("_Stencil") != stencil)
			{
				meshRenderer.materials[i] = Object.Instantiate(material);
				meshRenderer.materials[i].SetInt("_Stencil", stencil);
			}
		}
	}

	public void LoadAndSetTest(string skinId, ClassCharacterBase character, Transform wrapObject, bool isBack = false)
	{
		_spineObject = null;
		_character = character;
		IsBack = isBack;
		IsNoEvolveShift = _character.IsNoEvolveShift();
		GameObject gameObject = Resources.Load<GameObject>("Jpn/Ui/ClassChar/Prefab/class_" + skinId);
		if (!(gameObject != null))
		{
			return;
		}
		_maskSprite = new GameObject().AddComponent<SpriteRenderer>();
		_maskSprite.sprite = Resources.Load<Sprite>("Jpn/Ui/ClassChar/Textures/" + MaskTextureName(skinId));
		_maskMaterial = Object.Instantiate(Resources.Load<Material>("Jpn/Ui/ClassChar/Materials/mt_encampment_mask"));
		_maskMaterial.SetInt("_Stencil", character.GetStencil());
		_maskSprite.material = _maskMaterial;
		_maskSprite.transform.parent = wrapObject;
		_maskSprite.transform.localPosition = character.GetMaskImagePosition();
		_maskSprite.transform.localScale = Vector3.one * 0.46f;
		_maskSprite.gameObject.layer = 15;
		_maskSprite.sortingOrder = character.GetMaskSortingOrder(IsBack);
		_maskSprite.name = "SpineMask";
		_maskSprite.transform.localRotation = character.GetMaskImageRotation();
		_maskOutSprite = new GameObject().AddComponent<SpriteRenderer>();
		_maskOutSprite.sprite = Resources.Load<Sprite>("Jpn/Ui/ClassChar/Textures/tx_encampment_mask_out");
		_maskOutSprite.material = _maskMaterial;
		_maskOutSprite.transform.parent = wrapObject;
		_maskOutSprite.transform.localPosition = character.GetMaskImagePosition();
		_maskOutSprite.transform.localScale = new Vector3(30f, 30f, 1f);
		_maskOutSprite.gameObject.layer = 10;
		_maskOutSprite.sortingOrder = character.GetMaskSortingOrder(IsBack);
		_maskOutSprite.name = "SpineMaskOut";
		_maskOutSprite.gameObject.SetActive(value: false);
		if (character is HighRankSpineClassCharacter)
		{
			GameObject gameObject2 = null;
			foreach (Transform item in gameObject.transform)
			{
				if (item.gameObject.name == (IsBack ? "back" : "front"))
				{
					gameObject2 = item.gameObject;
					break;
				}
			}
			if (!(gameObject2 != null))
			{
				return;
			}
			gameObject = gameObject2;
		}
		_spineObject = Object.Instantiate(gameObject);
		_animationTransform = _spineObject.transform.Find(ANIMATION_TRANSFORM_NAME);
		Transform transform2 = _spineObject.transform;
		MotionUtils.SetLayerAll(_spineObject, 15);
		transform2.parent = wrapObject;
		transform2.localPosition = character.GetSpinePosition();
		transform2.localScale = character.ConvertSpineScale(transform2.localScale);
		transform2.localEulerAngles = GetDefaultRotate();
		_skeletonMecanim = transform2.GetComponentInChildren<SkeletonMecanim>();
		if (IsOpponentReverse)
		{
			_skeletonMecanim.transform.localPosition = OPPONENT_MECANIM_POSITION;
		}
		MeshRenderer component = _skeletonMecanim.GetComponent<MeshRenderer>();
		component.sortingOrder = character.GetSpineSortingOrder(IsBack);
		_animator = transform2.GetComponentInChildren<Animator>();
		_animator.speed = 1f;
		SetMaterialInfo(component, character.GetStencil());
		_spineEvolveScale = new Vector3(SPINE_DEFAULT_SCALE.x * Mathf.Abs(_animationTransform.localScale.x), SPINE_DEFAULT_SCALE.y * Mathf.Abs(_animationTransform.localScale.y) * 1.1207f, SPINE_DEFAULT_SCALE.z * Mathf.Abs(_animationTransform.localScale.z)) * 1.3f;
	}

	public void LoadAndSet(string skinId, ClassCharacterBase character, Transform wrapObject, bool isBack = false)
	{
		IsBack = isBack;
		_character = character;
		IsNoEvolveShift = _character.IsNoEvolveShift();
		IsOpponentReverse = _character.IsOpponentReverse();
		_maskSprite = new GameObject().AddComponent<SpriteRenderer>();
		_maskSprite.sprite = Toolbox.ResourcesManager.LoadObject<Sprite>(Toolbox.ResourcesManager.GetAssetTypePath(MaskTextureName(skinId), ResourcesManager.AssetLoadPathType.ClassCharaTexture, isfetch: true));
		_maskMaterial = Object.Instantiate(Toolbox.ResourcesManager.LoadObject<Material>(Toolbox.ResourcesManager.GetAssetTypePath("mt_encampment_mask", ResourcesManager.AssetLoadPathType.ClassCharaMaterial, isfetch: true)));
		_maskMaterial.SetInt("_Stencil", character.GetStencil());
		_maskSprite.material = _maskMaterial;
		_maskSprite.transform.parent = wrapObject;
		_maskSprite.transform.localPosition = character.GetMaskImagePosition();
		_maskSprite.transform.localScale = Vector3.one * 0.46f;
		_maskSprite.gameObject.layer = 15;
		_maskSprite.sortingOrder = character.GetMaskSortingOrder(IsBack);
		_maskSprite.name = "SpineMask";
		_maskSprite.transform.localRotation = character.GetMaskImageRotation();
		_maskOutSprite = new GameObject().AddComponent<SpriteRenderer>();
		_maskOutSprite.sprite = Toolbox.ResourcesManager.LoadObject<Sprite>(Toolbox.ResourcesManager.GetAssetTypePath("tx_encampment_mask_out", ResourcesManager.AssetLoadPathType.ClassCharaTexture, isfetch: true));
		_maskOutSprite.material = _maskMaterial;
		_maskOutSprite.transform.parent = wrapObject;
		_maskOutSprite.transform.localPosition = character.GetMaskImagePosition();
		_maskOutSprite.transform.localScale = new Vector3(30f, 30f, 1f);
		_maskOutSprite.gameObject.layer = 10;
		_maskOutSprite.sortingOrder = character.GetMaskSortingOrder(IsBack);
		_maskOutSprite.name = "SpineMaskOut";
		_maskOutSprite.gameObject.SetActive(value: false);
		_spineObject = null;
		GameObject gameObject = Toolbox.ResourcesManager.LoadObject<GameObject>(Toolbox.ResourcesManager.GetAssetTypePath(skinId, ResourcesManager.AssetLoadPathType.ClassCharaSpine, isfetch: true));
		if (!(gameObject != null))
		{
			return;
		}
		if (character is HighRankSpineClassCharacter)
		{
			GameObject gameObject2 = null;
			foreach (Transform item in gameObject.transform)
			{
				if (item.gameObject.name == (IsBack ? "back" : "front"))
				{
					gameObject2 = item.gameObject;
					break;
				}
			}
			if (!(gameObject2 != null))
			{
				return;
			}
			gameObject = gameObject2;
		}
		_spineObject = Object.Instantiate(gameObject);
		_animationTransform = _spineObject.transform.Find(ANIMATION_TRANSFORM_NAME);
		MotionUtils.SetLayerAll(_spineObject, 15);
		Transform transform2 = _spineObject.transform;
		transform2.parent = wrapObject;
		transform2.localPosition = character.GetSpinePosition();
		transform2.localScale = character.ConvertSpineScale(transform2.localScale);
		transform2.localEulerAngles = GetDefaultRotate();
		_skeletonMecanim = transform2.GetComponentInChildren<SkeletonMecanim>();
		if (IsOpponentReverse)
		{
			_skeletonMecanim.transform.localPosition = OPPONENT_MECANIM_POSITION;
		}
		MeshRenderer component = _skeletonMecanim.GetComponent<MeshRenderer>();
		component.sortingOrder = character.GetSpineSortingOrder(IsBack);
		_animator = transform2.GetComponentInChildren<Animator>();
		_animator.speed = 1f;
		SetMaterialInfo(component, character.GetStencil());
		_spineEvolveScale = new Vector3(SPINE_DEFAULT_SCALE.x * Mathf.Abs(_animationTransform.localScale.x), SPINE_DEFAULT_SCALE.y * Mathf.Abs(_animationTransform.localScale.y) * 1.1207f, SPINE_DEFAULT_SCALE.z * Mathf.Abs(_animationTransform.localScale.z)) * 1.3f;
	}

	private Vector3 GetDefaultRotate()
	{
		if (!IsOpponentReverse)
		{
			return BILLBOARD_ROTATE;
		}
		return BILLBOARD_ROTATE_REVERSE_VERTICAL;
	}

	public void Clear()
	{
		if (_spineObject != null)
		{
			Object.Destroy(_spineObject);
		}
		_spineObject = null;
		_skeletonMecanim = null;
		_animator = null;
		_spineMaterial = null;
		_maskMaterial = null;
	}

	public void WaitChangeFace(string faceStr)
	{
		if (_skeletonMecanim != null)
		{
			_ = _skeletonMecanim.skeleton;
			if (_skeletonMecanim.skeleton.Data.Skins.Any((Skin a) => a.Name == faceStr))
			{
				_skeletonMecanim.skeleton.SetSkin(faceStr);
			}
		}
	}

	public void OutFrame(bool isHighRank)
	{
		if (_maskOutSprite == null)
		{
			return;
		}
		_maskOutSprite.gameObject.SetActive(value: true);
		if (!(_spineObject != null))
		{
			return;
		}
		if (isHighRank)
		{
			_maskOutSprite.gameObject.layer = 13;
			_spineObject.layer = 13;
			_skeletonMecanim.gameObject.layer = 13;
			if (_character is PlayerHighRankSpineClassCharacter)
			{
				iTween.RotateTo(_spineObject, iTween.Hash("rotation", BILLBOARD_ROTATE_EVOLVE, "time", 0.3f, "islocal", true, "easetype", iTween.EaseType.easeOutExpo));
				iTween.ScaleTo(_spineObject, iTween.Hash("scale", SPINE_EVOLVE_SCALE, "time", 0.3f, "easetype", iTween.EaseType.easeOutExpo));
			}
			return;
		}
		if (_skeletonMecanim != null)
		{
			_spineObject.layer = 10;
			_skeletonMecanim.gameObject.layer = 10;
			_skeletonMecanim.gameObject.GetComponent<MeshRenderer>().sortingOrder = 1000;
			_maskOutSprite.sortingOrder = 1000;
		}
		if (IsNoEvolveShift)
		{
			_maskOutSprite.gameObject.layer = 13;
			_spineObject.layer = 13;
			_skeletonMecanim.gameObject.layer = 13;
			return;
		}
		iTween.MoveTo(_spineObject, iTween.Hash("position", OUT_OF_FRAME_POSITION + _animationTransform.localPosition, "time", 0.3f, "islocal", true, "easetype", iTween.EaseType.easeOutExpo));
		iTween.ScaleTo(_spineObject, iTween.Hash("scale", _spineEvolveScale, "time", 0.3f, "easetype", iTween.EaseType.easeOutExpo));
		iTween.RotateTo(_spineObject, iTween.Hash("rotation", SPINE_EVOLVE_ROTATION, "time", 0.3f, "islocal", true, "easetype", iTween.EaseType.easeOutExpo));
	}

	public void SetAnimationEnable(bool isAnimation, bool previous, bool isEvolveSkin = false, bool isEvolved = false)
	{
		if (_animator == null)
		{
			return;
		}
		if (isEvolveSkin)
		{
			if (previous != isAnimation)
			{
				_animator.Play(((!isEvolved) ? ClassCharaPrm.MotionType.idle : ClassCharaPrm.MotionType.z_idle).ToString(), 0, 0f);
			}
			_animator.speed = (isAnimation ? 1 : 0);
			return;
		}
		_animator.gameObject.SetActive(value: false);
		_animator.gameObject.SetActive(value: true);
		if (isAnimation)
		{
			_animator.enabled = true;
			return;
		}
		_animator.enabled = false;
		string faceStr = ClassCharaPrm.FaceType.skin_01.ToString();
		if (_skeletonMecanim.skeleton.Data.Skins.Any((Skin a) => a.Name == faceStr))
		{
			_skeletonMecanim.skeleton.SetSkin(faceStr);
		}
		_skeletonMecanim.skeleton.Update(Time.deltaTime);
	}

	public IEnumerator WaitReturnFrame(Vector3 position, bool isHighRank)
	{
		if (_spineObject != null && !IsNoEvolveShift)
		{
			if (!isHighRank)
			{
				iTween.MoveTo(_spineObject, iTween.Hash("position", position, "time", 0.3f, "islocal", true, "easetype", iTween.EaseType.easeInExpo));
			}
			iTween.ScaleTo(_spineObject, iTween.Hash("scale", SPINE_DEFAULT_SCALE, "time", isHighRank ? 0.24f : 0.3f, "easetype", iTween.EaseType.easeInExpo));
			iTween.RotateTo(_spineObject, iTween.Hash("rotation", GetDefaultRotate(), "time", isHighRank ? 0.24f : 0.3f, "islocal", true, "easetype", iTween.EaseType.easeInExpo));
		}
		yield return new WaitForSeconds(isHighRank ? 0.3f : 0.33f);
		if (!IsNoEvolveShift)
		{
			SetDefaultLayer(isHighRank);
		}
	}

	public void SetDefaultLayer(bool isHighRank)
	{
		if (_spineObject != null)
		{
			if (isHighRank || IsNoEvolveShift)
			{
				_maskOutSprite.gameObject.layer = 10;
			}
			_spineObject.layer = 15;
			_skeletonMecanim.gameObject.layer = 15;
		}
		if (_skeletonMecanim != null)
		{
			_skeletonMecanim.gameObject.GetComponent<MeshRenderer>().sortingOrder = _character.GetSpineSortingOrder(IsBack);
			_maskOutSprite.sortingOrder = _character.GetMaskSortingOrder(IsBack);
			_maskSprite.sortingOrder = _character.GetMaskSortingOrder(IsBack);
		}
		if (_maskOutSprite != null)
		{
			_maskOutSprite.gameObject.SetActive(value: false);
		}
	}
}
