package extend.mj.uitl;

import java.util.*;
import java.util.Map.Entry;

import com.game.Util;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;

import extend.mj.Config;
import extend.mj.OpCard;
import extend.mj.RuleWeight;
import extend.mj.WinCardType;



public class Paixing {
	
	private final static boolean qs_yijihua_check(Map<Integer, Integer> cardMap,int se,int index) {
		Integer num = cardMap.get(se+index);
		if(num!=null&&num==1) {
			for(int i=1;i<=9;++i) {
				if(i !=index) {
					if(cardMap.containsKey(se+i)){
						return false;
					}
				}
			}
			return true;
		}
		return false;
	}
	
	public final static void zt_check(Map<Integer, WinCardType> map,List<Integer> cardInhand,ITObject config,int card,Set<Integer> llsCardRecord, int difen) {
		if(config.getBoolean(Config.ROOM_CONFIG_ZT_DASIXI)) {
			if(Util.cardNum(card,cardInhand) >= 3) {
				ITArray opcard4 = new TArray();
				WinCardType wct = putWinCardType(map, RuleWeight.TYPE_DASIXI, 1,1);
				Util.addCard(opcard4, card, 4);
				wct.opcard = opcard4;
				
			}
		} 
		if(config.getBoolean(Config.ROOM_CONFIG_ZT_LIULIUSHUN)) {
			if(!llsCardRecord.contains(card)) {
				if(Util.cardNum(card,cardInhand) >= 2) {
					Map<Integer, Integer> cardMap =Util.getCardNumMap(cardInhand);
					for (Entry<Integer, Integer> entry : cardMap.entrySet()) {
						int t_card = entry.getKey();
						int num = entry.getValue();
						if(num>=3&&t_card!=card&&!llsCardRecord.contains(t_card)) {
							ITArray opcard3 = new TArray();
							Util.addCard(opcard3, card, 3);
							Util.addCard(opcard3, t_card, 3);
							WinCardType wct = putWinCardType(map, RuleWeight.TYPE_LIULIUSHUN, 1,1);
							wct.opcard = opcard3;
							break;
						}
					}
				}
				
			}
		}
	}
	
	public final static void qs_check(Map<Integer, WinCardType> map,List<Integer> cardInhand,ITObject config, int difen){
		Map<Integer, Integer> cardMap =Util.getCardNumMap(cardInhand);
		int card3count=0;
		int card4count=0;
		boolean banban = true;
		ITArray opcard4 = new TArray();
		ITArray opcard3 = new TArray();
		
		Set<Integer> se = new HashSet<Integer>();
		for (Entry<Integer, Integer> entry : cardMap.entrySet()) {
			int card = entry.getKey();
			if (card % 100 == 2 || card % 100 == 5 || card % 100 == 8) {
				banban = false;
			}
			se.add(card/100);
			int num = entry.getValue();
			if(num>=4) {
				Util.addCard(opcard4, card, 4);
				Util.addCard(opcard3, card, 3);
				card4count++;
				card3count++;
			}else if(num>=3) {
				Util.addCard(opcard3, card, 3);
				card3count++;
			}
		}
		if(card4count>0) {
			WinCardType wct = putWinCardType(map, RuleWeight.TYPE_DASIXI, card4count,1);
			wct.opcard = opcard4;
		}
		if(card3count>=2) {
			if(card3count>2 &&card3count %2 !=0){
				opcard3.del(opcard3.size()-1);
				opcard3.del(opcard3.size()-1);
				opcard3.del(opcard3.size()-1);
			}
			WinCardType wct = putWinCardType(map, RuleWeight.TYPE_LIULIUSHUN, card3count/2,1);
			wct.opcard = opcard3;
		}
		if(banban) {
			WinCardType wct = putWinCardType(map, RuleWeight.TYPE_BANBANHU, 1,1);
			wct.opcard = Util.toTArray(cardInhand);
		}
		if(!config.getBoolean(Config.ROOM_CONFIG_QUEYIMEN)&&se.size()<3) {
			WinCardType wct = putWinCardType(map, RuleWeight.TYPE_QUEYISE, 1,1);
			wct.opcard = Util.toTArray(cardInhand);
			
		}
		if(config.getBoolean(Config.ROOM_CONFIG_QS_YIZHIHUA)) {
			int yizhihua_count = 0;
			for(int k=100;k<=300;k+=100) {
				if(qs_yijihua_check(cardMap,k,5)) {
					yizhihua_count ++;
				}
			}
			if(yizhihua_count>0) {
				WinCardType wct = putWinCardType(map, RuleWeight.TYPE_YIZHIHUA, yizhihua_count,1);
				wct.opcard = Util.toTArray(cardInhand);
			}else {
				boolean card_5 = false;
				for (Entry<Integer, Integer> entry : cardMap.entrySet()) {
					int card = entry.getKey();
					if(!card_5 && card % 100 == 5&&entry.getValue() == 1) {
						card_5 = true;
					}else {
						if (card % 100 == 2 || card % 100 == 5 || card % 100 == 8) {
							card_5 = false;
							break;
						}
					}
				}
				if(card_5) {
					WinCardType wct = putWinCardType(map, RuleWeight.TYPE_YIZHIHUA, 1,1);
					wct.opcard = Util.toTArray(cardInhand);
				}
			}
		}
		
		boolean santong_2= false;
		if(config.getBoolean(Config.ROOM_CONFIG_QS_SANTONG)) {
			int santong_count = 0;
			ITArray st_opcard = new TArray();
			for(int i=1;i<=9;++i) {
				if(Util.cardNum(cardMap, 100+i, 2)&&Util.cardNum(cardMap, 200+i, 2)&&Util.cardNum(cardMap, 300+i, 2)) {
					santong_count++;
					Util.addCard(st_opcard, 100+i, 2);
					Util.addCard(st_opcard, 200+i, 2);
					Util.addCard(st_opcard, 300+i, 2);
					if (i == 2)santong_2=true;
				}
			}
			if(santong_count>0) {
				WinCardType wct = putWinCardType(map, RuleWeight.TYPE_SANTONG, santong_count,1);
				wct.opcard = st_opcard;
			}
		}
		
		if(!santong_2&&config.getBoolean(Config.ROOM_CONFIG_QS_JTYN)) {
			if(Util.cardNum(cardMap, 202, 2)&&Util.cardNum(cardMap, 302, 2)) {
				ITArray st_opcard = new TArray();
				Util.addCard(st_opcard, 202, 2);
				Util.addCard(st_opcard, 302, 2);
				WinCardType wct = putWinCardType(map, RuleWeight.TYPE_QTYN, 1,1);
				wct.opcard = st_opcard;
			}
		}
		
		if(config.getBoolean(Config.ROOM_CONFIG_QS_JIEJIEGAO)) {
			int jjg_count = 0;
			ITArray jjg_opcard = new TArray();
			for(int k=100;k<=300;k+=100) {
				for(int i=1;i<=7;++i) {
					if(Util.cardNum(cardMap, k+i, 2)&&Util.cardNum(cardMap, k+i+1, 2)&&Util.cardNum(cardMap, k+i+2, 2)) {
						jjg_count++;
						Util.addCard(jjg_opcard, k+i, 2);
						Util.addCard(jjg_opcard, k+i+1, 2);
						Util.addCard(jjg_opcard, k+i+2, 2);
						i+=2;
					}
				}
			}
			if(jjg_count>0) {
				WinCardType wct = putWinCardType(map, RuleWeight.TYPE_JIEJIEGAO, jjg_count,1);
				wct.opcard = jjg_opcard;
			}
		}
	}
	
	public static void main(String[] args) {
//		List<Integer> cardInhand = new java.util.ArrayList<>();
//		List<OpCard> opCards = new java.util.ArrayList<>();
//		opCards.add(new OpCard(RuleWeight.TYPE_PONG, 109));
//		opCards.add(new OpCard(RuleWeight.TYPE_PONG, 209));
//		cardInhand.add(106);
//		cardInhand.add(106);
//		cardInhand.add(107);
//		cardInhand.add(108);
////		cardInhand.add(109);
//		
//		
//		System.out.println(tingKongCheck(opCards,cardInhand, 109));
	}
	
	private final static boolean quanqiuren(List<OpCard> opCards,List<Integer> cardInhand, int drawCard) {
		if (cardInhand.size() > 1) {
			return false;
		}
		if(drawCard == 0)return true;
		if (cardInhand.get(0) != drawCard)
			return false;
		return true;
	}

	private final static boolean qingyise(List<OpCard> opCards, List<Integer> cardInhand, int drawCard) {
		int se = cardInhand.get(0) / 100;
		if (drawCard!=0&&drawCard / 100 != se)
			return false;
		for (OpCard card : opCards) {
			if (se != card.card / 100) {
				return false;
			}
		}
		for (int card : cardInhand) {
			if (se != card / 100) {
				return false;
			}
		}
		return true;
	}
	
	private final static boolean pongpong(List<OpCard> opCards, List<Integer> cardInhand, int drawCard,boolean quanqiuren) {
		for (OpCard card : opCards) {
			if (card.type == RuleWeight.TYPE_CHOW) {
				return false;
			}
		}
		if (quanqiuren)return true;
		
		int card1count=0,card2count=0;
		Map<Integer, Integer> cardMap =Util.getCardNumMap(cardInhand);
		for (Entry<Integer, Integer> entry : cardMap.entrySet()) {
			int card = entry.getKey();
			int num = entry.getValue();
			if(num == 4) return false;
			switch(num) {
			case 1:
				if(card1count>=1)return false;
				if(drawCard!=0&&card != drawCard)return false;
				card1count++;
				break;
			case 2:
				if(card2count >=2)return false;
				card2count ++;
				break;				
			}
		}
		if(card1count>0&&card2count>0)return false;
		if(card1count>0&&drawCard!=0&&!cardMap.containsKey(drawCard))return false;
		if(card2count == 2&&drawCard!=0) {
			if(!cardMap.containsKey(drawCard))return false;
			if(cardMap.get(drawCard)!=2)return false;
		}
		return true;
	}

	private final static boolean jiangjiang(List<OpCard> opCards, List<Integer> cardInhand, int drawCard) {
		if(drawCard!=0){
			if (drawCard % 100 != 2 && drawCard % 100 != 5 && drawCard % 100 != 8) {
				return false;
			}
		}
		for (OpCard card : opCards) {
			if (card.type == RuleWeight.TYPE_CHOW) {
				return false;
			}
			if (card.card % 100 != 2 && card.card % 100 != 5 && card.card % 100 != 8) {
				return false;
			}
		}
		for (int card : cardInhand) {
			if (card % 100 != 2 && card % 100 != 5 && card % 100 != 8) {
				return false;
			}

		}
		return true;
	}

	private final static int qixiaodui(List<OpCard> opCards, List<Integer> cardInhand, int drawCard) {
		if (cardInhand.size() != 13) {
			return -1;
		}
		List<Integer> cardlist = cardInhand;
		int pair = 0;
		int card4count=0;
		Map<Integer, Integer> cardMap =Util.getCardNumMap(cardlist);
		for (Entry<Integer, Integer> entry : cardMap.entrySet()) {
			int num = entry.getValue();
			int card = entry.getKey();
			if (num == 4) {
				pair +=2;
				card4count ++;
			}else if(num >=2) {
				if(num==3&&drawCard!=0&&drawCard != card) {
					return -1;
				}
				pair +=1;
			}else if(num ==1) {
				if(drawCard!=0&&drawCard != card) {
					return -1;
				}
			}
		}
		if(pair<6) return -1;
		if(drawCard ==0)return card4count+1;
		if(!cardMap.containsKey(drawCard)) return -1;
		if(cardMap.get(drawCard) == 3) {
			card4count++;
		}
		return card4count+1;
	}
	
	public final static WinCardType putWinCardType(Map<Integer, WinCardType> map, int type, int value,int score) {
		if (map == null)
			return null;
		if (map.containsKey(type)) {
			WinCardType wct = map.get(type);
			wct.value += value;
			return wct;
		} else {
			WinCardType wct = new WinCardType(type, value,score);
			map.put(type, wct);
			return wct;
		}
	}
	
	public static boolean checkWin(Map<Integer, WinCardType> map, List<OpCard> opCards, List<Integer> cardInhand,int drawCard, int difen) {
		return checkWin(map,opCards,cardInhand,drawCard,true, difen);
	}

	public static boolean checkWin(Map<Integer, WinCardType> map, List<OpCard> opCards, List<Integer> cardInhand,int drawCard,boolean jiang, int difen) {
		int qixiaodui = qixiaodui(opCards,cardInhand, drawCard);
		if (qixiaodui != -1) {
			putWinCardType(map, WinCardType.QIXIAODUI, qixiaodui,WinCardType.WIN_TYPE_SCORE);
			if (qingyise(opCards,cardInhand, drawCard)) {
				putWinCardType(map, WinCardType.QINGYISE, 1,WinCardType.WIN_TYPE_SCORE);
			}
			if (jiangjiang(opCards,cardInhand, drawCard)) {
				putWinCardType(map, WinCardType.JIANGJIANGHU, 1,WinCardType.WIN_TYPE_SCORE);
			}
			return true;
		}
		if (jiangjiang(opCards,cardInhand, drawCard)) {
			putWinCardType(map, WinCardType.JIANGJIANGHU, 1,WinCardType.WIN_TYPE_SCORE);
			boolean _qqr =quanqiuren(opCards,cardInhand, drawCard);
			if (_qqr) {
				putWinCardType(map, WinCardType.QUANQIUREN, 1,WinCardType.WIN_TYPE_SCORE);
			}
			if (pongpong(opCards,cardInhand, drawCard,_qqr)) {
				putWinCardType(map, WinCardType.PENGPENGHU, 1,WinCardType.WIN_TYPE_SCORE);
			}
			return true;
		}
		if (quanqiuren(opCards,cardInhand, drawCard)) {
			putWinCardType(map, WinCardType.QUANQIUREN, 1,WinCardType.WIN_TYPE_SCORE);
			if (qingyise(opCards,cardInhand, drawCard)) {
				putWinCardType(map, WinCardType.QINGYISE, 1,WinCardType.WIN_TYPE_SCORE);
			}
			if (jiangjiang(opCards,cardInhand, drawCard)) {
				putWinCardType(map, WinCardType.JIANGJIANGHU, 1,WinCardType.WIN_TYPE_SCORE);
			}
			if (pongpong(opCards,cardInhand, drawCard,true)) {
				putWinCardType(map, WinCardType.PENGPENGHU, 1,WinCardType.WIN_TYPE_SCORE);
			}
			return true;
		}
		if (pongpong(opCards,cardInhand, drawCard,false)) {
			putWinCardType(map, WinCardType.PENGPENGHU, 1,WinCardType.WIN_TYPE_SCORE);
			if (qingyise(opCards,cardInhand, drawCard)) {
				putWinCardType(map, WinCardType.QINGYISE, 1,WinCardType.WIN_TYPE_SCORE);
			}
			return true;
		}
		if (qingyise(opCards,cardInhand, drawCard)) {
			WinCard win = new WinCard(cardInhand, drawCard);
			win.jiang = false;
			if (win.tryWin()) {
				putWinCardType(map, WinCardType.QINGYISE, 1,WinCardType.WIN_TYPE_SCORE);
				return true;
			}
		} else {
			WinCard win = new WinCard(cardInhand, drawCard);
			win.jiang = jiang;
			if (win.tryWin()) {
				putWinCardType(map, WinCardType.XIAOHU, 1, difen);
				return true;
			}
		}
		return false;
	}
	
	static public boolean tingCheck(List<OpCard> opCards,List<Integer> cardInhand) {
		if(qixiaodui(opCards,cardInhand, 0)!=-1)return true;
		if (quanqiuren(opCards,cardInhand, 0))return true;
		if (jiangjiang(opCards,cardInhand, 0))return true;
		if (pongpong(opCards,cardInhand, 0,false))return true;
		
		if (qingyise(opCards,cardInhand, 0)) {
			WinCard win = new WinCard(cardInhand, 0);
			win.jiang = false;
			return win.tryWin();
		}
		WinCard win = new WinCard(cardInhand, 0);
		return win.tryWin();
	}

	
	static public boolean tingKongCheck(List<OpCard> opCards,List<Integer> cardInhand,int kongCard,boolean jiang) {
		if (quanqiuren(opCards,cardInhand, 0))return true;
		if (jiangjiang(opCards,cardInhand, kongCard))return true;
		if (pongpong(opCards,cardInhand, 0,false))return true;
		if (qingyise(opCards,cardInhand, kongCard)) {
			WinCard win = new WinCard(cardInhand, 0);
			win.jiang = false;
			return win.tryWin();
		}
		WinCard win = new WinCard(cardInhand, 0);
		win.jiang = jiang;
		return win.tryWin();
	}

}
