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

namespace Wizard;

public class TournamentController : MonoBehaviour
{
	[SerializeField]
	private GameObject _tournamentRoot;

	[SerializeField]
	private Transform _roundsRoot;

	[SerializeField]
	private GameObject _originalRound;

	[SerializeField]
	private UIDragMultiScrollView _dragMultiScrollView;

	[SerializeField]
	private UIButton _prevButton;

	[SerializeField]
	private UIButton _nextButton;

	[SerializeField]
	private UIPanel _panel;

	[SerializeField]
	private UISprite _leftCurtainSprite;

	[SerializeField]
	private UISprite _rightCurtainSprite;

	[SerializeField]
	private Transform _scrollBarRoot;

	[SerializeField]
	private GameObject _originalScrollBarObj;

	[SerializeField]
	private UIGrid _radioIconGrid;

	[SerializeField]
	private GameObject _originalRadioIconObj;

	private List<TournamentRound> _rounds;

	private bool _isChangeableSelectRound = true;

	private int _selectRoundIndex;

	private (float, float)[][] _cellPosBank;

	private SpringPanelWithUpdate _currentSpring;

	private List<UISprite> _radioIcons;

	private const float ROUND_OFFSET_X = -16f;

	private const float ROUND_WIDTH = 240f;

	private const float PARENT_CELL_INTERVAL = 200f;

	private const float CHANGE_SELECT_ROUND_DRAG_THRESHOLD_X = 45.5f;

	private const float CHANGE_SELECT_ROUND_DRAG_NG_THRESHOLD_Y = 16.25f;

	private const float CHANGE_SELECT_ROUND_DURATION = 0.15f;

	private const float CURTAIN_ALPHA_MAX = 0.5f;

	private void Start()
	{
		_originalRound.SetActive(value: false);
		UIEventListener uIEventListener = UIEventListener.Get(_dragMultiScrollView.gameObject);
		uIEventListener.onDrag = (UIEventListener.VectorDelegate)Delegate.Combine(uIEventListener.onDrag, new UIEventListener.VectorDelegate(OnDrag));
		_prevButton.onClick.Add(new EventDelegate(ChangeSelectRoundToPrevious));
		_nextButton.onClick.Add(new EventDelegate(ChangeSelectRoundToNext));
	}

	public IEnumerator Setup(TournamentData data, TournamentCellData currentCell, GatheringInfo info, bool isVisible)
	{
		int count = data.Rounds.Count;
		_rounds = new List<TournamentRound>(count);
		_radioIcons = new List<UISprite>(count);
		_originalRound.SetActive(value: true);
		_originalRadioIconObj.SetActive(value: true);
		_originalScrollBarObj.SetActive(value: true);
		Vector3 localPosition = _originalScrollBarObj.transform.localPosition;
		int currentRound = 0;
		for (int i = 0; i < count; i++)
		{
			TournamentRoundData tournamentRoundData = data.Rounds[i];
			TournamentRound component = NGUITools.AddChild(_roundsRoot.gameObject, _originalRound).GetComponent<TournamentRound>();
			UIScrollBar component2 = NGUITools.AddChild(_scrollBarRoot.gameObject, _originalScrollBarObj).GetComponent<UIScrollBar>();
			component2.transform.localPosition = localPosition;
			component.ScrollView.verticalScrollBar = component2;
			component.ScrollBarPanel = component2.GetComponent<UIPanel>();
			component.ScrollBarCollider = component2.backgroundWidget.GetComponent<BoxCollider>();
			component.Setup(tournamentRoundData, info);
			component.transform.localPosition = new Vector3(240f * (float)i, 0f, 0f);
			_dragMultiScrollView.AddScrollView(component.ScrollView);
			_rounds.Add(component);
			_radioIcons.Add(NGUITools.AddChild(_radioIconGrid.gameObject, _originalRadioIconObj).GetComponent<UISprite>());
			if (currentCell != null && tournamentRoundData.Cells.Contains(currentCell))
			{
				currentRound = i;
			}
		}
		_originalRound.SetActive(value: false);
		_originalRadioIconObj.SetActive(value: false);
		_originalScrollBarObj.SetActive(value: false);
		_radioIconGrid.Reposition();
		_cellPosBank = new(float, float)[_rounds.Count][];
		for (int j = 0; j < _cellPosBank.Length; j++)
		{
			(float, float)[] array = new(float, float)[_rounds[j].Cells.Count];
			for (int k = 0; k < array.Length; k++)
			{
				array[k] = (0f, 0f);
			}
			_cellPosBank[j] = array;
		}
		_dragMultiScrollView.OnPressCallback = OnPressScrollView;
		_dragMultiScrollView.OnScrollCallback = OnScrollWheel;
		if (count > 0)
		{
			_rounds[0].ScrollView.onMomentumMove = OnMomentumMove;
		}
		_panel.alpha = 0f;
		yield return null;
		AppendScrollBarEvent();
		foreach (TournamentRound round in _rounds)
		{
			round.SetCellEnable(isEnabled: true);
		}
		SetupCellLineEnd();
		PropagateScrollValue(currentRound);
		ChangeSelectRoundIndex(currentRound, isImmediate: true, isPlaySe: false);
		ChangeFocusCellImmediate(currentCell);
		RestrictWithinBounds(isImmediate: true);
		SetVisible(isVisible);
		if (isVisible && currentCell != null && currentCell.ViewerId == PlayerStaticData.UserViewerID)
		{
			TournamentCell tournamentCell = GetTournamentCell(currentCell);
			if (tournamentCell != null)
			{
				tournamentCell.SetYouMarkVisible(isVisible: true);
			}
		}
		yield return null;
		_panel.alpha = 1f;
	}

	private void OnDrag(GameObject obj, Vector2 delta)
	{
		if (!(delta.y > 16.25f) && !(delta.y < -16.25f))
		{
			if (delta.x > 45.5f)
			{
				ChangeSelectRoundToPrevious();
			}
			else if (delta.x < -45.5f)
			{
				ChangeSelectRoundToNext();
			}
		}
	}

	private void ChangeSelectRoundToPrevious()
	{
		if (_isChangeableSelectRound && _selectRoundIndex > 0)
		{
			ChangeSelectRoundIndex(_selectRoundIndex - 1);
		}
	}

	private void ChangeSelectRoundToNext()
	{
		if (_isChangeableSelectRound && _selectRoundIndex < _rounds.Count - 1)
		{
			ChangeSelectRoundIndex(_selectRoundIndex + 1);
		}
	}

	private void ChangeSelectRoundIndex(int index, bool isImmediate = false, bool isPlaySe = true)
	{
		if (!_isChangeableSelectRound)
		{
			return;
		}
		SetupCellPosition(index);
		Vector3 vector = new Vector3((float)(-index) * 240f + -16f, 0f, 0f);
		if (isImmediate)
		{
			_roundsRoot.localPosition = vector;
			ApplyCellPosition(1f);
			UpdateCellLine();
			UpdateWatchPosition();
			UpdateRoundAlpha(_selectRoundIndex, index, 1f);
			UpdateCurtainAlpha(_selectRoundIndex, index, 1f);
			UpdateScrollViewBounds();
			_panel.SetDirty();
		}
		else
		{
			_isChangeableSelectRound = false;
			AdjustCellPositionToFocusCell(index);
			UpdateRoundWatchEnable(-1);
			int beforeIndex = _selectRoundIndex;
			TweenPosition tweenPosition = TweenPositionWithUpdate.Begin(_roundsRoot.gameObject, 0.15f, vector, delegate(float factor)
			{
				ApplyCellPosition(factor);
				UpdateCellLine();
				UpdateWatchPosition();
				UpdateRoundAlpha(beforeIndex, index, factor);
				UpdateCurtainAlpha(beforeIndex, index, factor);
				UpdateScrollViewBounds();
				RestrictWithinBounds(isImmediate: true);
				_panel.SetDirty();
			});
			tweenPosition.method = UITweener.Method.EaseOut;
			tweenPosition.onFinished.Add(new EventDelegate(delegate
			{
				_isChangeableSelectRound = true;
				RestrictWithinBounds(isImmediate: false);
			}));
		}
		_selectRoundIndex = index;
		UpdateRoundWatchEnable(index);
		ChangeScrollBarController();
		UpdateRadioIcon();
		UpdateArrowButton();
		if (isPlaySe)
		{
			GameMgr.GetIns().GetSoundMgr().PlaySe(Se.TYPE.SYS_SLIDE_BTN);
		}
	}

	private void ChangeFocusCellImmediate(TournamentCellData focusCell)
	{
		if (focusCell != null)
		{
			TournamentRound tournamentRound = _rounds[_selectRoundIndex];
			TournamentCell tournamentCell = tournamentRound.Cells.FirstOrDefault((TournamentCell c) => c != null && c.Data == focusCell);
			if (!(tournamentCell == null))
			{
				Transform transform = tournamentRound.ScrollView.panel.transform;
				Vector3 relative = -transform.transform.InverseTransformPoint(tournamentCell.transform.position);
				relative.x = transform.localPosition.x;
				tournamentRound.ScrollView.MoveRelative(relative);
				PropagateScrollValue(_selectRoundIndex);
			}
		}
	}

	private void UpdateRadioIcon()
	{
		int i = 0;
		for (int count = _radioIcons.Count; i < count; i++)
		{
			_radioIcons[i].spriteName = ((i == _selectRoundIndex) ? "carousel_marker_on" : "carousel_marker_off");
		}
	}

	private void UpdateArrowButton()
	{
		_prevButton.gameObject.SetActive(_selectRoundIndex > 0);
		_nextButton.gameObject.SetActive(_selectRoundIndex < _rounds.Count - 1);
	}

	private void SetupCellPosition(int selectRoundIndex)
	{
		for (int i = 0; i < _rounds.Count; i++)
		{
			TournamentRound tournamentRound = _rounds[i];
			for (int j = 0; j < tournamentRound.Cells.Count; j++)
			{
				_cellPosBank[i][j].Item1 = tournamentRound.Cells[j].transform.localPosition.y;
			}
		}
		int num = 0;
		float num2 = 200f;
		for (int num3 = selectRoundIndex + 1; num3 >= selectRoundIndex - 1; num3--)
		{
			if (num3 < _rounds.Count && num3 >= 0)
			{
				num = num3;
				TournamentRound tournamentRound2 = _rounds[num3];
				for (int k = 0; k < tournamentRound2.Cells.Count; k++)
				{
					_cellPosBank[num3][k].Item2 = -200f * (float)k;
				}
				break;
			}
		}
		float num4 = num2 * 0.5f;
		for (int num5 = num - 1; num5 >= 0; num5--)
		{
			TournamentRound tournamentRound3 = _rounds[num5];
			TournamentRound tournamentRound4 = _rounds[num5 + 1];
			if (tournamentRound4.Data.IsExtraRound)
			{
				for (int l = 0; l < tournamentRound3.Cells.Count; l++)
				{
					_cellPosBank[num5][l].Item2 = _cellPosBank[num5 + 1][l].Item2;
				}
			}
			else
			{
				num2 *= 0.5f;
				num4 = num2 * 0.5f;
				for (int m = 0; m < tournamentRound3.Cells.Count; m++)
				{
					TournamentCell childCell = tournamentRound3.Cells[m];
					int childIndex;
					int parentCellIndex = GetParentCellIndex(childCell, tournamentRound4, out childIndex);
					float item = _cellPosBank[num5 + 1][parentCellIndex].Item2;
					_cellPosBank[num5][m].Item2 = item + num4 - num2 * (float)childIndex;
				}
			}
		}
		for (int n = num + 1; n < _rounds.Count; n++)
		{
			TournamentRound tournamentRound5 = _rounds[n];
			TournamentRound childRound = _rounds[n - 1];
			if (tournamentRound5.Data.IsExtraRound)
			{
				for (int num6 = 0; num6 < tournamentRound5.Cells.Count; num6++)
				{
					_cellPosBank[n][num6].Item2 = _cellPosBank[n - 1][num6].Item2;
				}
				continue;
			}
			float num7 = 0f;
			for (int num8 = 0; num8 < tournamentRound5.Cells.Count; num8++)
			{
				TournamentCell parentCell = tournamentRound5.Cells[num8];
				int childCellIndex = GetChildCellIndex(parentCell, childRound);
				if (childCellIndex >= 0)
				{
					num7 = (_cellPosBank[n][num8].Item2 = (_cellPosBank[n - 1][childCellIndex].Item2 + _cellPosBank[n - 1][childCellIndex + 1].Item2) * 0.5f);
				}
				else
				{
					_cellPosBank[n][num8].Item2 = num7 - 200f;
				}
			}
		}
	}

	private int GetParentCellIndex(TournamentCell childCell, TournamentRound parentRound, out int childIndex)
	{
		TournamentCellData data = childCell.Data;
		List<TournamentCell> cells = parentRound.Cells;
		for (int i = 0; i < cells.Count; i++)
		{
			TournamentCellData data2 = cells[i].Data;
			if (data2.Children == null)
			{
				continue;
			}
			for (int j = 0; j < data2.Children.Length; j++)
			{
				if (data2.Children[j] == data)
				{
					childIndex = j;
					return i;
				}
			}
		}
		childIndex = -1;
		return -1;
	}

	private int GetChildCellIndex(TournamentCell parentCell, TournamentRound childRound)
	{
		TournamentCellData data = parentCell.Data;
		List<TournamentCell> cells = childRound.Cells;
		for (int i = 0; i < cells.Count; i++)
		{
			if (cells[i].Data.Parent == data)
			{
				return i;
			}
		}
		return -1;
	}

	private void AdjustCellPositionToFocusCell(int selectRoundIndex)
	{
		int num = selectRoundIndex - _selectRoundIndex;
		if (num < -1 || num > 1 || num == 0)
		{
			return;
		}
		TournamentRound tournamentRound = _rounds[_selectRoundIndex];
		float y = tournamentRound.ScrollView.panel.clipOffset.y;
		int num2 = -1;
		float num3 = float.MaxValue;
		for (int i = 0; i < tournamentRound.Cells.Count; i++)
		{
			float num4 = Mathf.Abs(tournamentRound.Cells[i].transform.localPosition.y - y);
			if (!(num4 > num3))
			{
				num3 = num4;
				num2 = i;
			}
		}
		(float, float) tuple = _cellPosBank[_selectRoundIndex][num2];
		float item = tuple.Item1;
		float item2 = tuple.Item2;
		float num5 = item - item2;
		int j = 0;
		for (int count = _rounds.Count; j < count; j++)
		{
			int k = 0;
			for (int count2 = _rounds[j].Cells.Count; k < count2; k++)
			{
				_cellPosBank[j][k].Item2 += num5;
			}
		}
	}

	private void ApplyCellPosition(float factor)
	{
		int i = 0;
		for (int count = _rounds.Count; i < count; i++)
		{
			TournamentRound tournamentRound = _rounds[i];
			int j = 0;
			for (int count2 = tournamentRound.Cells.Count; j < count2; j++)
			{
				TournamentCell tournamentCell = tournamentRound.Cells[j];
				(float, float) tuple = _cellPosBank[i][j];
				UIUtil.SetLocalPositionY(tournamentCell.transform, Mathf.Lerp(tuple.Item1, tuple.Item2, factor));
			}
		}
	}

	private void UpdateWatchPosition()
	{
		foreach (TournamentRound round in _rounds)
		{
			round.UpdateWatchPosition();
		}
	}

	private void UpdateRoundAlpha(int beforeIndex, int afterIndex, float factor)
	{
		int i = 0;
		for (int count = _rounds.Count; i < count; i++)
		{
			TournamentRound tournamentRound = _rounds[i];
			float a = CalcRoundAlpha(i - beforeIndex);
			float b = CalcRoundAlpha(i - afterIndex);
			tournamentRound.ScrollView.panel.alpha = Mathf.Lerp(a, b, factor);
			a = CalcWatchAlpha(i - beforeIndex);
			b = CalcWatchAlpha(i - afterIndex);
			tournamentRound.SetWatchAlpha(Mathf.Lerp(a, b, factor));
		}
		static float CalcRoundAlpha(int indexDiff)
		{
			return Mathf.Max(0f, Mathf.Min(1f, 2f - (float)Mathf.Abs(indexDiff)));
		}
		static float CalcWatchAlpha(int indexDiff)
		{
			return Mathf.Max(0f, Mathf.Min(1f, 1f - (float)Mathf.Abs(indexDiff)));
		}
	}

	private void UpdateRoundWatchEnable(int selectRoundIndex)
	{
		for (int i = 0; i < _rounds.Count; i++)
		{
			_rounds[i].SetWatchEnable(i == selectRoundIndex);
		}
	}

	private void UpdateCurtainAlpha(int beforeIndex, int afterIndex, float factor)
	{
		float a = ((beforeIndex <= 0) ? 0f : 0.5f);
		float b = ((afterIndex <= 0) ? 0f : 0.5f);
		_leftCurtainSprite.alpha = Mathf.Lerp(a, b, factor);
		int num = _rounds.Count - 1;
		float a2 = ((beforeIndex >= num) ? 0f : 0.5f);
		float b2 = ((afterIndex >= num) ? 0f : 0.5f);
		_rightCurtainSprite.alpha = Mathf.Lerp(a2, b2, factor);
	}

	private void UpdateCellLine()
	{
		int i = 0;
		for (int count = _rounds.Count; i < count; i++)
		{
			List<TournamentCell> cells = _rounds[i].Cells;
			int j = 0;
			for (int count2 = cells.Count; j < count2; j++)
			{
				cells[j].UpdateLine();
			}
		}
	}

	private void SetupCellLineEnd()
	{
		int i = 0;
		for (int num = _rounds.Count - 1; i < num; i++)
		{
			List<TournamentCell> cells = _rounds[i].Cells;
			List<TournamentCell> cells2 = _rounds[i + 1].Cells;
			int j = 0;
			for (int count = cells.Count; j < count; j++)
			{
				TournamentCell cell = cells[j];
				if (cell.Data.IsPreExtra)
				{
					cell.SetLineEndTransform(cells.Find((TournamentCell c) => c != cell).RightConnectorTransform);
					continue;
				}
				TournamentCellData parentCellData = cell.Data.Parent;
				TournamentCell tournamentCell = cells2.Find((TournamentCell c) => c != null && c.Data == parentCellData);
				if (tournamentCell != null)
				{
					cell.SetLineEndTransform(tournamentCell.LeftConnectorTransform);
				}
			}
		}
	}

	private void UpdateScrollViewBounds()
	{
		foreach (TournamentRound round in _rounds)
		{
			round.ScrollView.NeedsCalculateBounds = true;
		}
	}

	private void ChangeScrollBarController()
	{
		int scrollTargetRoundIndex = GetScrollTargetRoundIndex();
		int i = 0;
		for (int count = _rounds.Count; i < count; i++)
		{
			_rounds[i].SetScrollBarEnable(i == scrollTargetRoundIndex);
		}
	}

	private int GetScrollTargetRoundIndex()
	{
		return Mathf.Max(0, _selectRoundIndex - 1);
	}

	private void AppendScrollBarEvent()
	{
		foreach (TournamentRound round in _rounds)
		{
			UIEventListener uIEventListener = UIEventListener.Get(round.ScrollView.verticalScrollBar.backgroundWidget.gameObject);
			uIEventListener.onPress = (UIEventListener.BoolDelegate)Delegate.Combine(uIEventListener.onPress, new UIEventListener.BoolDelegate(OnPressScrollBar));
			uIEventListener.onDrag = (UIEventListener.VectorDelegate)Delegate.Combine(uIEventListener.onDrag, new UIEventListener.VectorDelegate(OnDragScrollBar));
		}
	}

	private void OnPressScrollBar(GameObject go, bool isPressed)
	{
		PropagateScrollValue(GetRoundIndexByScrollBar(go.GetComponentInParent<UIScrollBar>()));
	}

	private void OnDragScrollBar(GameObject go, Vector2 delta)
	{
		PropagateScrollValue(GetRoundIndexByScrollBar(go.GetComponentInParent<UIScrollBar>()));
	}

	private int GetRoundIndexByScrollBar(UIScrollBar scrollBar)
	{
		int i = 0;
		for (int count = _rounds.Count; i < count; i++)
		{
			if (!(_rounds[i].ScrollView.verticalScrollBar != scrollBar))
			{
				return i;
			}
		}
		return -1;
	}

	private void PropagateScrollValue(int roundIndex)
	{
		TournamentRound tournamentRound = _rounds[roundIndex];
		UIScrollView scrollView = tournamentRound.ScrollView;
		Vector3 localPosition = scrollView.transform.localPosition;
		Vector2 clipOffset = scrollView.panel.clipOffset;
		Vector3 currentMomentum = scrollView.currentMomentum;
		foreach (TournamentRound round in _rounds)
		{
			if (!(round == tournamentRound))
			{
				UIScrollView scrollView2 = round.ScrollView;
				scrollView2.transform.localPosition = localPosition;
				scrollView2.panel.clipOffset = clipOffset;
				scrollView2.panel.SetDirty();
				scrollView2.currentMomentum = currentMomentum;
			}
		}
	}

	private void OnPressScrollView(bool isPressed)
	{
		if (!isPressed)
		{
			RestrictWithinBounds(isImmediate: false);
		}
	}

	private void OnScrollWheel(float delta)
	{
		RestrictWithinBounds(isImmediate: false);
	}

	private void OnMomentumMove()
	{
		RestrictWithinBounds(isImmediate: false);
	}

	private void RestrictWithinBounds(bool isImmediate)
	{
		int targetIndex = GetScrollTargetRoundIndex();
		UIScrollView scrollView = _rounds[targetIndex].ScrollView;
		Bounds bounds = scrollView.bounds;
		for (int i = Mathf.Max(0, _selectRoundIndex - 1); i <= Mathf.Min(_selectRoundIndex + 1, _rounds.Count - 1); i++)
		{
			Bounds bounds2 = _rounds[i].ScrollView.bounds;
			if (bounds2.min.y < bounds.min.y)
			{
				Vector3 min = bounds.min;
				min.y = bounds2.min.y;
				bounds.min = min;
			}
			if (bounds2.max.y > bounds.max.y)
			{
				Vector3 max = bounds.max;
				max.y = bounds2.max.y;
				bounds.max = max;
			}
		}
		Vector3 vector = scrollView.panel.CalculateConstrainOffset(bounds.min, bounds.max);
		vector.x = 0f;
		if (!(vector.sqrMagnitude > 0.1f))
		{
			return;
		}
		if (isImmediate)
		{
			scrollView.MoveRelative(vector);
			scrollView.currentMomentum = Vector3.zero;
			scrollView.CurrentScroll = 0f;
			PropagateScrollValue(targetIndex);
			return;
		}
		Vector3 pos = scrollView.transform.localPosition + vector;
		pos.x = Mathf.Round(pos.x);
		pos.y = Mathf.Round(pos.y);
		StopSpring();
		SpringPanelWithUpdate springPanelWithUpdate = SpringPanelWithUpdate.Begin(scrollView.gameObject, pos, 8f, delegate
		{
			PropagateScrollValue(targetIndex);
		});
		springPanelWithUpdate.onUpdate = delegate
		{
			PropagateScrollValue(targetIndex);
		};
		_currentSpring = springPanelWithUpdate;
	}

	private void StopSpring()
	{
		if (_currentSpring == null)
		{
			return;
		}
		if (!_currentSpring.enabled)
		{
			_currentSpring = null;
			return;
		}
		if (_currentSpring.onFinished != null)
		{
			_currentSpring.onFinished();
		}
		_currentSpring.enabled = false;
		_currentSpring = null;
	}

	public void SetVisible(bool isVisible)
	{
		_tournamentRoot.SetActive(isVisible);
	}

	private TournamentCell GetTournamentCell(TournamentCellData cellData)
	{
		foreach (TournamentRound round in _rounds)
		{
			TournamentCell tournamentCell = round.Cells.FirstOrDefault((TournamentCell cell) => cell.Data == cellData);
			if (tournamentCell != null)
			{
				return tournamentCell;
			}
		}
		return null;
	}
}
