package extend.zp.player.state;

import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.data.cache.GroupMemberCache;
import com.game.Global;
import com.game.data.Player;
import com.game.player.state.PlayerPauseState;
import com.game.player.state.PlayerWaitState;
import com.game.state.StateBase;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TObject;
import com.taurus.core.plugin.redis.Redis;
import com.taurus.core.util.Logger;
import com.taurus.core.util.StringUtil;
import com.taurus.permanent.TPServer;

import extend.zp.*;
import extend.zp.room.state.EXRoomSetpState;
import extend.zp.uitl.CardUtil;
import extend.zp.uitl.Paixing;


public class EXPlayerDrawState extends StateBase<EXPlayer> {
	Logger logger = Logger.getLogger(getClass());
	@Override
	public void enter(EXPlayer owner) {
		owner.notChiSet.clear();

		EXRoom room = owner.getRoom();
		if (owner.getRoom().card.getCount() == 0) {
			owner.getRoom().liuju = true;
			owner.getRoom().liujuNum++;
			owner.getRoom().endGame();
			return;
		}
		room.isAllPass = false;
		owner.getRoom().tipMap.clear();
		if (owner.seat == room.adminSeat) {
			if (room.while_list)
			{
				double rand = Math.random() % 100 * 100;
				ArrayList<Integer> tempCardList = new ArrayList<Integer>();
				int count = 0;
				do {
					int drawCard = room.card.popsub();

					boolean flag = false;
					for (Map.Entry<Integer, Player> entry : room.playerMapBySeat.entrySet()) {
						Player player = entry.getValue();

						if (!player.is_white) {
							if (Paixing.checkWin((EXPlayer) player, drawCard, true)) {
								flag = true;
								break;
							}
						}
					}

					if (flag) {
						if (rand > room.white_value && room.card.cardList.size() != 0 && count++ <= 5) {
							tempCardList.add(drawCard);
							Global.logger.info("no white:" + owner.playerid + " to hu:" + drawCard);
							continue;
						}
					}

					owner.drawCard = drawCard;
					break;
				}
				while(true);
				room.card.cardList.addAll(tempCardList);
			}
			else
			{
				owner.drawCard = room.card.popsub();
			}
		} else {
			if (room.while_list)
			{
				double rand = Math.random() % 100 * 100;
				if (rand > room.white_value)
				{
					ArrayList<Integer> tempCardList = new ArrayList<Integer>();
					int count = 0;
					do {
						int drawCard = room.card.pop();

						boolean flag = false;
						for (Map.Entry<Integer, Player> entry : room.playerMapBySeat.entrySet()) {
							Player player = entry.getValue();

							if (player.playerid != owner.playerid) {
								if (player.is_white)
								{
									if (IsGoodCard2((EXPlayer) player, drawCard)) {
										flag = true;
										break;
									}
								}
								else {
									if (IsGoodCard2((EXPlayer) player, drawCard)) {
										flag = false;
									}
								}
							}
						}

						if (owner.is_white) {
							if (IsGoodCard((EXPlayer) owner, drawCard)) {
								flag = true;
							}
						}
						else {
							if (IsGoodCard((EXPlayer) owner, drawCard)) {
								flag = false;
							}
						}

						if (!flag) {
							if (room.card.cardList.size() > 0 && count++ <= room.card.cardList.size()) {
								tempCardList.add(drawCard);
								//Global.logger.info("not good card:" + drawCard + " for white player");
								continue;
							}
						}

						owner.drawCard = drawCard;
						break;
					}
					while(true);
					room.card.cardList.addAll(tempCardList);
				}
				else {
					owner.drawCard = room.card.pop();
				}
			}
			else
			{
				if(owner.black_white_status == 2) {
					double rand = Math.random() % 100 * 100;
					if (rand <= owner.black_white_rate)
					{
						ArrayList<Integer> tempCardList = new ArrayList<Integer>();
						int count = 0;
						do {
							int drawCard = room.card.pop();

							boolean flag = false;
							if (IsGoodCard((EXPlayer) owner, drawCard)) {
								flag = true;
							}

							if (!flag) {
								if (room.card.cardList.size() > 0 && count++ <= room.card.cardList.size()) {
									tempCardList.add(drawCard);
									//Global.logger.info("not good card:" + drawCard + " for white player");
									continue;
								}
							}

							owner.drawCard = drawCard;
							break;
						}
						while(true);
						room.card.cardList.addAll(tempCardList);
					}
					else {
						owner.drawCard = room.card.pop();
					}
				}
				else if(owner.black_white_status == 1) {
					double rand = Math.random() % 100 * 100;
					if (rand <= owner.black_white_rate)
					{
						ArrayList<Integer> tempCardList = new ArrayList<Integer>();
						int count = 0;
						do {
							int drawCard = room.card.pop();

							boolean flag = false;
							if (IsGoodCard((EXPlayer) owner, drawCard)) {
								flag = true;
							}

							if (flag) {
								if (room.card.cardList.size() > 0 && count++ <= room.card.cardList.size()) {
									tempCardList.add(drawCard);
									//Global.logger.info("not good card:" + drawCard + " for white player");
									continue;
								}
							}

							owner.drawCard = drawCard;
							break;
						}
						while(true);
						room.card.cardList.addAll(tempCardList);
					}
					else {
						owner.drawCard = room.card.pop();
					}
				}
				else {
					boolean black_flag = false;
					for (Map.Entry<Integer, Player> entry : room.playerMapBySeat.entrySet()) {
						Player player = entry.getValue();

						if (player.playerid != owner.playerid) {
							if (player.black_white_status == 1)
							{
								black_flag = true;
							}
						}
					}

					double rand = Math.random() % 100 * 100;
					if (black_flag && rand <= owner.black_white_rate)
					{
						ArrayList<Integer> tempCardList = new ArrayList<Integer>();
						int count = 0;
						do {
							int drawCard = room.card.pop();

							boolean flag = false;
							for (Map.Entry<Integer, Player> entry : room.playerMapBySeat.entrySet()) {
								Player player = entry.getValue();

								if (player.playerid != owner.playerid) {
									if (player.black_white_status == 1)
									{
										if (IsGoodCard2((EXPlayer) player, drawCard)) {
											flag = true;
											break;
										}
									}
								}
							}

							if (flag) {
								if (room.card.cardList.size() > 0 && count++ <= room.card.cardList.size()) {
									tempCardList.add(drawCard);
									Global.logger.info("not good card:" + drawCard + " for white player");
									continue;
								}
							}

							owner.drawCard = drawCard;
							break;
						}
						while(true);
						room.card.cardList.addAll(tempCardList);
					}
					else {
						owner.drawCard = room.card.pop();
					}
				}
			}
		}

		room.step++;
		int tempStep = room.step;
		// if (owner.seat == 2) {
		// owner.drawCard = 102;
		// }
		logger.info("drawCard,player:" + owner + ",card:" + owner.drawCard);
		room.drawCard = owner.drawCard;

		int leftCount = room.card.getCount();
		((EXGameController) Global.gameCtr).getCard(owner, leftCount);

		int card = owner.drawCard;
		/*
		for (int i = 0; i < owner.kanGroup.size(); i++) {
			if (owner.drawCard == owner.kanGroup.get(i)[0]) {
				card = 0;
				break;
			}
		}
		for (int i = 0; i < owner.weiGroup.size(); i++) {
			if (owner.drawCard == owner.weiGroup.get(i)[0]) {
				card = 0;
				break;
			}
		}
		if (CardUtil.cardNum(owner.drawCard, owner.cardInhand) >= 2) {
			card = 0;
		}
		 */

		ITObject otherParam = new TObject();
		otherParam.putInt("card", card);
		otherParam.putInt("seat", owner.room.activeSeat);
		otherParam.putInt("left_count", leftCount);
		owner.room.broadCastToClient(owner.playerid, Config.GAME_EVT_DRAW, otherParam);

		EXMainServer.playerRuleMgr.conditionEx(PlayerRuleManager.TI_RULE, owner);
		if (owner.drawCard != 0 && tempStep == room.step) {
			this.toNextState(owner);
		}
	}

	private boolean IsGoodCard(EXPlayer player, int drawCard) {
		if (Paixing.checkWin((EXPlayer) player, drawCard, true)) {
			return true;
		}

		for (int i = 0; i < player.kanGroup.size(); i++) {
			if (drawCard == player.kanGroup.get(i)[0]) {
				return true;
			}
		}

		for (int i = 0; i < player.weiGroup.size(); i++) {
			if (drawCard == player.weiGroup.get(i)[0]) {
				return true;
			}
		}

		if (CardUtil.cardNum(drawCard, player.cardInhand) >= 2)
		{
			return true;
		}

		return false;
	}

	private boolean IsGoodCard2(EXPlayer player, int drawCard) {
		if (Paixing.checkWin((EXPlayer) player, drawCard, true)) {
			return true;
		}

		if (CardUtil.cardNum(drawCard, player.cardInhand) >= 2)
		{
			return true;
		}

		return false;
	}

	@Override
	public void toNextState(EXPlayer owner) {
		if (!owner.getRoom().isAllPass) {
			EXMainServer.playerRuleMgr.conditionEx(PlayerRuleManager.DRAW_RULE, owner);
			owner.room.broadCastToServer(owner.playerid, EXActionEvent.EVENT_OTHER_DRAW, null);
			if (owner.getRoom().tipMap.size() != 0) {
				for (Map.Entry<Integer, Player> entry : owner.getRoom().playerMapBySeat.entrySet()) {
					EXPlayer player = (EXPlayer) entry.getValue();
					if (player.isDiHu)
					{
						if (owner.getRoom().tipMap.containsKey(player.playerid))
						{
						    if (player.tipMgr.getTip(RuleWeight.TYPE_WIN) == null)
							{
								player.isDiHu = false;
							}
						}
						else {
							player.isDiHu = false;
						}
					}
				}
				if (!(owner.stateMachine.curState instanceof EXPlayerDrawTipState)) {
					owner.stateMachine.changeState(Global.getState(PlayerPauseState.class));
				}
				return;
			}
		}
		
		int tempStep = owner.getRoom().step;
		for (Map.Entry<Integer, Player> entry : owner.getRoom().playerMapBySeat.entrySet()) {
			EXPlayer player = (EXPlayer) entry.getValue();
			if (player != null)
			{
				player.isDiHu = false;
			}
		}

		//EXMainServer.playerRuleMgr.conditionEx(PlayerRuleManager.DRAW_PAO_RULE, owner);
		//owner.room.broadCastToServer(owner.playerid, EXActionEvent.EVENT_OTHER_PAO, null);

		if (owner.drawCard != 0 && tempStep == owner.getRoom().step) {

			timer(owner);
		}
	}

	public static void timer(EXPlayer owner) {
		if (owner.getRoom().card.getCount() == 0) {
			owner.getRoom().liuju = true;
			owner.getRoom().liujuNum++;
			owner.getRoom().endGame();
			return;
		}
		if (owner.getRoom().isAllPass) {
			ITObject param = new TObject();
			param.putInt("card", owner.drawCard);
			param.putInt("seat", owner.seat);
			owner.room.broadCastToClient(0, Config.GAME_EVT_THROW_CARD, param);
			owner.outcardList.add(owner.drawCard);
			owner.getRoom().throwCardsSet.add(owner.drawCard);
			owner.getRoom().getPlayBack().addThrowCardCommand(owner.seat, owner.drawCard);

			owner.drawCard = 0;
			owner.stateMachine.changeState(Global.getState(PlayerWaitState.class));
			owner.room.stateMachine.changeState(Global.getState(EXRoomSetpState.class));
		} else {
			TPServer.me().getTimerPool().schedule(new Runnable() {
				@Override
				public void run() {
					if (owner.room == null) {
						Global.logger.error("EXPlayerDrawState room is null");
						return;
					}
					if (owner.room.isDestroy)
						return;
					owner.room.enqueueRunnable(new Runnable() {
						@Override
						public void run() {
							if(owner.drawCard != 0) {
								ITObject param = new TObject();
								param.putInt("card", owner.drawCard);
								param.putInt("seat", owner.seat);
								owner.room.broadCastToClient(0, Config.GAME_EVT_THROW_CARD, param);
								owner.outcardList.add(owner.drawCard);
								owner.getRoom().throwCardsSet.add(owner.drawCard);
								owner.getRoom().getPlayBack().addThrowCardCommand(owner.seat, owner.drawCard);
	
								owner.drawCard = 0;
								owner.stateMachine.changeState(Global.getState(PlayerWaitState.class));
								owner.room.stateMachine.changeState(Global.getState(EXRoomSetpState.class));
							}
						}
					});
				}
			}, 1, TimeUnit.SECONDS);
		}
	}
}
