import { defineStore } from 'pinia'
import {
    GAME_PHASE,
    type GameState,
    type PendingClaimState,
} from '../types/state'
import type { RoomPlayerUpdatePayload } from '../game/actions'

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

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

        phase: GAME_PHASE.WAITING,

        dealerIndex: 0,
        currentTurn: 0,

        players: {},

        remainingTiles: 0,

        pendingClaim: undefined,

        winners: [],

        scores: {},
    }),

    actions: {
        // 初始化
        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)
            }

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

            // 更新回合（seatIndex）
            this.currentTurn = player.seatIndex

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

            // 进入出牌阶段
            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.discardTiles.push(data.tile)

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

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

        // 触发操作窗口（碰/杠/胡）
        onPendingClaim(data: PendingClaimState) {
            this.pendingClaim = data
            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 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,
                    missingSuit:
                        typeof missingSuitRaw === 'string' || missingSuitRaw === null
                            ? missingSuitRaw
                            : previous?.missingSuit,
                    handTiles: previous?.handTiles ?? [],
                    melds: previous?.melds ?? [],
                    discardTiles: previous?.discardTiles ?? [],
                    score: previous?.score ?? 0,
                    isReady:
                        typeof readyRaw === 'boolean'
                            ? readyRaw
                            : (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,
                        missingSuit: previous?.missingSuit,
                        handTiles: previous?.handTiles ?? [],
                        melds: previous?.melds ?? [],
                        discardTiles: previous?.discardTiles ?? [],
                        score: previous?.score ?? 0,
                        isReady: previous?.isReady ?? false,
                    }
                })
            }

            this.players = nextPlayers
        },

        // 清理操作窗口
        clearPendingClaim() {
            this.pendingClaim = undefined
            this.phase = GAME_PHASE.PLAYING
        },

        // 获取当前玩家ID（后续建议放到 userStore）
        getMyPlayerId(): string {
            return Object.keys(this.players)[0] || ''
        },
    },
})
