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

namespace Wizard;

public class ChatMessageInfo
{
	public class RoomMatchData
	{
		public string RoomId { get; private set; }

		public BattleParameter BattleParameterInstance { get; private set; }

		public bool IsWatchEnabled { get; private set; }

		public RoomMatchData(JsonData json)
		{
			RoomId = json["room_id"].ToString();
			BattleParameterInstance = BattleParameter.JsonToBattleParameter(json);
			IsWatchEnabled = json["is_watch_enabled"].ToInt() == 1;
		}
	}

	public class DeckLogData
	{
		public int MessageId { get; private set; }

		public bool IsAbleDeleteDeck { get; private set; }

		public DeckData DeckData { get; private set; }

		public DeckLogData(JsonData jsonData)
		{
			Format format = Data.ParseApiFormat(jsonData["deck_format"].ToInt());
			DeckData = new DeckData(format, DeckAttributeType.CustomDeck);
			DeckData.Initialize(jsonData);
			DeckData.SetDeckSleeveID(3000011L);
			DeckData.SetSkinId(DeckData.GetSkinId(isDefaultSkin: true));
			MessageId = jsonData["message_id"].ToInt();
			IsAbleDeleteDeck = jsonData["delete_permission_exists"].ToBoolean();
		}

		public static List<DeckLogData> ParseDeckDataList(JsonData jsonDeckList)
		{
			List<DeckLogData> list = new List<DeckLogData>();
			for (int i = 0; i < jsonDeckList.Count; i++)
			{
				list.Add(new DeckLogData(jsonDeckList[i]));
			}
			return list;
		}

		public static List<DeckData> ConvertDeckDataList(List<DeckLogData> deckLogDataList)
		{
			return deckLogDataList.ConvertAll((DeckLogData log) => log.DeckData);
		}

		public static DeckLogData GetDeckLogDataByDeckId(List<DeckLogData> deckLogDataList, int deckId)
		{
			return deckLogDataList.Find((DeckLogData data) => data.DeckData.GetDeckID() == deckId);
		}
	}

	public class GatheringWinnerUsers
	{
		public List<ChatUserInfo> WinnerList { get; private set; } = new List<ChatUserInfo>();

		public GatheringWinnerUsers(string message, List<ChatUserInfo> chatUserList)
		{
			if (message == "")
			{
				return;
			}
			string[] array = message.Split(',');
			foreach (string s in array)
			{
				ChatUserInfo item = null;
				if (int.TryParse(s, out var viewerId))
				{
					item = chatUserList.First((ChatUserInfo data) => data.ViewerId == viewerId);
				}
				WinnerList.Add(item);
			}
		}
	}

	public class GatheringTournamentRoomData
	{
		public RoomMatchData RoomData { get; private set; }

		public ChatUserInfo User1 { get; private set; }

		public ChatUserInfo User2 { get; private set; }

		public bool IsMyselfMathcedRoom
		{
			get
			{
				if (!User1.IsMyself())
				{
					return User2.IsMyself();
				}
				return true;
			}
		}

		public GatheringTournamentRoomData(JsonData jsonData, List<ChatUserInfo> chatUserList)
		{
			RoomData = new RoomMatchData(jsonData["room"]);
			int viewerId1 = jsonData["viewer_id1"].ToInt();
			int viewerId2 = jsonData["viewer_id2"].ToInt();
			User1 = chatUserList.First((ChatUserInfo data) => data.ViewerId == viewerId1);
			User2 = chatUserList.First((ChatUserInfo data) => data.ViewerId == viewerId2);
		}
	}

	public enum eMessageType
	{
		NORMAL = 0,
		STAMP = 1,
		DECK = 2,
		JOIN = 3,
		LEAVE = 4,
		REPLAY = 5,
		CHANGE_LEADER = 6,
		CHANGE_SUB_LEADER = 7,
		CREATE_GUILD = 8,
		REMOVE = 9,
		ROOM_MATCH = 10,
		DESCRIPTION = 11,
		GATHERING_CREATE = 12,
		GATHERING_JOIN = 13,
		GATHERING_LEAVE = 14,
		GATHERING_REMOVE = 15,
		GATHERING_BATTLE_START = 16,
		GATHERING_BATTLE_END = 17,
		GATHERING_TOURNAMENT_ROOM = 18,
		INVALID_VALUE = -1
	}

	public enum eTalkerType
	{
		INVALID,
		NO_MEMBER,
		OWN,
		OTHER
	}

	public bool IsVisibleMessage { get; private set; } = true;

	public bool IsCloseContent { get; private set; }

	public eTalkerType TalkerType
	{
		get
		{
			eTalkerType result = eTalkerType.INVALID;
			switch (MessageType)
			{
			case eMessageType.JOIN:
			case eMessageType.LEAVE:
			case eMessageType.CHANGE_LEADER:
			case eMessageType.CHANGE_SUB_LEADER:
			case eMessageType.CREATE_GUILD:
			case eMessageType.REMOVE:
			case eMessageType.DESCRIPTION:
			case eMessageType.GATHERING_CREATE:
			case eMessageType.GATHERING_JOIN:
			case eMessageType.GATHERING_LEAVE:
			case eMessageType.GATHERING_REMOVE:
			case eMessageType.GATHERING_BATTLE_START:
			case eMessageType.GATHERING_BATTLE_END:
			case eMessageType.GATHERING_TOURNAMENT_ROOM:
				result = eTalkerType.NO_MEMBER;
				break;
			case eMessageType.NORMAL:
			case eMessageType.STAMP:
			case eMessageType.DECK:
			case eMessageType.REPLAY:
			case eMessageType.ROOM_MATCH:
				result = ((ViewerId != PlayerStaticData.UserViewerID) ? eTalkerType.OTHER : eTalkerType.OWN);
				break;
			}
			return result;
		}
	}

	public int ViewerId { get; private set; }

	public ChatUserInfo UserInfo { get; private set; }

	public int MessageId { get; private set; }

	public eMessageType MessageType { get; private set; }

	public string Message { get; private set; }

	public int CreateTime { get; private set; }

	public int StampId { get; private set; }

	public ReplayInfoItem ReplayInfo { get; private set; }

	public DeckLogData DeckInfo { get; private set; }

	public RoomMatchData RoomData { get; private set; }

	public GatheringWinnerUsers GatheringWinnerUsersInfo { get; private set; }

	public GatheringTournamentRoomData GatheringTournamentRoom { get; private set; }

	public ChatMessageInfo(eMessageType messageType)
	{
		initialize();
		MessageType = messageType;
	}

	public ChatMessageInfo(JsonData messageData, List<ChatUserInfo> userList)
	{
		initialize();
		ParseMessageData(messageData, userList);
	}

	public string GetCreateTimeText()
	{
		return ConvertTime.DateTimeToAgoText(ConvertTime.ToLocalByDateTime(ConvertTime.UnixTimeToDateTime(CreateTime)));
	}

	public List<string> GetResourcePathList()
	{
		List<string> loadPath = new List<string>();
		switch (MessageType)
		{
		case eMessageType.STAMP:
			loadPath.Add(Toolbox.ResourcesManager.GetAssetTypePath(StampId.ToString(), ResourcesManager.AssetLoadPathType.Stamp));
			break;
		case eMessageType.DECK:
			if (DeckInfo != null)
			{
				long existingSleeveId = Toolbox.ResourcesManager.GetExistingSleeveId(DeckInfo.DeckData.GetDeckSleeveID());
				Sleeve sleeve = Data.Master.SleeveMgr.Get(existingSleeveId);
				loadPath.Add(Toolbox.ResourcesManager.GetAssetTypePath(existingSleeveId.ToString(), ResourcesManager.AssetLoadPathType.SleeveTexture));
				if (sleeve.IsPremiumSleeve)
				{
					UIManager.GetInstance().getUIBase_CardManager().AddPremireSleevePath(ref loadPath, sleeve);
				}
				loadPath.Add(Toolbox.ResourcesManager.GetAssetTypePath(DeckInfo.DeckData.GetSkinId().ToString(), ResourcesManager.AssetLoadPathType.DeckListTexture));
			}
			break;
		case eMessageType.REPLAY:
			if (ReplayInfo != null)
			{
				loadPath.Add(Toolbox.ResourcesManager.GetAssetTypePath(UserInfo.EmblemId.ToString(), ResourcesManager.AssetLoadPathType.Emblem_S));
				loadPath.Add(Toolbox.ResourcesManager.GetAssetTypePath(ReplayInfo.OpponentEmblemId, ResourcesManager.AssetLoadPathType.Emblem_S));
			}
			break;
		case eMessageType.GATHERING_BATTLE_END:
			foreach (ChatUserInfo winner in GatheringWinnerUsersInfo.WinnerList)
			{
				loadPath.Add(Toolbox.ResourcesManager.GetAssetTypePath(winner.EmblemId.ToString(), ResourcesManager.AssetLoadPathType.Emblem_S));
			}
			break;
		case eMessageType.GATHERING_TOURNAMENT_ROOM:
			if (GatheringTournamentRoom != null)
			{
				loadPath.AddRange(GatheringTournamentRoom.User1.GetResourcePathList());
				loadPath.AddRange(GatheringTournamentRoom.User2.GetResourcePathList());
			}
			break;
		}
		if ((TalkerType == eTalkerType.OWN || TalkerType == eTalkerType.OTHER) && UserInfo != null)
		{
			loadPath.AddRange(UserInfo.GetResourcePathList());
		}
		return loadPath.Distinct().ToList();
	}

	public void CloseContent()
	{
		IsCloseContent = true;
		ReplayInfo = null;
		DeckInfo = null;
		RoomData = null;
		GatheringTournamentRoom = null;
	}

	private void initialize()
	{
		ViewerId = 0;
		MessageId = 0;
		MessageType = eMessageType.NORMAL;
		Message = null;
		CreateTime = 0;
		StampId = 0;
		ReplayInfo = null;
		DeckInfo = null;
	}

	private void ParseMessageData(JsonData json, List<ChatUserInfo> userList)
	{
		ViewerId = json["viewer_id"].ToInt();
		MessageId = json["message_id"].ToInt();
		int num = json["message_type"].ToInt();
		if (Enum.IsDefined(typeof(eMessageType), num))
		{
			MessageType = (eMessageType)num;
		}
		CreateTime = json["create_time"].ToInt();
		switch (MessageType)
		{
		case eMessageType.NORMAL:
			Message = json["message"].ToString();
			break;
		case eMessageType.STAMP:
			StampId = json["message"].ToInt();
			break;
		case eMessageType.REPLAY:
			ParseReplayData(json);
			break;
		case eMessageType.DECK:
			ParseDeckData(json);
			break;
		case eMessageType.ROOM_MATCH:
			ParseRoomMatchData(json);
			break;
		case eMessageType.GATHERING_BATTLE_END:
			GatheringWinnerUsersInfo = new GatheringWinnerUsers(json["message"].ToString(), userList);
			break;
		case eMessageType.GATHERING_TOURNAMENT_ROOM:
			ParseGatheringTournamentRoomData(json, userList);
			break;
		}
		SetUserInfo(userList);
	}

	private void ParseReplayData(JsonData json)
	{
		if (json.Keys.Contains("replay"))
		{
			JsonData jsonData = json["replay"];
			if (jsonData == null)
			{
				ReplayInfo = null;
				CloseContent();
			}
			else
			{
				ReplayInfo = new ReplayInfoItem(jsonData);
			}
		}
	}

	private void ParseDeckData(JsonData json)
	{
		if (json.Keys.Contains("deck"))
		{
			JsonData jsonData = json["deck"];
			if (jsonData == null)
			{
				DeckInfo = null;
				CloseContent();
			}
			else
			{
				DeckInfo = new DeckLogData(jsonData);
			}
		}
	}

	private void ParseRoomMatchData(JsonData json)
	{
		if (json.Keys.Contains("room"))
		{
			JsonData jsonData = json["room"];
			if (jsonData == null)
			{
				RoomData = null;
				CloseContent();
			}
			else
			{
				RoomData = new RoomMatchData(jsonData);
			}
		}
	}

	private void ParseGatheringTournamentRoomData(JsonData json, List<ChatUserInfo> userList)
	{
		if (json.Keys.Contains("room"))
		{
			IsVisibleMessage = json["viewer_id1"].ToInt() == PlayerStaticData.UserViewerID || json["viewer_id2"].ToInt() == PlayerStaticData.UserViewerID;
			if (json["room"] == null)
			{
				GatheringTournamentRoom = null;
				CloseContent();
			}
			else
			{
				GatheringTournamentRoom = new GatheringTournamentRoomData(json, userList);
			}
		}
	}

	private void SetUserInfo(List<ChatUserInfo> userList)
	{
		UserInfo = userList.Find((ChatUserInfo x) => x.ViewerId == ViewerId);
	}
}
