package com.dong.maxhap.demos.game

import androidx.compose.ui.geometry.Offset

// 象棋棋子类型枚举
enum class ChessPieceType {
    JIANG, SHI, XIANG, MA, CHE, PAO, BING
}

// 棋子颜色枚举
enum class ChessPieceColor {
    RED, BLACK
}

// 象棋棋子数据类
data class ChessPiece(
    val type: ChessPieceType,
    val color: ChessPieceColor,
    val position: Offset // (x, y) 坐标，范围 0-8 (列) 和 0-9 (行)
)

// 象棋游戏状态
data class XiangqiGameState(
    val board: List<List<ChessPiece?>>, // 9x10 棋盘
    val currentPlayer: ChessPieceColor,
    val selectedPiece: Offset?, // 当前选中的棋子位置
    val gameOver: Boolean,
    val winner: ChessPieceColor?
)

// 象棋游戏逻辑类
class XiangqiLogic {
    
    companion object {
        const val BOARD_WIDTH = 9
        const val BOARD_HEIGHT = 10
    }
    
    // 初始化棋盘
    internal fun initializeBoard(): List<List<ChessPiece?>> {
        val board = List(BOARD_HEIGHT) { List<ChessPiece?>(BOARD_WIDTH) { null } }
        val mutableBoard = board.toMutableList().map { it.toMutableList() }
        
        // 初始化红方棋子
        mutableBoard[0][0] = ChessPiece(ChessPieceType.CHE, ChessPieceColor.RED, Offset(0f, 0f))
        mutableBoard[0][1] = ChessPiece(ChessPieceType.MA, ChessPieceColor.RED, Offset(1f, 0f))
        mutableBoard[0][2] = ChessPiece(ChessPieceType.XIANG, ChessPieceColor.RED, Offset(2f, 0f))
        mutableBoard[0][3] = ChessPiece(ChessPieceType.SHI, ChessPieceColor.RED, Offset(3f, 0f))
        mutableBoard[0][4] = ChessPiece(ChessPieceType.JIANG, ChessPieceColor.RED, Offset(4f, 0f))
        mutableBoard[0][5] = ChessPiece(ChessPieceType.SHI, ChessPieceColor.RED, Offset(5f, 0f))
        mutableBoard[0][6] = ChessPiece(ChessPieceType.XIANG, ChessPieceColor.RED, Offset(6f, 0f))
        mutableBoard[0][7] = ChessPiece(ChessPieceType.MA, ChessPieceColor.RED, Offset(7f, 0f))
        mutableBoard[0][8] = ChessPiece(ChessPieceType.CHE, ChessPieceColor.RED, Offset(8f, 0f))
        
        mutableBoard[2][1] = ChessPiece(ChessPieceType.PAO, ChessPieceColor.RED, Offset(1f, 2f))
        mutableBoard[2][7] = ChessPiece(ChessPieceType.PAO, ChessPieceColor.RED, Offset(7f, 2f))
        
        mutableBoard[3][0] = ChessPiece(ChessPieceType.BING, ChessPieceColor.RED, Offset(0f, 3f))
        mutableBoard[3][2] = ChessPiece(ChessPieceType.BING, ChessPieceColor.RED, Offset(2f, 3f))
        mutableBoard[3][4] = ChessPiece(ChessPieceType.BING, ChessPieceColor.RED, Offset(4f, 3f))
        mutableBoard[3][6] = ChessPiece(ChessPieceType.BING, ChessPieceColor.RED, Offset(6f, 3f))
        mutableBoard[3][8] = ChessPiece(ChessPieceType.BING, ChessPieceColor.RED, Offset(8f, 3f))
        
        // 初始化黑方棋子
        mutableBoard[9][0] = ChessPiece(ChessPieceType.CHE, ChessPieceColor.BLACK, Offset(0f, 9f))
        mutableBoard[9][1] = ChessPiece(ChessPieceType.MA, ChessPieceColor.BLACK, Offset(1f, 9f))
        mutableBoard[9][2] = ChessPiece(ChessPieceType.XIANG, ChessPieceColor.BLACK, Offset(2f, 9f))
        mutableBoard[9][3] = ChessPiece(ChessPieceType.SHI, ChessPieceColor.BLACK, Offset(3f, 9f))
        mutableBoard[9][4] = ChessPiece(ChessPieceType.JIANG, ChessPieceColor.BLACK, Offset(4f, 9f))
        mutableBoard[9][5] = ChessPiece(ChessPieceType.SHI, ChessPieceColor.BLACK, Offset(5f, 9f))
        mutableBoard[9][6] = ChessPiece(ChessPieceType.XIANG, ChessPieceColor.BLACK, Offset(6f, 9f))
        mutableBoard[9][7] = ChessPiece(ChessPieceType.MA, ChessPieceColor.BLACK, Offset(7f, 9f))
        mutableBoard[9][8] = ChessPiece(ChessPieceType.CHE, ChessPieceColor.BLACK, Offset(8f, 9f))
        
        mutableBoard[7][1] = ChessPiece(ChessPieceType.PAO, ChessPieceColor.BLACK, Offset(1f, 7f))
        mutableBoard[7][7] = ChessPiece(ChessPieceType.PAO, ChessPieceColor.BLACK, Offset(7f, 7f))
        
        mutableBoard[6][0] = ChessPiece(ChessPieceType.BING, ChessPieceColor.BLACK, Offset(0f, 6f))
        mutableBoard[6][2] = ChessPiece(ChessPieceType.BING, ChessPieceColor.BLACK, Offset(2f, 6f))
        mutableBoard[6][4] = ChessPiece(ChessPieceType.BING, ChessPieceColor.BLACK, Offset(4f, 6f))
        mutableBoard[6][6] = ChessPiece(ChessPieceType.BING, ChessPieceColor.BLACK, Offset(6f, 6f))
        mutableBoard[6][8] = ChessPiece(ChessPieceType.BING, ChessPieceColor.BLACK, Offset(8f, 6f))
        
        return mutableBoard.map { it.toList() }
    }
    
    // 初始化游戏状态
    internal fun initializeGame(): XiangqiGameState {
        return XiangqiGameState(
            board = initializeBoard(),
            currentPlayer = ChessPieceColor.RED,
            selectedPiece = null,
            gameOver = false,
            winner = null
        )
    }
    
    // 检查移动是否合法
    internal fun isValidMove(
        board: List<List<ChessPiece?>>,
        from: Offset,
        to: Offset,
        playerColor: ChessPieceColor
    ): Boolean {
        val piece = board[from.y.toInt()][from.x.toInt()] ?: return false
        if (piece.color != playerColor) return false
        if (to.x < 0 || to.x >= BOARD_WIDTH || to.y < 0 || to.y >= BOARD_HEIGHT) return false
        
        val targetPiece = board[to.y.toInt()][to.x.toInt()]
        if (targetPiece?.color == playerColor) return false // 不能吃自己的棋子
        
        return isValidPieceMove(board, piece, from, to)
    }
    
    // 检查特定棋子的移动规则
    private fun isValidPieceMove(
        board: List<List<ChessPiece?>>,
        piece: ChessPiece,
        from: Offset,
        to: Offset
    ): Boolean {
        val dx = (to.x - from.x).toInt()
        val dy = (to.y - from.y).toInt()
        val absDx = kotlin.math.abs(dx)
        val absDy = kotlin.math.abs(dy)
        
        return when (piece.type) {
            ChessPieceType.JIANG -> {
                // 帅/将只能在九宫格内移动一格
                absDx <= 1 && absDy <= 1 && isInPalace(to, piece.color)
            }
            ChessPieceType.SHI -> {
                // 士只能斜着走一格，且在九宫格内
                absDx == 1 && absDy == 1 && isInPalace(to, piece.color)
            }
            ChessPieceType.XIANG -> {
                // 象走田字，不能过河，且不能蹩脚
                absDx == 2 && absDy == 2 && 
                !isBlockedByRiver(to, piece.color) &&
                !isElephantLegBlocked(board, from, to)
            }
            ChessPieceType.MA -> {
                // 马走日字，不能蹩马腿
                (absDx == 2 && absDy == 1) || (absDx == 1 && absDy == 2) &&
                !isKnightLegBlocked(board, from, to)
            }
            ChessPieceType.CHE -> {
                // 车直线移动，路径不能有阻挡
                (dx == 0 || dy == 0) && !isPathBlocked(board, from, to)
            }
            ChessPieceType.PAO -> {
                // 炮直线移动，吃子时需要隔一个棋子
                (dx == 0 || dy == 0) && isValidCannonMove(board, from, to)
            }
            ChessPieceType.BING -> {
                // 兵/卒只能向前走一格，过河后可以横向移动
                isValidSoldierMove(piece, from, to)
            }
        }
    }
    
    // 检查是否在九宫格内
    private fun isInPalace(position: Offset, color: ChessPieceColor): Boolean {
        val x = position.x.toInt()
        val y = position.y.toInt()
        return when (color) {
            ChessPieceColor.RED -> x in 3..5 && y in 0..2
            ChessPieceColor.BLACK -> x in 3..5 && y in 7..9
        }
    }
    
    // 检查是否被河阻挡（象的限制）
    private fun isBlockedByRiver(position: Offset, color: ChessPieceColor): Boolean {
        val y = position.y.toInt()
        return when (color) {
            ChessPieceColor.RED -> y > 4
            ChessPieceColor.BLACK -> y < 5
        }
    }
    
    // 检查象腿是否被蹩住
    private fun isElephantLegBlocked(board: List<List<ChessPiece?>>, from: Offset, to: Offset): Boolean {
        val legX = (from.x + to.x) / 2
        val legY = (from.y + to.y) / 2
        return board[legY.toInt()][legX.toInt()] != null
    }
    
    // 检查马腿是否被蹩住
    private fun isKnightLegBlocked(board: List<List<ChessPiece?>>, from: Offset, to: Offset): Boolean {
        val dx = (to.x - from.x).toInt()
        val dy = (to.y - from.y).toInt()
        
        val legX = from.x + if (kotlin.math.abs(dx) == 2) dx/2 else 0
        val legY = from.y + if (kotlin.math.abs(dy) == 2) dy/2 else 0
        
        return board[legY.toInt()][legX.toInt()] != null
    }
    
    // 检查车的路径是否被阻挡
    private fun isPathBlocked(board: List<List<ChessPiece?>>, from: Offset, to: Offset): Boolean {
        val dx = (to.x - from.x).toInt()
        val dy = (to.y - from.y).toInt()
        
        val stepX = if (dx > 0) 1 else if (dx < 0) -1 else 0
        val stepY = if (dy > 0) 1 else if (dy < 0) -1 else 0
        
        var x = from.x.toInt() + stepX
        var y = from.y.toInt() + stepY
        
        while (x != to.x.toInt() || y != to.y.toInt()) {
            if (board[y][x] != null) return true
            x += stepX
            y += stepY
        }
        return false
    }
    
    // 检查炮的移动是否合法
    private fun isValidCannonMove(board: List<List<ChessPiece?>>, from: Offset, to: Offset): Boolean {
        val pathBlocked = isPathBlocked(board, from, to)
        val targetPiece = board[to.y.toInt()][to.x.toInt()]
        
        // 如果目标位置有棋子，必须路上恰好有一个棋子才能吃掉
        // 如果目标位置无棋子，路上不能有棋子才能移动
        return if (targetPiece != null) {
            pathBlocked && countPiecesBetween(board, from, to) == 1
        } else {
            !pathBlocked
        }
    }
    
    // 计算两点之间有多少个棋子
    private fun countPiecesBetween(board: List<List<ChessPiece?>>, from: Offset, to: Offset): Int {
        var count = 0
        val dx = (to.x - from.x).toInt()
        val dy = (to.y - from.y).toInt()
        
        val stepX = if (dx > 0) 1 else if (dx < 0) -1 else 0
        val stepY = if (dy > 0) 1 else if (dy < 0) -1 else 0
        
        var x = from.x.toInt() + stepX
        var y = from.y.toInt() + stepY
        
        while (x != to.x.toInt() || y != to.y.toInt()) {
            if (board[y][x] != null) count++
            x += stepX
            y += stepY
        }
        return count
    }
    
    // 检查兵/卒的移动是否合法
    private fun isValidSoldierMove(piece: ChessPiece, from: Offset, to: Offset): Boolean {
        val dx = (to.x - from.x).toInt()
        val dy = (to.y - from.y).toInt()
        
        return when (piece.color) {
            ChessPieceColor.RED -> {
                if (from.y.toInt() < 5) {
                    // 未过河：只能向前走
                    dx == 0 && dy == 1
                } else {
                    // 已过河：可以向前或横向走
                    (dx == 0 && dy == 1) || (dy == 0 && kotlin.math.abs(dx) == 1)
                }
            }
            ChessPieceColor.BLACK -> {
                if (from.y.toInt() > 4) {
                    // 未过河：只能向前走
                    dx == 0 && dy == -1
                } else {
                    // 已过河：可以向前或横向走
                    (dx == 0 && dy == -1) || (dy == 0 && kotlin.math.abs(dx) == 1)
                }
            }
        }
    }
    
    // 执行移动
    internal fun makeMove(state: XiangqiGameState, from: Offset, to: Offset): XiangqiGameState {
        if (!isValidMove(state.board, from, to, state.currentPlayer)) {
            return state
        }
        
        val newBoard = state.board.toMutableList().map { it.toMutableList() }
        val piece = newBoard[from.y.toInt()][from.x.toInt()]!!
        val newPosition = piece.copy(position = to)
        
        newBoard[from.y.toInt()][from.x.toInt()] = null
        newBoard[to.y.toInt()][to.x.toInt()] = newPosition
        
        val winner = checkWinner(newBoard)
        val gameOver = winner != null
        
        return state.copy(
            board = newBoard.map { it.toList() },
            currentPlayer = if (state.currentPlayer == ChessPieceColor.RED) ChessPieceColor.BLACK else ChessPieceColor.RED,
            selectedPiece = null,
            gameOver = gameOver,
            winner = winner
        )
    }
    
    // 检查是否有赢家
    private fun checkWinner(board: List<List<ChessPiece?>>): ChessPieceColor? {
        var redJiangExists = false
        var blackJiangExists = false
        
        for (row in board) {
            for (piece in row) {
                if (piece?.type == ChessPieceType.JIANG) {
                    when (piece.color) {
                        ChessPieceColor.RED -> redJiangExists = true
                        ChessPieceColor.BLACK -> blackJiangExists = true
                    }
                }
            }
        }
        
        return when {
            !redJiangExists -> ChessPieceColor.BLACK
            !blackJiangExists -> ChessPieceColor.RED
            else -> null
        }
    }
    
    // 选择棋子
    internal fun selectPiece(state: XiangqiGameState, position: Offset): XiangqiGameState {
        val piece = state.board[position.y.toInt()][position.x.toInt()]
        
        // 如果点击的是己方棋子，选中它
        if (piece?.color == state.currentPlayer) {
            return state.copy(selectedPiece = position)
        }
        
        // 如果已有选中的棋子，尝试移动
        if (state.selectedPiece != null) {
            return makeMove(state, state.selectedPiece, position)
        }
        
        return state
    }
    
    // 取消选择
    internal fun deselectPiece(state: XiangqiGameState): XiangqiGameState {
        return state.copy(selectedPiece = null)
    }
    
    // 重新开始游戏
    internal fun restartGame(): XiangqiGameState {
        return initializeGame()
    }
}