import { defineStore } from 'pinia'
import {
    GAME_PHASE,
    type GameState,
    type PendingClaimState,
} from '../types/state'
import type { PlayerTurnPayload, RoomPlayerUpdatePayload, RoomTrusteePayload } from '../game/actions'
import { readStoredAuth } from '../utils/auth-storage'

import type { Tile } from '../types/tile'

function parseBooleanish(value: unknown): boolean | null {
    if (typeof value === 'boolean') {
        return value
    }
    if (typeof value === 'number') {
        if (value === 1) {
            return true
        }
        if (value === 0) {
            return false
        }
    }
    if (typeof value === 'string') {
        const normalized = value.trim().toLowerCase()
        if (normalized === 'true' || normalized === '1') {
            return true
        }
        if (normalized === 'false' || normalized === '0') {
            return false
        }
    }
    return null
}

export const useGameStore = defineStore('game', {
    state: (): GameState => ({
        roomId: '',

        phase: GAME_PHASE.WAITING,

        dealerIndex: 0,
        currentTurn: 0,
        currentPlayerId: '',
        needDraw: false,

        players: {},

        remainingTiles: 0,

        pendingClaim: undefined,

        winners: [],

        scores: {},

        currentRound: 0,

        totalRounds: 0,
    }),

    actions: {
        resetGame() {
            this.$reset()
        },

        // 初始�?
        initGame(data: GameState) {
            Object.assign(this, data)
        },

        // 摸牌
        onDrawTile(data: { playerId: string; tile: Tile }) {
            const player = this.players[data.playerId]
            if (!player) return

            // 只更新自己的手牌
            if (player.playerId === this.getMyPlayerId()) {
                player.handTiles.push(data.tile)
            }
            player.handCount += 1

            // 剩余牌数减少
            this.remainingTiles = Math.max(0, this.remainingTiles - 1)

            // 更新回合（seatIndex�?
            this.currentTurn = player.seatIndex
            this.currentPlayerId = player.playerId

            // 清除操作窗口
            this.pendingClaim = undefined
            this.needDraw = false

            // 进入出牌阶段
            this.phase = GAME_PHASE.PLAYING
        },

        // 出牌
        onPlayTile(data: {
            playerId: string
            tile: Tile
            nextSeat: number
        }) {
            const player = this.players[data.playerId]
            if (!player) return

            // 如果是自己，移除手牌
            if (player.playerId === this.getMyPlayerId()) {
                const index = player.handTiles.findIndex(
                    (t) => t.id === data.tile.id
                )
                if (index !== -1) {
                    player.handTiles.splice(index, 1)
                }
            }
            player.handCount = Math.max(0, player.handCount - 1)

            // 加入出牌�?
            player.discardTiles.push(data.tile)

            // 更新回合
            this.currentTurn = data.nextSeat
            this.needDraw = true

            // 等待其他玩家响应
            this.phase = GAME_PHASE.ACTION
        },

        // 触发操作窗口（碰/�?胡）
        onPendingClaim(data: PendingClaimState) {
            this.pendingClaim = data
            this.needDraw = false
            this.phase = GAME_PHASE.ACTION
        },

        onRoomPlayerUpdate(payload: RoomPlayerUpdatePayload) {
            if (typeof payload.room_id === 'string' && payload.room_id) {
                this.roomId = payload.room_id
            }

            if (typeof payload.status === 'string' && payload.status) {
                const phaseMap: Record<string, GameState['phase']> = {
                    waiting: GAME_PHASE.WAITING,
                    dealing: GAME_PHASE.DEALING,
                    playing: GAME_PHASE.PLAYING,
                    action: GAME_PHASE.ACTION,
                    settlement: GAME_PHASE.SETTLEMENT,
                }
                this.phase = phaseMap[payload.status] ?? this.phase
            }

            const hasPlayerList =
                Array.isArray(payload.players) || Array.isArray(payload.player_ids)
            if (!hasPlayerList) {
                return
            }

            const nextPlayers: GameState['players'] = {}
            const players = Array.isArray(payload.players) ? payload.players : []
            const playerIds = Array.isArray(payload.player_ids) ? payload.player_ids : []

            players.forEach((raw, index) => {
                const playerId =
                    (typeof raw.PlayerID === 'string' && raw.PlayerID) ||
                    (typeof raw.player_id === 'string' && raw.player_id) ||
                    playerIds[index]
                if (!playerId) {
                    return
                }

                const previous = this.players[playerId]
                const seatRaw = raw.Index ?? raw.index ?? index
                const seatIndex =
                    typeof seatRaw === 'number' && Number.isFinite(seatRaw) ? seatRaw : index
                const readyRaw = raw.Ready ?? raw.ready
                const ready = parseBooleanish(readyRaw)
                const displayNameRaw = raw.PlayerName ?? raw.player_name
                const avatarUrlRaw = raw.AvatarUrl ?? raw.avatar_url
                const missingSuitRaw = raw.MissingSuit ?? raw.missing_suit

                nextPlayers[playerId] = {
                    playerId,
                    seatIndex,
                    displayName:
                        typeof displayNameRaw === 'string' && displayNameRaw
                            ? displayNameRaw
                            : previous?.displayName,
                    avatarURL:
                        typeof avatarUrlRaw === 'string'
                            ? avatarUrlRaw
                            : previous?.avatarURL,
                    isTrustee: previous?.isTrustee ?? false,
                    missingSuit:
                        typeof missingSuitRaw === 'string' || missingSuitRaw === null
                            ? missingSuitRaw
                            : previous?.missingSuit,
                    handTiles: previous?.handTiles ?? [],
                    handCount: previous?.handCount ?? 0,
                    melds: previous?.melds ?? [],
                    discardTiles: previous?.discardTiles ?? [],
                    hasHu: previous?.hasHu ?? false,
                    score: previous?.score ?? 0,
                    isReady:
                        ready !== null
                            ? ready
                            : (previous?.isReady ?? false),
                }
            })

            if (players.length === 0) {
                playerIds.forEach((playerId, index) => {
                    if (typeof playerId !== 'string' || !playerId) {
                        return
                    }
                    const previous = this.players[playerId]
                    nextPlayers[playerId] = {
                        playerId,
                        seatIndex: previous?.seatIndex ?? index,
                        displayName: previous?.displayName ?? playerId,
                        avatarURL: previous?.avatarURL,
                        isTrustee: previous?.isTrustee ?? false,
                        missingSuit: previous?.missingSuit,
                        handTiles: previous?.handTiles ?? [],
                        handCount: previous?.handCount ?? 0,
                        melds: previous?.melds ?? [],
                        discardTiles: previous?.discardTiles ?? [],
                        hasHu: previous?.hasHu ?? false,
                        score: previous?.score ?? 0,
                        isReady: previous?.isReady ?? false,
                    }
                })
            }

            this.players = nextPlayers
        },

        onRoomTrustee(payload: RoomTrusteePayload) {
            const playerId =
                (typeof payload.player_id === 'string' && payload.player_id) ||
                (typeof payload.playerId === 'string' && payload.playerId) ||
                ''
            if (!playerId) {
                return
            }

            const player = this.players[playerId]
            if (!player) {
                return
            }

            player.isTrustee = typeof payload.trustee === 'boolean' ? payload.trustee : true
        },

        // 清理操作窗口
        onPlayerTurn(payload: PlayerTurnPayload) {
            const playerId =
                (typeof payload.player_id === 'string' && payload.player_id) ||
                (typeof payload.playerId === 'string' && payload.playerId) ||
                (typeof payload.PlayerID === 'string' && payload.PlayerID) ||
                ''
            if (!playerId) {
                return
            }

            const player = this.players[playerId]
            if (player) {
                this.currentTurn = player.seatIndex
            }
            this.currentPlayerId = playerId

            this.needDraw = false
            this.pendingClaim = undefined
            this.phase = GAME_PHASE.PLAYING
        },

        clearPendingClaim() {
            this.pendingClaim = undefined
            this.phase = GAME_PHASE.PLAYING
        },

        // 获取当前玩家ID（后续建议放�?userStore�?
        getMyPlayerId(): string {
            const auth = readStoredAuth()
            const source = auth?.user as Record<string, unknown> | undefined
            const rawId =
                source?.id ??
                source?.userID ??
                source?.user_id
            if (typeof rawId === 'string' && rawId.trim()) {
                return rawId
            }
            if (typeof rawId === 'number') {
                return String(rawId)
            }
            return ''
        },
    },
})


