package extend.zp.uitl;

import java.io.IOException;
import java.util.*;

import extend.zp.EXPlayer;
import extend.zp.EXRoom;
import extend.zp.OpCard;
import extend.zp.RuleWeight;

public class WinCard {
	public int					pair_count;
	public int					long_count;
	public Stack<List<Integer>>	stack;
	public Stack<Integer>		stackHuxi;
	public List<Integer>		cardList;

	private void push(List<Integer> cardGroup) {
		this.stack.push(cardGroup);
	}

	private void rollBack() {
		List<Integer> cardGroup = this.stack.pop();
		for (Integer card : cardGroup) {
			this.cardList.add(card);
		}
		Collections.sort(this.cardList);
	}

	private boolean tryKezi(int card, EXPlayer player) {
		if (CardUtil.cardNum(card, this.cardList) >= 3) {
			CardUtil.removeCard(this.cardList, card, CardUtil.cardNum(card, this.cardList));
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card);
			cardGroup.add(card);
			this.push(cardGroup);
			int huXi = 0;
			if (player.getRoom().isTianHu && card == player.getRoom().drawCard && player.getRoom().bankerSeat == player.seat) {
				huXi = Paixing.caclHuxi(RuleWeight.TYPE_KAN, card);
			} else {
				huXi = Paixing.caclHuxi(RuleWeight.TYPE_PONG, card);
			}
			player.huXi += huXi;
			this.stackHuxi.push(huXi);
			return true;
		}
		return false;
	}

	private boolean tryShunzi1(int card, EXPlayer player) {
		if (card < 200 && card % 100 > 8) {
			return false;
		}
		if (CardUtil.cardNum(card + 1, this.cardList) > 0 && CardUtil.cardNum(card + 2, this.cardList) > 0) {
			CardUtil.removeCard(this.cardList, card, 1);
			CardUtil.removeCard(this.cardList, card + 1, 1);
			CardUtil.removeCard(this.cardList, card + 2, 1);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card + 1);
			cardGroup.add(card + 2);
			this.push(cardGroup);

			int huXi = 0;
			if (card % 100 == 1) {
				huXi = Paixing.caclHuxi(RuleWeight.TYPE_CHOW, card);
				player.huXi += huXi;
			}
			this.stackHuxi.push(huXi);
			return true;
		}
		return false;
	}

	private boolean tryShunzi2(int card) {
		if (CardUtil.cardType(card) == RuleWeight.SMALL_CARD) {
			if (CardUtil.cardNum(card + 100, this.cardList) >= 1 && CardUtil.cardNum(card, this.cardList) >= 2) {
				CardUtil.removeCard(this.cardList, card, 2);
				CardUtil.removeCard(this.cardList, card + 100, 1);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card);
				cardGroup.add(card + 100);
				this.push(cardGroup);
				this.stackHuxi.push(0);
				return true;
			}
			if (CardUtil.cardNum(card + 100, this.cardList) >= 2) {
				CardUtil.removeCard(this.cardList, card, 1);
				CardUtil.removeCard(this.cardList, card + 100, 2);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card + 100);
				cardGroup.add(card + 100);
				this.push(cardGroup);
				this.stackHuxi.push(0);
				return true;
			}
		} else {
			if (CardUtil.cardNum(card - 100, this.cardList) >= 1 && CardUtil.cardNum(card, this.cardList) >= 2) {
				CardUtil.removeCard(this.cardList, card, 2);
				CardUtil.removeCard(this.cardList, card - 100, 1);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card);
				cardGroup.add(card - 100);
				this.push(cardGroup);
				this.stackHuxi.push(0);
				return true;
			}
			if (CardUtil.cardNum(card - 100, this.cardList) >= 2) {
				CardUtil.removeCard(this.cardList, card, 1);
				CardUtil.removeCard(this.cardList, card - 100, 2);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card - 100);
				cardGroup.add(card - 100);
				this.push(cardGroup);
				this.stackHuxi.push(0);
				return true;
			}
		}
		return false;
	}

	private boolean tryShunzi3(int card, EXPlayer player) {
		if (card % 100 == 2) {
			if (CardUtil.cardNum(card + 5, this.cardList) > 0 && CardUtil.cardNum(card + 8, this.cardList) > 0) {
				CardUtil.removeCard(this.cardList, card, 1);
				CardUtil.removeCard(this.cardList, card + 5, 1);
				CardUtil.removeCard(this.cardList, card + 8, 1);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card + 5);
				cardGroup.add(card + 8);
				this.push(cardGroup);

				int huXi = Paixing.caclHuxi(RuleWeight.TYPE_CHOW, card);
				player.huXi += huXi;
				this.stackHuxi.push(huXi);
				return true;
			}
		}
		return false;
	}

	private boolean tryPair(int card) {
		if (this.pair_count > 0) {
			return false;
		}
		if (CardUtil.cardNum(card, this.cardList) >= 2) {
			CardUtil.removeCard(this.cardList, card, 2);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card);
			this.push(cardGroup);
			this.pair_count = 1;
			this.stackHuxi.push(0);
			return true;
		}
		return false;
	}

	public boolean tryWin(EXPlayer player) {
		if (this.cardList.size() == 0) {
			if (player.tiCount + player.kongCount > 0) {
				if (this.pair_count == 1) {
					return true;
				}
				return false;
			} else {
				if (this.pair_count > 0) {
					return false;
				}
				return true;
			}
		}

		int activeCard = 0;
		for (int card : this.cardList) {
			if (card == 201 || card == 202) {
				activeCard = card;
				break;
			}
		}


		if (activeCard == 0) {
			activeCard = this.cardList.get(0);
		}

		if (activeCard % 100 == 1) {
			if (tryShunzi1(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}

			if (tryKezi(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (player.tiCount + player.kongCount > 0) {
				if (tryPair(activeCard)) {
					if (tryWin(player)) {
						return true;
					}
					this.pair_count = 0;
					this.rollBack();
					this.stackHuxi.pop();
				}
			}
			if (tryShunzi2(activeCard)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				this.stackHuxi.pop();
			}
		} else if (activeCard % 100 == 2) {
			if (tryShunzi3(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryKezi(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (player.tiCount + player.kongCount > 0) {
				if (tryPair(activeCard)) {
					if (tryWin(player)) {
						return true;
					}
					this.pair_count = 0;
					this.rollBack();
					this.stackHuxi.pop();
				}
			}
			if (tryShunzi1(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryShunzi2(activeCard)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				this.stackHuxi.pop();
			}
		} else {
			if (tryKezi(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (player.tiCount + player.kongCount > 0) {
				if (tryPair(activeCard)) {
					if (tryWin(player)) {
						return true;
					}
					this.pair_count = 0;
					this.rollBack();
					this.stackHuxi.pop();
				}
			}
			if (tryShunzi1(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryShunzi2(activeCard)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				this.stackHuxi.pop();
			}
		}

		return false;
	}

	public WinCard(List<Integer> cardInhand, int addCard) {
		this.stack = new Stack<List<Integer>>();
		this.stackHuxi = new Stack<Integer>();
		this.cardList = new ArrayList<Integer>();
		this.cardList.addAll(cardInhand);
		if (addCard > 0) {
			this.cardList.add(addCard);
		}
		Collections.sort(this.cardList);
	}

	public static void main(String[] args) throws ClassNotFoundException, IOException {
		Map<String, String> redis_room_map = new HashMap<>();

		redis_room_map.put("id","749322");
		redis_room_map.put("game","17");
		redis_room_map.put("maxPlayers","2");
		redis_room_map.put("players","[168168,791309]");
		redis_room_map.put("group","532196");
		redis_room_map.put("owner","{user}:123456");
		redis_room_map.put("create_time","1749539730");
		redis_room_map.put("options","{\"tuoguan_active_time\":0,\"daniao\":2,\"pid\":17,\"shoupai\":0,\"honghu\":true,\"yikuaibian\":true,\"tiandihu\":true,\"isvip\":0,\"mode\":1,\"hpData\":{\"limitloot\":0,\"limitInRoom\":0,\"type\":1,\"times\":3000,\"maxRound\":100,\"xipai_rewardType\":3,\"limitPump\":0,\"limitPlay\":1000,\"robot_room\":0,\"basePump\":0,\"anchou_rewardType\":3,\"tex_times_room\":1000,\"rewards_list\":[{\"UpperLimitReward\":0,\"pumpProportion\":0,\"UpperLimit\":0}]},\"kahu\":true,\"maxRound\":100,\"mingwei\":true,\"hp_no_limit\":0,\"isNonnegative\":1,\"wuhu\":true,\"game_id\":17,\"maxPlayers\":2,\"hunum\":0,\"fengding\":1,\"haidiliao\":false,\"tuoguan\":false,\"isHidden\":0,\"xi_pai\":true,\"yidianhong\":true,\"shisanhong\":true,\"tuoguan_active_timeIndex\":1,\"tuoguan_result_type\":0,\"xi_pai_score\":1000,\"choupai\":0}");
		redis_room_map.put("cache_ver","12345");
		redis_room_map.put("times","100");
		redis_room_map.put("pay","2");
		redis_room_map.put("payer","2");
		redis_room_map.put("AA","1");
		redis_room_map.put("agent","true");
		redis_room_map.put("status","1");
		redis_room_map.put("isActive","true");
		redis_room_map.put("opt","1");
		redis_room_map.put("round","1");
		redis_room_map.put("gpid","17");
		redis_room_map.put("open","0");
		redis_room_map.put("kick_time","30");
		redis_room_map.put("seats","[1,2]");

		;
		EXRoom room = new EXRoom("749322",redis_room_map);
		EXPlayer player = new EXPlayer(168168,room,"ddddddd");


		List<Integer> list = new ArrayList<>();
		String str = "106";
		for (String card : str.split(", ")) {
			list.add(Integer.parseInt(card));
		}
		player.cardInhand = list;


		List<OpCard> op = new ArrayList<OpCard>();
		OpCard opCard=new OpCard(3, 102, 102, 102, 9);
		op.add(opCard);
		WinCard win = new WinCard(list, 106);
		boolean res = win.tryWin(player);
	}

}
