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

namespace Wizard;

public class UISpriteAtlasOverwriter : MonoBehaviour
{
	private class SpriteAtlasPair
	{
		public UISprite Sprite { get; }

		public UIAtlas Atlas { get; }

		public SpriteAtlasPair(UISprite sprite)
		{
			Sprite = sprite;
			Atlas = sprite.atlas;
		}
	}

	public class TargetObject
	{
		private readonly GameObject _rootObject;

		private readonly bool _includeChildren;

		public UISprite[] Sprites
		{
			get
			{
				if (!_includeChildren)
				{
					return new UISprite[1] { _rootObject.GetComponent<UISprite>() };
				}
				return _rootObject.GetComponentsInChildren<UISprite>(includeInactive: true);
			}
		}

		public bool IsRootObjectDestoryed => _rootObject == null;

		public TargetObject(GameObject rootObject, bool includeChildren)
		{
			_rootObject = rootObject;
			_includeChildren = includeChildren;
		}
	}

	private UIAtlas _atlas;

	private TargetObject[] _targetObjects;

	private List<TargetObject> _exceptionObjects;

	private readonly List<SpriteAtlasPair> _originalSpriteAtlasPairs = new List<SpriteAtlasPair>();

	private void OnDisable()
	{
		UndoParameters();
	}

	private void LateUpdate()
	{
		OverwriteAtlas();
	}

	public void Init(UIAtlas atlas, TargetObject[] targetObjects)
	{
		UndoParameters();
		_atlas = atlas;
		_targetObjects = targetObjects;
	}

	public void AddExceptionObjects(List<TargetObject> exceptionObjects)
	{
		if (_exceptionObjects == null)
		{
			_exceptionObjects = new List<TargetObject>();
		}
		_exceptionObjects.AddRange(exceptionObjects);
	}

	private void UndoParameters()
	{
		foreach (SpriteAtlasPair originalSpriteAtlasPair in _originalSpriteAtlasPairs)
		{
			if (originalSpriteAtlasPair.Sprite != null)
			{
				originalSpriteAtlasPair.Sprite.atlas = originalSpriteAtlasPair.Atlas;
			}
		}
		_originalSpriteAtlasPairs.Clear();
	}

	private void OverwriteAtlas()
	{
		if (!(_atlas == null) && _targetObjects != null)
		{
			TargetObject[] targetObjects = _targetObjects;
			foreach (TargetObject targetObject in targetObjects)
			{
				OverwriteAtlas(targetObject);
			}
		}
	}

	private void OverwriteAtlas(TargetObject targetObject)
	{
		UISprite[] sprites = targetObject.Sprites;
		foreach (UISprite uISprite in sprites)
		{
			if (!IsExceptionSprite(uISprite))
			{
				OverwriteAtlas(uISprite);
			}
		}
	}

	private bool IsExceptionSprite(UISprite sprite)
	{
		if (_exceptionObjects == null)
		{
			return false;
		}
		if (_exceptionObjects.Count() == 0)
		{
			_exceptionObjects = null;
			return false;
		}
		try
		{
			TargetObject[] array = _exceptionObjects.ToArray();
			foreach (TargetObject targetObject in array)
			{
				if (targetObject.IsRootObjectDestoryed)
				{
					_exceptionObjects.Remove(targetObject);
					continue;
				}
				UISprite[] sprites = targetObject.Sprites;
				for (int j = 0; j < sprites.Length; j++)
				{
					if (sprites[j] == sprite)
					{
						return true;
					}
				}
			}
		}
		catch
		{
			return false;
		}
		return false;
	}

	private void OverwriteAtlas(UISprite targetSprite)
	{
		if (!(targetSprite.atlas == _atlas) && _atlas.spriteList.Any((UISpriteData s) => s.name == targetSprite.spriteName))
		{
			_originalSpriteAtlasPairs.Add(new SpriteAtlasPair(targetSprite));
			targetSprite.atlas = _atlas;
			targetSprite.CreatePanel();
		}
	}
}
