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

namespace Wizard;

public class ChatLogUI : MonoBehaviour
{
	public class PartsForPlate
	{
		public ChatDeckView DeckView { get; private set; }

		public PartsForPlate(ChatDeckView chatDeckView)
		{
			DeckView = chatDeckView;
		}
	}

	public const int INVALID_UNREAD_MESSAGE_ID = -1;

	public const int SCROLL_OBJECT_NUM = 10;

	private const int SCROLL_OBJECT_MARGIN = 10;

	[SerializeField]
	private UIButton _buttonToNewMessage;

	[SerializeField]
	private UIScrollView _scrollView;

	[SerializeField]
	private UIWrapVariableContentVertical _wrapVariableContent;

	[SerializeField]
	private UIScrollBarWrapContent _scrollBarWrapContent;

	[SerializeField]
	private WrapVariableContentsScrollBarSize _wrapContentScrollBarSize;

	private UIPanel _panelScrollView;

	private float _startBaseClipRegionY;

	private float _startBaseClipRegionW;

	private ChatLogPlate _logPlateOriginal;

	private ChatLogPlate _logPlateForSizeCalcDummyObject;

	private List<ChatLogPlate> _plateList = new List<ChatLogPlate>();

	private List<string> _loadedResourceList = new List<string>();

	[SerializeField]
	private ChatDeckView _chatDeckView;

	private bool _isCreateFinish;

	private Action _onInitializeOldestLog;

	private int _unreadMessageId;

	private int _oldUnreadMessageId = -1;

	private List<ChatOpenCloseAnimation> _dependOpenCloseAnimationList = new List<ChatOpenCloseAnimation>();

	private float _scrollViewBasePosY;

	private bool _isFollowingAnimation;

	private Coroutine _bottomScrollViewAnimationCoroutin;

	private float _bottomScrollViewAnimationDistance;

	private IChatSettings _chatSettings;

	private ChatConnectController _chatConnectController;

	private List<int> _stampList;

	private PartsForPlate _partsForPlate;

	public bool IsEnableUpdateUI { get; private set; }

	public List<ChatMessageInfo> ChatVisibleLogList { get; private set; } = new List<ChatMessageInfo>();

	public List<ChatMessageInfo> ChatAllLogList { get; private set; } = new List<ChatMessageInfo>();

	public void Init(IChatSettings chatSettings, ChatConnectController chatConnectController, List<int> stampList)
	{
		_chatSettings = chatSettings;
		_chatConnectController = chatConnectController;
		_stampList = stampList;
		_logPlateOriginal = chatSettings.PrefabChatLogPlate;
		_chatDeckView.Init(chatSettings.ApiSettings, chatConnectController, CloseChatLogContent);
		_partsForPlate = new PartsForPlate(_chatDeckView);
	}

	public void ShowDeckViewByDeckLog(ChatMessageInfo.DeckLogData deckLogData, Action onOpen = null, Action onClose = null, Action<Format, Dictionary<Format, List<ChatMessageInfo.DeckLogData>>> onDeleteDeckSuccess = null)
	{
		_chatDeckView.ShowDeckViewByDeckLog(deckLogData, onOpen, onClose, onDeleteDeckSuccess);
	}

	public void ShowDeckViewByDeckData(DeckData deck, Action onOpen, Action onClose, bool isActiveRedButton, bool isActiveDeckIntroductionObj)
	{
		_chatDeckView.ShowDeckViewByDeckData(deck, onOpen, onClose, isActiveRedButton, isActiveDeckIntroductionObj);
	}

	public void CloseDeckView()
	{
		_chatDeckView.CloseDeckView();
	}

	public bool IsShowDeckView()
	{
		return _chatDeckView.IsShowDeckCardView();
	}

	public void CreateChatLogView(List<ChatMessageInfo> messageList, Action onInitializeOldestLog, Action onFinCallBack, int unreadMessageId = -1)
	{
		_onInitializeOldestLog = onInitializeOldestLog;
		_panelScrollView = _scrollView.GetComponent<UIPanel>();
		Vector4 baseClipRegion = _panelScrollView.baseClipRegion;
		_startBaseClipRegionY = baseClipRegion.y;
		_startBaseClipRegionW = baseClipRegion.w;
		_buttonToNewMessage.onClick.Clear();
		_buttonToNewMessage.onClick.Add(new EventDelegate(delegate
		{
			MoveNewMessagePosition();
		}));
		_buttonToNewMessage.gameObject.SetActive(value: false);
		_unreadMessageId = unreadMessageId;
		AddChatLogInfo(messageList, Chat.eRequestDirection.OLD);
		List<string> chatLogAssetPathList = GetChatLogAssetPathList(ChatVisibleLogList);
		for (int num = 0; num < _stampList.Count; num++)
		{
			string assetTypePath = Toolbox.ResourcesManager.GetAssetTypePath(_stampList[num].ToString(), ResourcesManager.AssetLoadPathType.Stamp);
			chatLogAssetPathList.Add(assetTypePath);
		}
		LoadResources(chatLogAssetPathList, delegate
		{
			CreateScrollView(ChatVisibleLogList);
			ResetScrollDefaultPosition(unreadMessageId);
			onFinCallBack.Call();
			_isCreateFinish = true;
		});
	}

	public void CloseChatLogView()
	{
		UnloadResources();
	}

	public void ResetScrollDefaultPosition(int unreadMessageId = -1)
	{
		int centerIndex = Mathf.Max(ChatVisibleLogList.Count - 1, 0);
		if (unreadMessageId != -1)
		{
			int num = ChatVisibleLogList.FindIndex((ChatMessageInfo log) => log.MessageId == unreadMessageId);
			if (num >= 0)
			{
				centerIndex = num;
			}
		}
		_wrapVariableContent.ResetScrollPositionByIndex(centerIndex);
	}

	public void SetEnableUpdateUI()
	{
		if (IsEnableUpdateUI)
		{
			return;
		}
		IsEnableUpdateUI = true;
		if (_oldUnreadMessageId != -1)
		{
			UpdateChatLogSizeByIndex(ChatVisibleLogList.FindIndex((ChatMessageInfo info) => info.MessageId == _oldUnreadMessageId));
			_oldUnreadMessageId = -1;
		}
		_wrapContentScrollBarSize.ContentUpdate();
		_wrapVariableContent.WrapContent();
	}

	public void AddChatLogView(ChatInfo chatInfo, Chat.eRequestDirection eDirection, bool in_enableUpdateUI = true, Action onFinCallBack = null)
	{
		if (chatInfo.MessageList.Count <= 0)
		{
			onFinCallBack.Call();
			return;
		}
		AddChatLogInfo(chatInfo.MessageList, eDirection);
		if (chatInfo.VisibleMessageList.Count <= 0)
		{
			onFinCallBack.Call();
			return;
		}
		if (eDirection == Chat.eRequestDirection.NEW && IsEnableUpdateUI && !in_enableUpdateUI)
		{
			_oldUnreadMessageId = _unreadMessageId;
			_unreadMessageId = chatInfo.VisibleMessageList[0].MessageId;
		}
		IsEnableUpdateUI = in_enableUpdateUI;
		bool flag = _wrapVariableContent.IsBottom();
		List<string> chatLogAssetPathList = GetChatLogAssetPathList(chatInfo.VisibleMessageList);
		LoadResources(chatLogAssetPathList);
		AddScrollPlate(chatInfo.VisibleMessageList, eDirection);
		if (eDirection == Chat.eRequestDirection.NEW && flag && IsEnableUpdateUI)
		{
			MoveNewMessagePosition();
		}
		onFinCallBack.Call();
	}

	public void MoveNewMessagePosition()
	{
		if (_wrapVariableContent.IsScrollEnableSize())
		{
			_wrapVariableContent.ResetScrollPositionBottomEasing();
		}
	}

	public void ChangeLogViewSizeByInputUIAnimation(ChatOpenCloseAnimation sendUIAnimation)
	{
		_scrollBarWrapContent.gameObject.SetActive(value: false);
		_buttonToNewMessage.gameObject.SetActive(value: false);
		if (!_dependOpenCloseAnimationList.Contains(sendUIAnimation))
		{
			_dependOpenCloseAnimationList.Add(sendUIAnimation);
		}
		if (_dependOpenCloseAnimationList.All((ChatOpenCloseAnimation x) => x.IsAnimationStartFromOpenedOrClosed))
		{
			_isFollowingAnimation = IsEnableFollowAnimation();
			float num = (_isFollowingAnimation ? GetDependOpenCloseAnimationHeight() : 0f);
			_scrollViewBasePosY = _scrollView.transform.localPosition.y - num;
			if (_isFollowingAnimation && _bottomScrollViewAnimationCoroutin == null)
			{
				_bottomScrollViewAnimationCoroutin = StartCoroutine(CalcHeightBottomScrollViewAnimation());
			}
		}
	}

	private IEnumerator CalcHeightBottomScrollViewAnimation()
	{
		float distance = _wrapVariableContent.GetDistanceBetweenBottomItemAndScrollBottomPos();
		float durationTime = _dependOpenCloseAnimationList.Max((ChatOpenCloseAnimation x) => x.AnimationTime);
		_bottomScrollViewAnimationDistance = 0f;
		CustomEasing easing = new CustomEasing(CustomEasing.eType.outQuad, 0f, distance, durationTime);
		while (easing.IsMoving)
		{
			_bottomScrollViewAnimationDistance = easing.GetCurVal(Time.deltaTime);
			yield return null;
		}
		_bottomScrollViewAnimationDistance = distance;
		_bottomScrollViewAnimationCoroutin = null;
	}

	private void CloseChatLogContent(int messageId)
	{
		int num = ChatVisibleLogList.FindIndex((ChatMessageInfo log) => log.MessageId == messageId);
		if (num >= 0)
		{
			ChatVisibleLogList[num].CloseContent();
			UpdateChatLogSizeByIndex(num);
		}
	}

	private void UpdateChatLogSizeByIndex(int index)
	{
		if (index >= 0 && ChatVisibleLogList.Count >= index)
		{
			_wrapVariableContent.UpdateItemSize(index, GetHeightPlateSize(ChatVisibleLogList[index]));
			_wrapContentScrollBarSize.ContentUpdate();
		}
	}

	private bool IsEnableFollowAnimation()
	{
		if (!_wrapVariableContent.IsScrollEnableSize())
		{
			return false;
		}
		if (!_wrapVariableContent.IsBottom())
		{
			return false;
		}
		if (_wrapVariableContent.TopOverflowItemSize() < GetDependOpenCloseAnimationHeight())
		{
			return false;
		}
		return true;
	}

	private float GetDependOpenCloseAnimationHeight()
	{
		float num = 0f;
		foreach (ChatOpenCloseAnimation dependOpenCloseAnimation in _dependOpenCloseAnimationList)
		{
			float num2 = num;
			num2 = ((!dependOpenCloseAnimation.IsMoving) ? ((!dependOpenCloseAnimation.IsOpen) ? 0f : dependOpenCloseAnimation.OpenHeight) : dependOpenCloseAnimation.CurrentPosHeight);
			num = Mathf.Max(num, num2);
		}
		return num;
	}

	private void Update()
	{
		UpdateButtonToNewMessage();
	}

	private void UpdateButtonToNewMessage()
	{
		if (IsEnableUpdateUI && _dependOpenCloseAnimationList.Count <= 0)
		{
			_buttonToNewMessage.gameObject.SetActive(!_wrapVariableContent.IsBottom());
		}
	}

	private void LateUpdate()
	{
		if (IsUpdateLogViewSize())
		{
			UpdateLogViewSizeDependAnimation();
		}
	}

	private bool IsUpdateLogViewSize()
	{
		return _dependOpenCloseAnimationList.Any((ChatOpenCloseAnimation x) => x.IsMoving || !x.IsOpen);
	}

	private void UpdateLogViewSizeDependAnimation()
	{
		float dependOpenCloseAnimationHeight = GetDependOpenCloseAnimationHeight();
		Vector4 baseClipRegion = _panelScrollView.baseClipRegion;
		baseClipRegion.y = _startBaseClipRegionY + dependOpenCloseAnimationHeight * 0.5f;
		baseClipRegion.w = _startBaseClipRegionW - dependOpenCloseAnimationHeight;
		_panelScrollView.baseClipRegion = baseClipRegion;
		float num = _scrollViewBasePosY;
		if (_isFollowingAnimation)
		{
			num += dependOpenCloseAnimationHeight + _bottomScrollViewAnimationDistance;
		}
		_wrapVariableContent.MoveScrollPanel(num);
		_dependOpenCloseAnimationList.RemoveAll((ChatOpenCloseAnimation x) => !x.IsMoving && !x.IsOpen);
		_scrollBarWrapContent.gameObject.SetActive(_dependOpenCloseAnimationList.Count == 0 && _wrapVariableContent.IsScrollEnableSize());
	}

	private void AddChatLogInfo(List<ChatMessageInfo> addChatLogList, Chat.eRequestDirection eDirection)
	{
		if (eDirection == Chat.eRequestDirection.OLD)
		{
			for (int num = addChatLogList.Count - 1; num >= 0; num--)
			{
				ChatAllLogList.Insert(0, addChatLogList[num]);
			}
		}
		else
		{
			ChatAllLogList.AddRange(addChatLogList);
		}
		ChatVisibleLogList = ChatAllLogList.Where((ChatMessageInfo log) => log.IsVisibleMessage).ToList();
	}

	private List<string> GetChatLogAssetPathList(List<ChatMessageInfo> logList)
	{
		List<string> list = new List<string>();
		List<string> list2 = new List<string>();
		for (int i = 0; i < logList.Count; i++)
		{
			list.AddRange(logList[i].GetResourcePathList());
		}
		list = list.Distinct().ToList();
		for (int j = 0; j < list.Count; j++)
		{
			string item = list[j];
			if (!_loadedResourceList.Contains(item))
			{
				list2.Add(item);
			}
		}
		return list2;
	}

	private void LoadResources(List<string> resourcePathList, Action callBack = null)
	{
		if (resourcePathList.Count <= 0)
		{
			callBack.Call();
			return;
		}
		UIManager.GetInstance().StartCoroutine(Toolbox.ResourcesManager.LoadAssetGroupAsync(resourcePathList, delegate
		{
			_loadedResourceList.AddRange(resourcePathList);
			callBack.Call();
		}));
	}

	private void CreateScrollView(List<ChatMessageInfo> addChatLogList)
	{
		_wrapVariableContent.gameObject.SetActive(value: false);
		_scrollBarWrapContent.m_WrapContents = _wrapVariableContent;
		_scrollBarWrapContent.gameObject.SetActive(value: true);
		_scrollView.gameObject.SetActive(value: true);
		_wrapVariableContent.Init(10, 0, 0, OnInitializeItem);
		_wrapVariableContent.gameObject.SetActive(value: true);
		if (ChatVisibleLogList.Count > 0)
		{
			AddScrollPlate(addChatLogList, Chat.eRequestDirection.OLD);
		}
	}

	private void AddScrollPlate(List<ChatMessageInfo> addChatLogList, Chat.eRequestDirection eDirection)
	{
		List<int> list = new List<int>();
		foreach (ChatMessageInfo addChatLog in addChatLogList)
		{
			int heightPlateSize = GetHeightPlateSize(addChatLog);
			if (heightPlateSize > 0)
			{
				list.Add(heightPlateSize);
			}
		}
		_wrapVariableContent.AddItemList(list, eDirection == Chat.eRequestDirection.NEW);
		if (_plateList.Count < 10)
		{
			_wrapVariableContent.enabled = true;
			for (int i = _plateList.Count; i < ChatVisibleLogList.Count && i < 10; i++)
			{
				ChatLogPlate item = CreateLogPlate(_wrapVariableContent.gameObject);
				_plateList.Add(item);
			}
			for (int j = 0; j < _plateList.Count; j++)
			{
				_plateList[j].gameObject.SetActive(value: true);
			}
			_wrapVariableContent.SortBasedOnScrollMovement();
			if (!_wrapVariableContent.IsScrollEnableSize())
			{
				_scrollView.ResetPosition();
			}
		}
		if (IsEnableUpdateUI)
		{
			_wrapContentScrollBarSize.ContentUpdate();
			_wrapVariableContent.WrapContent();
		}
	}

	private int GetHeightPlateSize(ChatMessageInfo logInfo)
	{
		if (_logPlateForSizeCalcDummyObject == null)
		{
			_logPlateForSizeCalcDummyObject = CreateLogPlate(base.gameObject);
			_logPlateForSizeCalcDummyObject.gameObject.SetActive(value: false);
		}
		return _logPlateForSizeCalcDummyObject.GetHeightSize(logInfo, logInfo.MessageId == _unreadMessageId) + 10;
	}

	private ChatLogPlate CreateLogPlate(GameObject rootObj)
	{
		ChatLogPlate component = NGUITools.AddChild(rootObj, _logPlateOriginal.gameObject).GetComponent<ChatLogPlate>();
		component.Init(_chatSettings, _chatConnectController, _partsForPlate, IsLoadedResources);
		return component;
	}

	private void OnInitializeItem(GameObject go, int wrapIndex, int realIndex)
	{
		int num = -realIndex;
		if (num >= ChatVisibleLogList.Count || num < 0)
		{
			go.SetActive(value: false);
			return;
		}
		go.SetActive(value: true);
		ChatMessageInfo chatMessageInfo = ChatVisibleLogList[num];
		go.GetComponent<ChatLogPlate>().SetData(chatMessageInfo, chatMessageInfo.MessageId == _unreadMessageId);
		if (num == 0 && _isCreateFinish)
		{
			_onInitializeOldestLog.Call();
		}
	}

	private void OnDestroy()
	{
		UnloadResources();
	}

	private bool IsLoadedResources(List<string> checkResourceList)
	{
		for (int i = 0; i < checkResourceList.Count; i++)
		{
			if (!_loadedResourceList.Contains(checkResourceList[i]))
			{
				return false;
			}
		}
		return true;
	}

	private void UnloadResources()
	{
		if (_loadedResourceList != null)
		{
			Toolbox.ResourcesManager.RemoveAssetGroup(_loadedResourceList);
			_loadedResourceList.Clear();
		}
	}
}
