package teen

import (
	"encoding/json"
	"math/rand"
	"os"
	"server/game/room"
	"server/msg"
	"sort"
	"sync"

	"github.com/name5566/leaf/log"
)

// 全局房间存储
var roomStorage = map[string]*room.Room{}
var mu sync.Mutex // 用于保护房间存储的并发访问

type TeenPattiRoom struct {
	Boot         string `json:"boot"`
	MinBuyin     string `json:"minBuyin"`
	ChaalLimmit  string `json:"chaalLimmit"`
	PotLimit     string `json:"potLimit"`
	TotalPlayers string `json:"totalPlayers"`
	RoomLevel    string `json:"roomLevel"`
	ConfId       string `json:"ConfId"`
	Type         string `json:"type"`
}

var GameConfig struct {
	GameId    string          `json:"game_id"`
	Name      string          `json:"name"`
	Status    int             `json:"status"`
	RoomList  []TeenPattiRoom `json:"room_list"`
	ThinkTime int             `json:"think_time"`
}

// var Teen_Patti_Room = &room.Room{
// 	Id:      "teen_patti",
// 	Players: make([]*player.Player, 0),
// 	Status:  1,
// }

var SelfSitPos int32 = 4

// 定义玩家手牌的类型
type CardType int

const (
	CardTypeThreeOfAKind  CardType = 0 //三条
	CardTypeFlushStraight CardType = 1 // 同花顺
	CardTypeStraight      CardType = 2 // 同花顺
	CardTypeFlush         CardType = 3 // 同花
	CardTypePair          CardType = 4 // 对子
	CardTypeSingle        CardType = 5 // 散牌
)

func InitGame() {

}
func init() {
	data, err := os.ReadFile("../../bin/gamedata/teen_patti_conf.json")
	if err != nil {
		log.Fatal("%v", err)
	}
	err = json.Unmarshal(data, &GameConfig)
	if err != nil {
		log.Fatal("%v", err)
	}

	go handleEvents()
}

/* 完整的52张牌映射：
黑桃(0):
    i=0:  ♠A  (Color=0, Point=1)
    i=1:  ♠2  (Color=0, Point=2)
    i=2:  ♠3  (Color=0, Point=3)
    ...
    i=10: ♠J  (Color=0, Point=11)
    i=11: ♠Q  (Color=0, Point=12)
    i=12: ♠K  (Color=0, Point=13)

红桃(1):
    i=13: ♥A  (Color=1, Point=1)
    i=14: ♥2  (Color=1, Point=2)
    i=15: ♥3  (Color=1, Point=3)
    ...
    i=23: ♥J  (Color=1, Point=11)
    i=24: ♥Q  (Color=1, Point=12)
    i=25: ♥K  (Color=1, Point=13)

梅花(2):
    i=26: ♣A  (Color=2, Point=1)
    i=27: ♣2  (Color=2, Point=2)
    i=28: ♣3  (Color=2, Point=3)
    ...
    i=36: ♣J  (Color=2, Point=11)
    i=37: ♣Q  (Color=2, Point=12)
    i=38: ♣K  (Color=2, Point=13)

方块(3):
    i=39: ♦A  (Color=3, Point=1)
    i=40: ♦2  (Color=3, Point=2)
    i=41: ♦3  (Color=3, Point=3)
    ...
    i=49: ♦J  (Color=3, Point=11)
    i=50: ♦Q  (Color=3, Point=12)
    i=51: ♦K  (Color=3, Point=13)
*/
// 初始化房间的卡牌
func initCardDeck(c_room *room.Room) {
	// 创建长度为52的切片
	cards := make([]*msg.ReqCard, 52)

	// 初始化卡牌
	for i := 0; i < 52; i++ {
		point := int32(i%13 + 1) // 计算点数
		if point == 1 {          // A（Ace）从 1 改成 14
			point = 14
		}
		cards[i] = &msg.ReqCard{
			Color: int32(i / 13), // 计算花色
			Point: point,         // 计算点数
		}
	}
	// 赋值给房间
	c_room.CardDeck = cards
}

// func initCardDeck(c_room *room.Room) {
// 	// 创建长度为52的切片
// 	cards := make([]*msg.ReqCard, 52)

// 	// 初始化卡牌
// 	for i := 0; i < 52; i++ {
// 		cards[i] = &msg.ReqCard{
// 			Color: int32(i / 13),
// 			Point: int32(i%13 + 1),
// 		}
// 	}
// 	// 赋值给房间
// 	c_room.CardDeck = cards
// }

// 洗牌
func shuffleCardDeck(deck []*msg.ReqCard) {
	rand.Shuffle(len(deck), func(i, j int) {
		deck[i], deck[j] = deck[j], deck[i]
	})
}

// 计算一个玩家的手牌的类型，按照三条>同花顺>顺子>同花>对子>散牌的顺序
func calculateCardType(cards []*msg.ReqCard) CardType {
	// 先判断是否是同花顺
	isThreeOfAKind := isThreeOfAKind(cards)
	isFlush := isFlush(cards)
	// 判断是否是三条
	if isThreeOfAKind {
		return CardTypeThreeOfAKind
	}
	isStraight := isStraight(cards)
	if isFlush && isStraight {
		return CardTypeFlushStraight
	}
	// 判断是否是顺子
	if isStraight {
		return CardTypeStraight
	}
	// 判断是否是同花
	if isFlush {
		return CardTypeFlush
	}

	// 判断是否是对子
	isPair := isPair(cards)
	if isPair {
		return CardTypePair
	}

	// 散牌
	return CardTypeSingle
}

// 判断是否是同花（三张牌花色相同）
func isFlush(cards []*msg.ReqCard) bool {
	if len(cards) != 3 {
		return false
	}
	return cards[0].Color == cards[1].Color && cards[1].Color == cards[2].Color
}

// 判断是否是三条（三张相同点数）
func isThreeOfAKind(cards []*msg.ReqCard) bool {
	if len(cards) != 3 {
		return false
	}
	return cards[0].Point == cards[1].Point && cards[1].Point == cards[2].Point
}

// 判断是否是顺子（三张牌点数连续）
func isStraight(cards []*msg.ReqCard) bool {
	if len(cards) != 3 {
		return false
	}

	// 复制一个新的切片用于排序
	points := make([]int32, 3)
	for i, card := range cards {
		points[i] = card.Point
	}

	// 排序
	sort.Slice(points, func(i, j int) bool {
		return points[i] < points[j]
	})

	// 特殊情况：A,2,3
	if points[0] == 1 && points[1] == 2 && points[2] == 3 {
		return true
	}

	// 特殊情况：Q,K,A
	if points[0] == 1 && points[1] == 12 && points[2] == 13 {
		return true
	}

	// 普通情况：判断是否连续
	return points[1] == points[0]+1 && points[2] == points[1]+1
}

// 判断是否是对子（三张牌中有两张点数相同）
func isPair(cards []*msg.ReqCard) bool {
	if len(cards) != 3 {
		return false
	}

	return cards[0].Point == cards[1].Point ||
		cards[1].Point == cards[2].Point ||
		cards[0].Point == cards[2].Point
}

// 返回玩家列表里最大的玩家
func compareCards(players []*room.Player) *room.Player {
	if len(players) == 0 {
		return nil
	}

	// 找到第一个没有弃牌的玩家作为基准
	maxPlayer := players[0]
	for _, p := range players {
		if !p.IsPacked {
			maxPlayer = p
			break
		}
	}

	// 如果所有玩家都弃牌了
	if maxPlayer.IsPacked {
		return nil
	}

	// 遍历所有玩家，找出最大的
	for _, player := range players {
		// 跳过已弃牌的玩家
		if player.IsPacked || player == maxPlayer {
			continue
		}

		cards1 := maxPlayer.HandCards
		cards2 := player.HandCards

		cardType1 := calculateCardType(cards1)
		cardType2 := calculateCardType(cards2)
		// 处理A=14 ,并且把cards从大到小排序
		sortCardsByPoint(cards1)
		for _, card := range cards1 {
			log.Debug("cards1---:Point: %d, Color: %d\n", card.Point, card.Color)
		}
		sortCardsByPoint(cards2)
		for _, card := range cards2 {
			log.Debug("cards2---: Point: %d, Color: %d\n", card.Point, card.Color)
		}
		// 如果牌型不同
		if cardType1 != cardType2 {
			// CardType 数字越小牌型越大
			if cardType2 < cardType1 {
				maxPlayer = player
			}
			continue
		}
		// 如果牌型相同,先确认是什么类型的牌
		switch cardType1 {
		//三条
		case 0:
			res := compareThreeOfAKind(cards1, cards2)
			if res == 0 {
				maxPlayer = player
			}
		//同花顺
		case 1:
			res := compareStraightFlush(cards1, cards2)
			if res == 0 {
				maxPlayer = player
			}
		//顺子
		case 2:
			log.Debug("对子终于来了")
			res := compareStraight(cards1, cards2)
			log.Debug("结果", res)
			if res == 0 {
				maxPlayer = player
			}
		//同花
		case 3:
			res := compareFlush(cards1, cards2)
			if res == 0 {
				maxPlayer = player
			}
		//对子
		case 4:
			res := comparePair(cards1, cards2)
			if res == 0 {
				maxPlayer = player
			}
		//高牌
		case 5:
			res := compareSingle(cards1, cards2)
			if res == 0 {
				maxPlayer = player
			}
		}

	}

	return maxPlayer
}

// valueToInt 映射点数，处理A为最大牌（14）
func valueToInt(value int32) int32 {
	// A (1) 作为最大牌，转换为 14
	if value == 1 {
		return 14
	}
	return value
}

// 排序：先按点数从大到小排序
func sortCardsByPoint(cards []*msg.ReqCard) {
	// 先把A转换为14，然后按点数从大到小排序
	sort.Slice(cards, func(i, j int) bool {
		// 转换点数（如果是A，将其视为14）
		pointI := valueToInt(cards[i].Point)
		pointJ := valueToInt(cards[j].Point)
		// 如果点数相同，按花色排序（从小到大）
		if pointI == pointJ {
			return cards[i].Color < cards[j].Color
		}
		// 按点数从大到小排序
		return pointI > pointJ
	})
	// 排序完成后，更新所有 A 的点数为 14
	for _, card := range cards {
		if card.Point == 1 {
			card.Point = 14
		}
	}
}

// 比较三条的大小
func compareThreeOfAKind(cards1, cards2 []*msg.ReqCard) int {
	// 比较三条的点数（这里需要特别处理 A）
	val1 := cards1[0].Point
	val2 := cards2[0].Point

	// 比较点数
	if val1 > val2 {
		return 1 // cards1更大
	} else {
		return 0 // cards2更大
	}
}

// 比较同花顺的大小
func compareStraightFlush(cards1, cards2 []*msg.ReqCard) int {

	// 比较最小的牌（最后一张牌，即最大点数）
	max1 := cards1[2].Point // 排序后第三张牌是最大牌
	max2 := cards2[2].Point
	if max1 > max2 {
		return 1 // cards1更大
	} else if max1 < max2 {
		return 0 // cards2更大
	}
	// 如果最小牌相同，则比较花色
	if cards1[2].Color > cards2[2].Color {
		return 1 // cards1更大
	} else {
		return 0 // cards2更大
	}
}

// 顺子
func compareStraight(cards1, cards2 []*msg.ReqCard) int {
	// 比较最大的牌
	max1 := cards1[0].Point // 排序后第三张牌是最大牌
	max2 := cards2[0].Point
	if max1 > max2 {
		return 1 // cards1更大
	} else if max1 < max2 {
		return 0 // cards2更大
	}
	// 如果最大牌相同，则比较花色
	if cards1[0].Color > cards2[0].Color {
		return 1 // cards1更大
	} else {
		return 0 // cards2更大
	}
}

// 同花
func compareFlush(cards1, cards2 []*msg.ReqCard) int {
	// 比较最大的牌
	max1 := cards1[0].Point // 排序后第三张牌是最大牌
	max2 := cards2[0].Point
	if max1 > max2 {
		return 1 // cards1更大
	} else if max1 < max2 {
		return 0 // cards2更大
	}
	// 比较第二大的牌
	max1 = cards1[1].Point // 排序后第三张牌是最大牌
	max2 = cards2[1].Point
	if max1 > max2 {
		return 1 // cards1更大
	} else if max1 < max2 {
		return 0 // cards2更大
	}
	// 比较第三大的牌
	max1 = cards1[2].Point // 排序后第三张牌是最大牌
	max2 = cards2[2].Point
	if max1 > max2 {
		return 1 // cards1更大
	} else if max1 < max2 {
		return 0 // cards2更大
	}

	// 如果相同，则比较最大牌的花色
	if cards1[0].Color > cards2[0].Color {
		return 1 // cards1更大
	} else {
		return 0 // cards2更大
	}
}

// 对子
func comparePair(cards1, cards2 []*msg.ReqCard) int {
	var pairCardColor1, pairCardColor2 int32 // 声明花色变量
	// 第二张牌一定是对子的其中一张
	// 先判断对子大小, 如果相同,就判断剩余两张的点数加起来
	// 直接比较第二张牌（即对子）
	pair1 := cards1[1].Point
	pair2 := cards2[1].Point

	// 比较对子大小
	if pair1 > pair2 {
		return 1 // cards1的对子更大
	} else if pair1 < pair2 {
		return 0 // cards2的对子更大
	}

	// 对子相同，比较另外两张牌的点数之和
	remaining1 := cards1[0].Point + cards1[2].Point
	remaining2 := cards2[0].Point + cards2[2].Point

	if remaining1 > remaining2 {
		return 1 // cards1的剩余点数更大
	} else if remaining1 < remaining2 {
		return 0 // cards2的剩余点数更大
	}
	// 如果剩余点数相同，比较对子最大牌的花色
	if cards1[0].Point == cards1[1].Point {
		pairCardColor1 = cards1[0].Color
	} else {
		pairCardColor1 = cards1[1].Color
	}

	if cards2[0].Point == cards2[1].Point {
		pairCardColor2 = cards2[0].Color
	} else {
		pairCardColor2 = cards2[1].Color
	}

	// 比较最大对子牌的花色
	if pairCardColor1 > pairCardColor2 {
		return 1 // cards1的对子花色较小
	} else {
		return 0 // cards2的对子花色较小
	}
}

// 高张
func compareSingle(cards1, cards2 []*msg.ReqCard) int {
	// 比较最大的牌
	max1 := cards1[0].Point // 排序后第三张牌是最大牌
	max2 := cards2[0].Point
	if max1 > max2 {
		return 1 // cards1更大
	} else if max1 < max2 {
		return 0 // cards2更大
	}
	// 第二张的牌
	max1 = cards1[1].Point // 排序后第三张牌是最大牌
	max2 = cards2[1].Point
	if max1 > max2 {
		return 1 // cards1更大
	} else if max1 < max2 {
		return 0 // cards2更大
	}
	// 第三大的牌
	max1 = cards1[2].Point // 排序后第三张牌是最大牌
	max2 = cards2[2].Point
	if max1 > max2 {
		return 1 // cards1更大
	} else if max1 < max2 {
		return 0 // cards2更大
	}
	// 如果都想等,就比较最大的花色
	if cards1[0].Color > cards2[0].Color {
		return 1 // cards1更大
	} else {
		return 0 // cards2
	}
}
