<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import deskImage from '../assets/images/desk/desk_01.png'
import topBackImage from '../assets/images/tiles/top/tbgs_2.png'
import rightBackImage from '../assets/images/tiles/right/tbgs_1.png'
import bottomBackImage from '../assets/images/tiles/bottom/tdbgs_4.png'
import leftBackImage from '../assets/images/tiles/left/tbgs_3.png'
import TopPlayerCard from '../components/game/TopPlayerCard.vue'
import RightPlayerCard from '../components/game/RightPlayerCard.vue'
import BottomPlayerCard from '../components/game/BottomPlayerCard.vue'
import LeftPlayerCard from '../components/game/LeftPlayerCard.vue'
import type { SeatPlayerCardModel } from '../components/game/seat-player-card'
import { useChengduGameRoom, type SeatKey } from '../features/chengdu-game/useChengduGameRoom'

const route = useRoute()
const router = useRouter()
const {
  roomState,
  roomId,
  roomName,
  loggedInUserName,
  wsStatus,
  wsError,
  wsMessages,
  startGamePending,
  leaveRoomPending,
  canStartGame,
  seatViews,
  connectWs,
  sendStartGame,
  backHall,
} = useChengduGameRoom(route, router)

const now = ref(Date.now())
let clockTimer: number | null = null

const roomStatusText = computed(() => {
  if (roomState.value.status === 'playing') {
    return '对局中'
  }
  if (roomState.value.status === 'finished') {
    return '已结束'
  }
  return '等待中'
})

const currentPhaseText = computed(() => {
  const phase = roomState.value.game?.state?.phase?.trim()
  if (!phase) {
    return roomState.value.status === 'playing' ? '牌局进行中' : '未开局'
  }

  const phaseLabelMap: Record<string, string> = {
    dealing: '发牌',
    draw: '摸牌',
    discard: '出牌',
    action: '响应',
    settle: '结算',
    finished: '已结束',
  }

  return phaseLabelMap[phase] ?? phase
})

const networkLabel = computed(() => {
  if (wsStatus.value === 'connected') {
    return '已连接'
  }
  if (wsStatus.value === 'connecting') {
    return '连接中'
  }
  return '未连接'
})

const formattedClock = computed(() => {
  return new Date(now.value).toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false,
  })
})

const statusRibbon = computed(() => {
  return roomState.value.game?.rule?.name || currentPhaseText.value
})

const wallBacks = computed<Record<SeatKey, string[]>>(() => {
  const wallSize = roomState.value.game?.state?.wall.length ?? 0
  const perSide = Math.max(6, Math.ceil((wallSize || 48) / 4 / 2))

  return {
    top: Array.from({ length: perSide }, (_, index) => `top-${index}`),
    right: Array.from({ length: perSide }, (_, index) => `right-${index}`),
    bottom: Array.from({ length: perSide }, (_, index) => `bottom-${index}`),
    left: Array.from({ length: perSide }, (_, index) => `left-${index}`),
  }
})

const seatDecor = computed<Record<SeatKey, SeatPlayerCardModel>>(() => {
  const scoreMap = roomState.value.game?.state?.scores ?? {}
  const dealerIndex = roomState.value.game?.state?.dealerIndex ?? -1
  const emptyLabel = missingSuitLabel(null)

  return seatViews.value.reduce(
    (acc, seat, index) => {
      const playerId = seat.player?.playerId ?? ''
      const score = playerId ? scoreMap[playerId] : undefined

      acc[seat.key] = {
        avatar: seat.isSelf ? '我' : String(index + 1),
        name: seat.player ? (seat.isSelf ? '你' : playerId) : '空位',
        money: typeof score === 'number' ? `${score}` : '--',
        dealer: seat.player?.index === dealerIndex,
        isTurn: seat.isTurn,
        isOnline: Boolean(seat.player),
        missingSuitLabel: emptyLabel,
      }

      return acc
    },
    {
      top: {
        avatar: '1',
        name: '空位',
        money: '--',
        dealer: false,
        isTurn: false,
        isOnline: false,
        missingSuitLabel: emptyLabel,
      },
      right: {
        avatar: '2',
        name: '空位',
        money: '--',
        dealer: false,
        isTurn: false,
        isOnline: false,
        missingSuitLabel: emptyLabel,
      },
      bottom: {
        avatar: '我',
        name: '空位',
        money: '--',
        dealer: false,
        isTurn: false,
        isOnline: false,
        missingSuitLabel: emptyLabel,
      },
      left: {
        avatar: '4',
        name: '空位',
        money: '--',
        dealer: false,
        isTurn: false,
        isOnline: false,
        missingSuitLabel: emptyLabel,
      },
    },
  )
})

const centerTimer = computed(() => {
  const wallLeft = roomState.value.game?.state?.wall.length
  if (typeof wallLeft === 'number' && Number.isFinite(wallLeft)) {
    return `余牌 ${wallLeft}`
  }

  return roomState.value.playerCount > 0
    ? `${roomState.value.playerCount}/${roomState.value.maxPlayers} 人`
    : '等待中'
})

function missingSuitLabel(value: string | null | undefined): string {
  if (!value) {
    return '待定'
  }

  const suitMap: Record<string, string> = {
    wan: '万',
    tong: '筒',
    tiao: '条',
  }

  return suitMap[value] ?? value
}

function getBackImage(seat: SeatKey): string {
  const imageMap: Record<SeatKey, string> = {
    top: topBackImage,
    right: rightBackImage,
    bottom: bottomBackImage,
    left: leftBackImage,
  }

  return imageMap[seat]
}

onMounted(() => {
  clockTimer = window.setInterval(() => {
    now.value = Date.now()
  }, 1000)
})

onBeforeUnmount(() => {
  if (clockTimer !== null) {
    window.clearInterval(clockTimer)
    clockTimer = null
  }
})
</script>

<template>
  <section class="hall-page game-page">
    <header class="hall-header game-header">
      <div class="topbar-left">
        <button class="ghost-btn topbar-back-btn" type="button" :disabled="leaveRoomPending" @click="backHall">
          {{ leaveRoomPending ? '退出中...' : '返回大厅' }}
        </button>
        <div class="topbar-room-meta">
          <p class="eyebrow">成都麻将对局</p>
          <p class="topbar-room-name">{{ roomState.name || roomName || '未命名房间' }}</p>
          <p v-if="loggedInUserName" class="sub-title">玩家：{{ loggedInUserName }}</p>
        </div>
      </div>

      <div class="topbar-center">
        <div class="title-stack">
          <p class="game-title">成都麻将实战桌</p>
          <p class="game-subtitle">{{ roomStatusText }} · {{ currentPhaseText }}</p>
        </div>
      </div>
      <div class="topbar-right">
        <div class="status-chip net-chip">
          <span class="wifi-dot" :class="`is-${wsStatus}`"></span>
          <strong>{{ networkLabel }}</strong>
        </div>
        <div class="status-chip clock-chip">{{ formattedClock }}</div>
        <button class="header-btn ghost-btn" type="button" @click="connectWs">重连</button>
      </div>
    </header>

    <section class="table-panel game-table-panel">
      <div class="room-brief">
        <span class="room-brief-title">当前房间</span>
        <span class="room-brief-item">
          <em>房间名：</em>
          <strong>{{ roomState.name || roomName || '未命名房间' }}</strong>
        </span>
        <span class="room-brief-item room-brief-id">
          <em>room_id:</em>
          <strong>{{ roomId || '未选择房间' }}</strong>
        </span>
        <span class="room-brief-item">
          <em>状态：</em>
          <strong>{{ roomStatusText }}</strong>
        </span>
        <span class="room-brief-item">
          <em>人数：</em>
          <strong>{{ roomState.playerCount }}/{{ roomState.maxPlayers }}</strong>
        </span>
        <button
          class="ghost-btn ws-reconnect"
          type="button"
          :disabled="!canStartGame || startGamePending"
          @click="sendStartGame"
        >
          {{ startGamePending ? '开局请求中...' : '开始游戏' }}
        </button>
      </div>
    </section>

    <section class="table-shell">
      <img class="table-desk" :src="deskImage" alt="" />
      <div class="table-felt">
        <div class="felt-frame outer"></div>
        <div class="felt-frame inner"></div>
        <div class="table-watermark">
          <span>{{ statusRibbon }}</span>
          <strong>指尖四川麻将</strong>
          <small>底注 6 番 · 封顶 32 倍</small>
        </div>

        <TopPlayerCard :player="seatDecor.top" />
        <RightPlayerCard :player="seatDecor.right" />
        <BottomPlayerCard :player="seatDecor.bottom" />
        <LeftPlayerCard :player="seatDecor.left" />

        <div class="wall wall-top">
          <img v-for="key in wallBacks.top" :key="key" :src="getBackImage('top')" alt="" />
        </div>
        <div class="wall wall-right">
          <img v-for="key in wallBacks.right" :key="key" :src="getBackImage('right')" alt="" />
        </div>
        <div class="wall wall-bottom">
          <img v-for="key in wallBacks.bottom" :key="key" :src="getBackImage('bottom')" alt="" />
        </div>
        <div class="wall wall-left">
          <img v-for="key in wallBacks.left" :key="key" :src="getBackImage('left')" alt="" />
        </div>

        <div class="center-deck" :class="`state-${roomState.status}`">
          <span class="wind north">北</span>
          <span class="wind west">西</span>
          <span class="wind south">南</span>
          <span class="wind east">东</span>
          <strong>{{ centerTimer }}</strong>
        </div>
        <div
          v-for="seat in seatViews"
          :key="seat.key"
          class="seat"
          :class="[
            `seat-${seat.key}`,
            { occupied: Boolean(seat.player), 'seat-me': seat.isSelf, 'seat-turn': seat.isTurn },
          ]"
        >
          <strong>{{ seat.label }}</strong>
          <small v-if="seat.subLabel">{{ seat.subLabel }}</small>
          <span v-if="seat.isTurn" class="turn-indicator">出牌中</span>
        </div>
        <div class="table-center">
          <p>成都麻将</p>
          <p>{{ roomState.id || roomId || '等待中...' }}</p>
        </div>
      </div>

      <section class="ws-panel">
        <div class="ws-panel-head">
          <strong>实时消息</strong>
          <div class="ws-actions">
            <span class="ws-state" :class="`is-${wsStatus}`">{{ wsStatus }}</span>
            <button class="ghost-btn ws-reconnect" type="button" @click="connectWs">重连</button>
          </div>
        </div>
        <p v-if="wsError" class="message error">{{ wsError }}</p>
        <div class="ws-log">
          <p v-if="wsMessages.length === 0" class="ws-empty">等待服务器消息...</p>
          <p v-for="(line, idx) in wsMessages" :key="idx" class="ws-line">{{ line }}</p>
        </div>
      </section>
    </section>
  </section>
</template>
