using System.Collections.Generic;
using System.Linq;
using LitJson;

namespace Wizard;

public class GatheringTournamentInfoTask : BaseTask
{
	private class Match
	{
		public int MatchId;

		public int ParentMatchId;

		public int ParentMatchUserIndex;

		public int Status;

		public int ViewerId1;

		public int ViewerId2;

		public int WinnerViewerId;

		public int RoomId;

		public bool IsForceLose1;

		public bool IsForceLose2;

		public bool IsForceLoseWinner;

		public bool IsExtra;

		public bool IsFinalMatchReset;

		public bool IsActive
		{
			get
			{
				if (ViewerId1 > 0 && ViewerId2 > 0)
				{
					return WinnerViewerId == 0;
				}
				return false;
			}
		}
	}

	public List<TournamentData> TournamentDataList { get; private set; }

	public GatheringTournamentInfoTask()
	{
		base.type = ApiType.Type.GatheringTournamentInfo;
	}

	protected override int Parse()
	{
		int num = base.Parse();
		if (num != 1)
		{
			return num;
		}
		TournamentDataList = ParseTournamentDataList(base.ResponseData["data"]);
		return num;
	}

	private List<TournamentData> ParseTournamentDataList(JsonData data)
	{
		if (data == null)
		{
			return null;
		}
		Dictionary<int, (string, long)> userInfo = CollectUserInfo(data);
		List<TournamentData> list = new List<TournamentData>();
		if (data.TryGetValue("1", out var value))
		{
			list.Add(ParseTournamentData(value, isWinners: true, userInfo));
		}
		if (data.TryGetValue("2", out var value2))
		{
			list.Add(ParseTournamentData(value2, isWinners: false, userInfo));
		}
		return list;
	}

	private TournamentData ParseTournamentData(JsonData data, bool isWinners, Dictionary<int, (string, long)> userInfo)
	{
		Match[][] matches = ConvertToMatch(data);
		Dictionary<TournamentCellData, int> cellMatchIdDict = new Dictionary<TournamentCellData, int>();
		TournamentData tournamentData = new TournamentData();
		int num = matches.Length + 1;
		List<TournamentRoundData> list = (tournamentData.Rounds = new List<TournamentRoundData>(num));
		for (int i = 0; i < num; i++)
		{
			TournamentRoundData item = new TournamentRoundData
			{
				RoundNo = i + 1,
				Cells = new List<TournamentCellData>(),
				Watchs = new List<TournamentWatchData>()
			};
			list.Add(item);
		}
		Match match = matches[matches.Length - 1][0];
		TournamentCellData.CellState cellState = GetCellState(match, match.WinnerViewerId, match.IsForceLoseWinner);
		CreateCell(list[num - 1], match.WinnerViewerId, match.MatchId, cellState, isWinners).IsTerminal = true;
		int i2 = matches.Length - 1;
		while (i2 >= 0)
		{
			Match[] source = matches[i2];
			TournamentRoundData tournamentRoundData = list[i2 + 1];
			TournamentRoundData tournamentRoundData2 = list[i2];
			foreach (TournamentCellData cell in tournamentRoundData.Cells)
			{
				if (cell == null || !cellMatchIdDict.ContainsKey(cell))
				{
					continue;
				}
				int matchId = cellMatchIdDict[cell];
				Match match2 = source.FirstOrDefault((Match m) => m.MatchId == matchId);
				TournamentCellData tournamentCellData = CreateCell(tournamentRoundData2, match2.ViewerId1, GetChildMatchId(1), GetCellState(match2, match2.ViewerId1, match2.IsForceLose1), isChampion: false);
				tournamentCellData.Line = TournamentCellData.LineType.Down;
				tournamentCellData.Parent = cell;
				tournamentCellData.IsFinalMatchReset = false;
				TournamentCellData tournamentCellData2 = CreateCell(tournamentRoundData2, match2.ViewerId2, GetChildMatchId(2), GetCellState(match2, match2.ViewerId2, match2.IsForceLose2), isChampion: false);
				tournamentCellData2.Line = TournamentCellData.LineType.Up;
				tournamentCellData2.Parent = cell;
				tournamentCellData2.IsFinalMatchReset = match2.IsFinalMatchReset;
				cell.Children = new TournamentCellData[2] { tournamentCellData, tournamentCellData2 };
				tournamentRoundData2.IsExtraRound = match2.IsExtra;
				if (match2.RoomId > 0)
				{
					CreateWatch(tournamentRoundData2, match2);
				}
				if (match2.IsExtra)
				{
					i2--;
					match2 = matches[i2][0];
					matchId = match2.MatchId;
					tournamentRoundData2 = list[i2];
					tournamentCellData = CreateCell(tournamentRoundData2, match2.ViewerId1, GetChildMatchId(1), GetCellState(match2, match2.ViewerId1, match2.IsForceLose1), isChampion: false);
					tournamentCellData.Line = TournamentCellData.LineType.Down;
					tournamentCellData.IsPreExtra = true;
					tournamentCellData2 = CreateCell(tournamentRoundData2, match2.ViewerId2, GetChildMatchId(2), GetCellState(match2, match2.ViewerId2, match2.IsForceLose2), isChampion: false);
					tournamentCellData2.Line = TournamentCellData.LineType.Up;
					tournamentCellData2.IsPreExtra = true;
					if (match2.RoomId > 0)
					{
						CreateWatch(tournamentRoundData2, match2);
					}
				}
				int GetChildMatchId(int parentMatchUserIndex)
				{
					if (i2 == 0)
					{
						return 0;
					}
					return matches[i2 - 1].FirstOrDefault((Match m) => m.ParentMatchId == matchId && m.ParentMatchUserIndex == parentMatchUserIndex)?.MatchId ?? 0;
				}
			}
			int num2 = i2 - 1;
			i2 = num2;
		}
		return tournamentData;
		TournamentCellData CreateCell(TournamentRoundData round, int viewerId, int num3, TournamentCellData.CellState state, bool isChampion)
		{
			TournamentCellData tournamentCellData3 = new TournamentCellData
			{
				State = state
			};
			(string, long) tuple = userInfo[viewerId];
			tournamentCellData3.Name = tuple.Item1;
			tournamentCellData3.EmblemId = tuple.Item2;
			tournamentCellData3.ViewerId = viewerId;
			tournamentCellData3.IsChampion = isChampion;
			tournamentCellData3.Round = round;
			round.Cells.Add(tournamentCellData3);
			if (num3 > 0)
			{
				cellMatchIdDict.Add(tournamentCellData3, num3);
			}
			return tournamentCellData3;
		}
		static TournamentWatchData CreateWatch(TournamentRoundData round, Match match3)
		{
			TournamentWatchData tournamentWatchData = new TournamentWatchData
			{
				RoomId = match3.RoomId,
				ViewerId0 = match3.ViewerId1,
				ViewerId1 = match3.ViewerId2
			};
			round.Watchs.Add(tournamentWatchData);
			return tournamentWatchData;
		}
	}

	private TournamentCellData.CellState GetCellState(Match match, int viewerId, bool isForceLose)
	{
		if (isForceLose)
		{
			if (viewerId != 0)
			{
				return TournamentCellData.CellState.LoseByDefault;
			}
			return TournamentCellData.CellState.Blank;
		}
		if (match.Status == 5)
		{
			if (viewerId == 0)
			{
				return TournamentCellData.CellState.LoseByDefault;
			}
			if (match.WinnerViewerId != viewerId)
			{
				return TournamentCellData.CellState.Lose;
			}
			return TournamentCellData.CellState.Win;
		}
		if (viewerId == 0)
		{
			return TournamentCellData.CellState.Blank;
		}
		if (match.IsActive)
		{
			return TournamentCellData.CellState.Active;
		}
		return TournamentCellData.CellState.Unresolved;
	}

	private Dictionary<int, (string, long)> CollectUserInfo(JsonData data)
	{
		Dictionary<int, (string, long)> dictionary = new Dictionary<int, (string, long)> { 
		{
			0,
			(string.Empty, 0L)
		} };
		foreach (string key2 in data.Keys)
		{
			JsonData jsonData = data[key2];
			foreach (string key3 in jsonData.Keys)
			{
				JsonData jsonData2 = jsonData[key3];
				for (int i = 0; i < jsonData2.Count; i++)
				{
					JsonData jsonData3 = jsonData2[i];
					Add(jsonData3["user1"], dictionary);
					Add(jsonData3["user2"], dictionary);
				}
			}
		}
		return dictionary;
		static void Add(JsonData userData, Dictionary<int, (string, long)> dict)
		{
			if (userData != null)
			{
				int key = userData["viewer_id"].ToInt();
				if (!dict.ContainsKey(key))
				{
					string item = userData["name"].ToString();
					long item2 = userData["emblem_id"].ToLong();
					dict.Add(key, (item, item2));
				}
			}
		}
	}

	private Match[][] ConvertToMatch(JsonData data)
	{
		Match[][] array = new Match[data.Count][];
		for (int i = 0; i < data.Count; i++)
		{
			JsonData jsonData = data[(i + 1).ToString()];
			Match[] array2 = new Match[jsonData.Count];
			for (int j = 0; j < jsonData.Count; j++)
			{
				JsonData jsonData2 = jsonData[j];
				bool isFinalMatchReset = false;
				if (jsonData2.TryGetValue("is_show_one_more_win", out var value))
				{
					isFinalMatchReset = value.ToInt() == 1;
				}
				Match match = new Match
				{
					MatchId = jsonData2["matching_id"].ToInt(),
					ParentMatchId = jsonData2["winner_parent_matching_id"].ToInt(),
					ParentMatchUserIndex = jsonData2["winner_parent_matching_viewer_id_suffix"].ToInt(),
					Status = jsonData2["status"].ToInt(),
					ViewerId1 = jsonData2["viewer_id1"].ToInt(),
					ViewerId2 = jsonData2["viewer_id2"].ToInt(),
					WinnerViewerId = jsonData2["winner_viewer_id"].ToInt(),
					RoomId = jsonData2["display_room_id"].ToInt(),
					IsForceLose1 = (jsonData2["is_force_lose1"].ToInt() == 1),
					IsForceLose2 = (jsonData2["is_force_lose2"].ToInt() == 1),
					IsExtra = (jsonData2["side_type"].ToInt() == 3),
					IsFinalMatchReset = isFinalMatchReset
				};
				match.IsForceLoseWinner = ((match.ViewerId1 == match.WinnerViewerId) ? match.IsForceLose1 : match.IsForceLose2);
				array2[j] = match;
			}
			array[i] = array2;
		}
		return array;
	}
}
