package extend.pk;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

import com.game.Constant;
import com.game.GameController;
import com.game.Global;
import com.game.data.Player;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.routes.ActionKey;
import com.taurus.core.util.Logger;
import com.taurus.permanent.data.Session;

import extend.pk.uitl.CardUtil;

/**
 * 
 * 
 */
public class EXGameController extends GameController {
	Logger logger = Logger.getLogger(getClass());

	public EXGameController() {
		super();
	}

	@ActionKey(Config.GAME_DIS_CARD)
	public void RouterDisCard(Session sender, ITObject params, int gid, Player owner) {
		owner.stateMachine.execute(EXActionEvent.EVENT_DISCARD, 0, params);
	}

	@ActionKey(Config.GAME_DIS_PASS)
	public void RouterDisPass(Session sender, ITObject params, int gid, Player owner) {
		owner.stateMachine.execute(EXActionEvent.EVENT_PASS, 0, params);

	}

	@ActionKey(Config.GAME_NIAO)
	public void RouterDaniao(Session sender, ITObject params, int gid, Player owner) {
		owner.stateMachine.execute(EXActionEvent.EVENT_DA_NIAO, 0, params);

	}

	/**
	 * @param owner
	 */
	public void daNiaoTipEvent(EXPlayer owner, int reload) {
		ITObject response = new TObject();
		response.putInt("niao", owner.room.config.getInt(Config.GAME_DANIAO));
		response.putInt("reload", reload);
		owner.sendEvent(Config.GAME_EVT_DANIAO_TIP, response);

//		ITObject param = new TObject();
//		param.putInt("seat", owner.seat);
//		owner.room.broadCastToClient(0, Config.GAME_PLAYER_DANIAO_TIP, param);

	}
	

	/**
	 * @param owner 打鸟事件
	 */
	public void daNiaoEvent(EXPlayer owner) {
		ITObject param = new TObject();
		param.putInt("seat", owner.seat);
		param.putInt("niao", owner.niaoValue);
		param.putInt("daNiao", owner.daNiao);

		owner.room.broadCastToClient(0, Config.GAME_EVT_DANIAO, param);
	}

	@ActionKey(Config.GAME_PIAO)
	public void RouterPiao(Session sender, ITObject params, int gid, Player owner) {
		owner.stateMachine.execute(EXActionEvent.EVENT_PIAO, 0, params);
	}

	// 改变活动玩家
	public void changeActiveSeat(EXRoom owner, int activeSeat) {
		owner.activeSeat = activeSeat;
		ITObject param = new TObject();
		param.putInt("index", activeSeat);
		owner.broadCastToClient(0, Config.GAME_EVT_CHANGE_ACTIVE_PLAYER, param);
	}

	public void sendPutError(EXPlayer owner, int code) {
		ITObject param = new TObject();
		param.putInt("error", code);
		owner.sendEvent(Config.GAME_EVT_PUT_ERROR, param);
	}

	/**
	 * pass
	 * 
	 * @param owner
	 */
	public void pass(EXPlayer owner) {
		EXRoom room = owner.getRoom();
		ITObject response = new TObject();
		response.putInt("seat", owner.seat);
		if (Global.loggerDebug) {
			Global.logger.info(owner + " pass!");
		}
		owner.pass = true;
		owner.last_outcard = null;
		EXPlayBack pb = (EXPlayBack) room.playBackData;
		pb.addPassCommand(owner.seat);
		room.broadCastToClient(0, Config.GAME_EVT_PASS, response);
	}

	/**
	 * 票鸟提示
	 * 
	 * @param owner
	 */
	public void piaoTipEvent(EXPlayer owner, int reload) {

		ITObject response = new TObject();
		response.putInt("piao", owner.room.config.getInt(Config.ROOM_CONFIG_PIAO));
		response.putInt("reload", reload);
		owner.sendEvent(Config.GAME_EVT_PIAO_TIP, response);
	}

	/**
	 * 票鸟事件
	 * 
	 * @param owner
	 */
	public void piaoEvent(EXPlayer owner) {
		if (owner.piao == -1)
			return;

		ITObject param = new TObject();
		param.putInt("seat", owner.seat);
		param.putInt("piao", owner.piao);
		owner.room.broadCastToClient(0, Config.GAME_EVT_PIAO, param);
	}

	public void outCard(EXPlayer owner, CardGroup ct) {
		EXRoom room = owner.getRoom();
		ITObject response = new TObject();
		response.putInt("player", owner.seat);
		response.putTObject("card_obj", ct.toObject(false));

		owner.outCards.addAll(ct.card_list);

		room.lastDiscardSeat = owner.seat;
		room.discard = ct;
		owner.last_outcard = ct;
		owner.pass = false;
		room.firstCard = 0;
		if (Global.loggerDebug) {
			Global.logger.info(owner + " out card:" + ct);
		}
		EXPlayBack pb = (EXPlayBack) room.playBackData;
		pb.addOutCardCommand(owner.seat, ct);
		CardUtil.removeCard(owner.cardInhand, ct.card_list);

		response.putInt("remain", owner.cardInhand.size());
		room.broadCastToClient(0, Config.GAME_EVT_DISCARD, response);

	}

	public void dealCard(EXRoom owner) {
		if (owner.targetCards.size() == 0) {
			owner.card.init();
		}

		int maxDanPai = 0;
		int maxDuizi = 0;
		int maxSanZhang = 0;
		boolean existWhite = false;
		boolean existXingyunhao = false;
		boolean existGeneral = false;
		boolean existBlack = false;
		double white_rate = 0;


		ArrayList<EXPlayer> tmpPlayerList = new ArrayList<>();
		for (Entry<Integer, Player> entry : owner.playerMapBySeat.entrySet()) {
			EXPlayer player = (EXPlayer) entry.getValue();
			tmpPlayerList.add(player);
			Global.logger.info("跑得快："+player.playerid + ",player.black_white_rate:" +
			player.black_white_rate+",player.is_white:"+player.is_white+",white_rate:"+white_rate+",room.white_value:"+owner.white_value);

		}

		Collections.shuffle(tmpPlayerList);


		for (int i = 0; i < tmpPlayerList.size(); i++) {
			EXPlayer player = tmpPlayerList.get(i);

			if (player.is_white) {
				existXingyunhao = true;
			} else {
				if (player.black_white_status == 0) {
					existGeneral = true;
				} else if (player.black_white_status == 1) {
					existBlack = true;
				} else if (player.black_white_status == 2) {
					existWhite = true;
				}
			}
		}

		for (int i = 0; i < tmpPlayerList.size(); i++) {
			EXPlayer player = tmpPlayerList.get(i);

			if (player.is_white) {
				white_rate = 100 - owner.white_value;
				Global.logger.info("dealcards playerid:" + player.playerid + " xingyuhao:" + player.is_white
						+ " white_value:" + owner.white_value);
			} else {
				continue;
			}

			player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value,
					player.black_white_status, player.black_white_rate, player.black_white_rate, 0, 0, 0);


			Collections.sort(player.cardInhand);

			Map<Integer, Integer> playermap = CardUtil.getCardNumMap(player.cardInhand);
			for (Entry<Integer, Integer> card_entry : playermap.entrySet()) {
				int card = card_entry.getKey();
				int num = card_entry.getValue();
				if (card > maxDanPai) {
					maxDanPai = card;
				}

				if (num == 2) {
					if (card > maxDuizi) {
						maxDuizi = card;
					}
				}

				if (num == 3) {
					if (card > maxSanZhang) {
						maxSanZhang = card;
					}
				}
			}
		}

		for (int i = 0; i < tmpPlayerList.size(); i++) {
			EXPlayer player = tmpPlayerList.get(i);

			if (player.is_white) {
				continue;
			} else {
				if (player.black_white_status == 2) {
					white_rate = player.black_white_rate;
					Global.logger
							.info("dealcards playerid:" + player.playerid + " white player:" + player.black_white_rate);
				} else {
					continue;
				}
			}

			if (!existXingyunhao) {
				player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value,
						player.black_white_status, player.black_white_rate, player.black_white_rate, 0, 0, 0);
			} else {
				player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value,
						player.black_white_status, player.black_white_rate, player.black_white_rate, maxDanPai,
						maxDuizi, maxSanZhang);

			}

			Collections.sort(player.cardInhand);

			if (!existXingyunhao && (existGeneral || existBlack)) {
				Map<Integer, Integer> playermap = CardUtil.getCardNumMap(player.cardInhand);
				for (Entry<Integer, Integer> card_entry : playermap.entrySet()) {
					int card = card_entry.getKey();
					int num = card_entry.getValue();
					if (card > maxDanPai) {
						maxDanPai = card;
					}

					if (num == 2) {
						if (card > maxDuizi) {
							maxDuizi = card;
						}
					}

					if (num == 3) {
						if (card > maxSanZhang) {
							maxSanZhang = card;
						}
					}
				}
			}
		}

		for (int i = 0; i < tmpPlayerList.size(); i++) {
			EXPlayer player = tmpPlayerList.get(i);

			if (player.is_white) {
				continue;
			} else {
				if (player.black_white_status == 0) {
					Global.logger.info(
							"dealcards playerid:" + player.playerid + " general player:" + player.black_white_rate);
				} else {
					continue;
				}
			}


			// 指定牌型
//			player.cardInhand = owner.card.deal1(player.seat);
			player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value,
					player.black_white_status, white_rate, white_rate, maxDanPai, maxDuizi, maxSanZhang);


			Collections.sort(player.cardInhand);

			if (!existXingyunhao && !existWhite && existBlack) {
				Map<Integer, Integer> playermap = CardUtil.getCardNumMap(player.cardInhand);
				for (Entry<Integer, Integer> card_entry : playermap.entrySet()) {
					int card = card_entry.getKey();
					int num = card_entry.getValue();
					if (card > maxDanPai) {
						maxDanPai = card;
					}

					if (num == 2) {
						if (card > maxDuizi) {
							maxDuizi = card;
						}
					}

					if (num == 3) {
						if (card > maxSanZhang) {
							maxSanZhang = card;
						}
					}
				}
			}
		}

		for (int i = 0; i < tmpPlayerList.size(); i++) {
			EXPlayer player = tmpPlayerList.get(i);

			if (player.is_white) {
				continue;
			} else {
				if (player.black_white_status == 1) {
					Global.logger.info("dealcards playerid:" + player.playerid + " black player:"
							+ (player.black_white_rate + white_rate));
				} else {
					continue;
				}
			}

			if (!existXingyunhao && !existWhite && !existGeneral) {
				player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value,
						player.black_white_status, player.black_white_rate + white_rate,
						player.black_white_rate + white_rate, 0, 0, 0);
			} else {
				player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value,
						player.black_white_status, player.black_white_rate + white_rate,
						player.black_white_rate + white_rate, maxDanPai, maxDuizi, maxSanZhang);
			}

			Collections.sort(player.cardInhand);
		}

		Global.logger.info("sssss==>" + owner.supCards.size());
		if (owner.targetCards.size() > 0 && owner.adminSeat > 0 && owner.supCards.size() > 0) {
			owner.card.cardList = owner.supCards.get(0);
		}

//		测试牌型
//		for (Entry<Integer, Player> entry : owner.playerMapBySeat.entrySet()) {
//			EXPlayer player = (EXPlayer) entry.getValue();
//			player.cardInhand = owner.card.deal1(player.seat);
//		}

		// 如果是首局，需要确定庄家


		if (owner.bankerSeat == 0) {

			int rule = Config.RULE_RANDOM;
			if (owner.config.containsKey(Config.ROOM_CONFIG_RULE)) {
				rule = owner.config.getInt(Config.ROOM_CONFIG_RULE);
			}

			owner.bankerSeat = this.getBankerSeat(owner);

			this.sendPlayerDeal(owner);
			// 如果是随机确定庄家
			if (rule == Config.RULE_RANDOM) {

				EXPlayer player = (EXPlayer) owner.playerMapBySeat.get(owner.bankerSeat);
				if (player != null) {

					int len = player.cardInhand.size();
					if (len > 0) {
						Random random = new Random();
						int rand_pos = random.nextInt(len);

						this.sendMingPai(owner, player.cardInhand.get(rand_pos).card);
					}
				}
			}
		} else {
			this.sendPlayerDeal(owner);
		}

	}

	/**
	 * 发生随机牌 用于指示谁首先出牌
	 * 
	 * @param owner
	 */
	private void sendMingPai(EXRoom owner, int card) {

		ITObject param = new TObject();
		param.putInt("mingpai", card);

		for (Entry<Integer, Player> entry : owner.playerMapBySeat.entrySet()) {

			EXPlayer exPlayer = (EXPlayer) entry.getValue();
			exPlayer.sendEvent(Config.GAME_EVT_MING_PAI, param);
		}
		;
	}

	/**
	 * 发牌
	 * 
	 * @param owner
	 */
	private void sendPlayerDeal(EXRoom owner) {
		for (Entry<Integer, Player> entry : owner.playerMapBySeat.entrySet()) {
			EXPlayer exPlayer = (EXPlayer) entry.getValue();
			ITObject param = new TObject();
			ITArray handCard = CardUtil.toTArray(exPlayer.cardInhand);
			param.putTArray("cards", handCard);
			param.putInt("bank_seat", exPlayer.room.bankerSeat);
			param.putInt("round", owner.round);
			if (Global.loggerDebug) {
				Global.logger.info(owner + " deal card:" + exPlayer.cardInhand);
			}
			exPlayer.sendEvent(Config.GAME_EVT_PLAYER_DEAL, param);
		}
		;
	}

	private int getBankerSeatByCard(EXRoom owner) {
		for (int index = 3; index <= 13; index++) {
			for (int color = 4; color >= 1; color--) {
				for (Entry<Integer, Player> entry : owner.playerMapBySeat.entrySet()) {
					EXPlayer player = (EXPlayer) entry.getValue();
					for (CardObj card : player.cardInhand) {
						if (card.card == color * 100 + index) {
							owner.firstCard = card.card;
							return player.seat;
						}
					}
				}
			}
		}
		return 0;
	}

	private int getBankerSeat(EXRoom owner) {
		int seat = 0;

		int rule = Config.RULE_RANDOM;
		if (owner.config.containsKey(Config.ROOM_CONFIG_RULE)) {
			rule = owner.config.getInt(Config.ROOM_CONFIG_RULE);
		}
		// 如果是兩人的情況
		if (owner.maxPlayers == 2) {

			// 如果是随机确定庄家
			if (rule == Config.RULE_RANDOM) {
				Random random = new Random();
				seat = random.nextInt(2) + 1;
			}
			// 如果是黑桃3先出
			else {
				seat = getBankerSeatByCard(owner);

				// 如果黑桃3 不在任何一个玩家手里 则随机确定一个庄家
				if (seat == 0) {
					Random random = new Random();
					seat = random.nextInt(2) + 1;
				}
			}
		} else {
			// 如果是随机确定庄家
			if (rule == Config.RULE_RANDOM) {
				Random random = new Random();
				seat = random.nextInt(3) + 1;
			}
			// 如果是黑桃3先出
			else {
				seat = getBankerSeatByCard(owner);

			}
		}
		return seat;
	}

	public void discardTipEvent(EXPlayer owner) {
		ITObject param = new TObject();
		boolean gen = (owner.getRoom().lastDiscardSeat != 0 && owner.getRoom().lastDiscardSeat != owner.seat);
		param.putInt("play", gen ? 1 : 0);
		if (gen) {
			param.putTObject("card_obj", owner.getRoom().discard.toObject(true));

		}
		// 如果可以不出

		owner.sendEvent(Config.GAME_EVT_DISCARD_TIP, param);

	}

	private ITObject getRoomResultData(EXRoom owner, boolean total) {

		ITObject mp = TObject.newInstance();

		EXPlayer win = owner.win;

		ITArray info = new TArray();

		for (Entry<Integer, Player> entry : owner.playerMapById.entrySet()) {
			EXPlayer player = (EXPlayer) entry.getValue();
			ITObject obj = TObject.newInstance();
			obj.putInt("seat", player.seat);

			obj.putInt("score", player.score.total_score);
			obj.putInt("winscore", player.score.round_score);
			float winCardScore = player.winCardScore * player.getRoom().hpData.getInt("times");
			obj.putFloat("winCardScore", winCardScore / 100);
//			Global.logger.info("结算后：player.room.upper_limit_hp:" + player.room.upper_limit_hp);
//			Global.logger.info("结算后：winCardScore:" + winCardScore);
//
//			if (winCardScore > player.room.upper_limit_hp) {
//				obj.putInt("winCardScore", ((int) player.room.upper_limit_hp)/1000);
//			} else if (winCardScore < 0 && Math.abs(winCardScore) > player.room.upper_limit_hp) {
//				obj.putInt("winCardScore", (0 - (int) player.room.upper_limit_hp)/1000);
//			} else {
//				obj.putInt("winCardScore", winCardScore/ 1000);
//			}

			player.winCardScore = 0;
			player.hp_info(obj);
			obj.putInt("thisboomnum", player.boomnum);
			obj.putInt("piao", player.piao);
			obj.putTArray("cards", CardUtil.toTArray(player.cardInhand));
			obj.putBoolean("chuntian", player.chuntian);

			obj.putTArray("handCards", CardUtil.toTArray(player.cardInhand));
			obj.putTArray("outCards", CardUtil.toTArray(player.outCards));

			if (total) {
				if (player.score.total_score > 0) {
					obj.putInt("daniao", player.getRoom().daNiaoScore * player.getRoom().hpData.getInt("times") / 100);
				} else if (player.score.total_score < 0) {
					obj.putInt("daniao",
							0 - player.getRoom().daNiaoScore * player.getRoom().hpData.getInt("times") / 100);
				} else {
					obj.putInt("daniao", 0);

				}

				obj.putInt("award", player.bonusScore);

				if (owner.endType == Constant.END_TYPE_ENTRUST) {
					obj.putInt("entrust", player.entrust ? 1 : 0);
				}
				obj.putTObject("settle_log", player.settleLog.toTObject());
				obj.putInt("total_score", player.score.total_score);

			}
			info.addTObject(obj);
		}

		if (win != null) {
			mp.putInt("winseat", win.seat);
		} else {
			mp.putInt("winseat", 0);
		}
		mp.putTArray("remaincards", CardUtil.toTArray(owner.card.cardList));
		mp.putTArray("info", info);
		mp.putFloat("xipai_score", Float.parseFloat(owner.xi_pai_score + "") / 100);
//		mp.putFloat("xipai_score", owner.xi_pai_score/1000);

		return mp;
	}



	public void roomResult(EXRoom owner) {

		ITObject result = getRoomResultData(owner, false);
		result.putInt("type", 0);
		owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, result);
	}

	/**
	 * 房间大结算
	 * 
	 * @param owner
	 * @param dissmiss
	 */
	public void roomTotalResult(EXRoom owner, boolean dissmiss) {

		ITObject result = getRoomResultData(owner, true);

		long t = System.currentTimeMillis() / 1000;
		result.putLong("time", t);
		result.putInt("type", dissmiss ? 2 : 1);
		owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, result);
	}

}
