package extend.pk;

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.permanent.data.Session;
import extend.pk.uitl.CardUtil;

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

/**
 * 
 * 
 */
public class EXGameController extends GameController {

	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_PIAO)
	public void RouterPiao(Session sender,ITObject params,int gid,Player owner) {
		owner.stateMachine.execute(EXActionEvent.EVENT_PIAO, 0, params);
	}

	@ActionKey(Config.GAME_KAN_FEN)
	public void RouterKanFen(Session sender,ITObject params,int gid,Player owner) {
		EXPlayer player = (EXPlayer) owner;
		player.getRoom().kanFen(player);
	}

	@ActionKey(Config.GAME_EVT_QIANG_ZHUANG)
	public void RouterQiangZhuang(Session sender,ITObject params,int gid,Player owner) {
		owner.stateMachine.execute(EXActionEvent.EVENT_QIANG_ZHUANG, 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();
		if(room.lastDiscardSeat != 0 && room.lastDiscardSeat != owner.seat) {
			EXPlayer lastPlayer = (EXPlayer)room.playerMapBySeat.get(room.lastDiscardSeat);
			if (lastPlayer != null)
			{
				room.add510kScore(lastPlayer);
			}
		}
		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 qiangZhuangTipEvent(EXPlayer owner,int reload) {
		ITObject response = new TObject();
		response.putInt("reload", reload);
		owner.sendEvent(Config.GAME_NOTIFY_QIANG_ZHUANG, 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);
	}

	/**
	 * 票鸟事件
	 * @param owner
	 */
	public void qiangZhuangEvent(EXPlayer owner) {
		ITObject param = new TObject();
		param.putInt("banker_seat", owner.seat);
		owner.room.broadCastToClient(0, Config.GAME_EVT_XIN_ZHUANG_JIA, param);
	}

	public void outCard(EXPlayer owner,CardGroup ct) {
		EXRoom room = owner.getRoom();
		int curPaiFen = 0;
		for(int i = 0; i < ct.card_list.size(); i++)
		{
			CardObj obj = ct.card_list.get(i);
			if (obj.cardMod == 5)
			{
				room.out510KInhand.add(new CardObj(obj.card));
				curPaiFen += 5;
			}
			else if (obj.cardMod == 10 || obj.cardMod == 13)
			{
				room.out510KInhand.add(new CardObj(obj.card));
				curPaiFen += 10;
			}
		}

		room.curPaiFen += curPaiFen;

		if (ct.config.type == Config.TYPE_ZHA)
		{
			if (room.config.getBoolean(Config.WU_ZHANG_SUAN_XI))
			{
				if (ct.card_list.size() >= 5)
				{
					room.addAllXiScore(owner, ct.card_list.size()*10);
				}
			}
			else {
				if (ct.card_list.size() >= 6)
				{
					room.addAllXiScore(owner, ct.card_list.size()*10);
				}
			}
		}


		ITObject response = new TObject();
		response.putInt("player", owner.seat);
		response.putInt("pai_fen", room.curPaiFen);
		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;
		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);
		}

		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;
				}
			}

			if (!existXingyunhao && !existWhite)
			{
				player.cardInhand = owner.card.deal(owner.while_list, player.is_white, owner.white_value,
						player.black_white_status,  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,  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);
		}

		// 如果是首局，需要确定庄家
		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 getBankerSeat(EXRoom owner) {
		int seat = 0;
		
		int rule = Config.RULE_RANDOM;

		//如果是兩人的情況
		if (owner.maxPlayers == 2) {
			// 如果是随机确定庄家
			if(rule == Config.RULE_RANDOM) {
				Random random = new Random();
				seat = random.nextInt(2) + 1;
			}
		} else {
			// 如果是随机确定庄家
			if(rule == Config.RULE_RANDOM) {
				Random random = new Random();
				seat = random.nextInt(3) + 1;
			}
		}
		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.putInt("pass", 1);
		}
		else {
			param.putInt("pass", 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("you_seat", player.you_seat);
			obj.putInt("score", player.score.total_score);
			obj.putInt("winscore", player.score.round_score);
			obj.putInt("zhuascore", player.zhuaScore);
			obj.putInt("xiscore", player.xiScore);
			obj.putInt("huascore", player.huaScore);
			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) {
				obj.putInt("daniao", player.daniaoScore);
				obj.putInt("award", player.bonusScore);

				obj.putInt("one_you", player.one_you);
				obj.putInt("two_you", player.two_you);
				obj.putInt("three_you", player.three_you);
				obj.putInt("four_you", player.four_you);

				obj.putInt("xi_fen_count", player.xi_fen_count);

				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.putInt("xipai_score", owner.xi_pai_score);
		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);
	}

}
