<script setup lang="ts">
import GameActionDock from './GameActionDock.vue'
import GameMessageStack from './GameMessageStack.vue'
import PublicEventTimeline from './PublicEventTimeline.vue'
import PublicSeatBoard from './PublicSeatBoard.vue'
import SelfHandPanel from './SelfHandPanel.vue'
import ViewSwitchPanel from './ViewSwitchPanel.vue'
import type {
  DiagnosticItem,
  GameStateResponse,
  PrivateActionCandidate,
  PrivateActionMessage,
  PrivateTeachingMessage,
  PublicGameMessage,
  ScoreChangeCardView,
  SettlementCardView,
  ViewUserOption
} from '../types/game'
import { phaseLabelMap } from '../utils/gameUi'

const props = defineProps<{
  game: GameStateResponse | null
  currentUserId: string
  currentViewLabel: string
  viewUserOptions: ViewUserOption[]
  lackSuit: string
  canSelectLack: boolean
  canDiscard: boolean
  recommendedDiscardTile: string | null
  privateTeaching: PrivateTeachingMessage | null
  privateTeachingHint: string
  privateTeachingCandidates: { tile: string; score: number; reasonTags: string[] }[]
  privateAction: PrivateActionMessage | null
  privateActionSummary: string
  actionPanelHint: string
  turnActionCandidates: PrivateActionCandidate[]
  responseActionCandidates: PrivateActionCandidate[]
  responseContextSummary: string
  actionDiagnosticItems: DiagnosticItem[]
  publicSeats: GameStateResponse['seats']
  publicEvents: PublicGameMessage[]
  latestSettlementCard: SettlementCardView | null
  latestSettlementScoreChanges: ScoreChangeCardView[]
  wsStatus: string
}>()

const emit = defineEmits<{
  'update:lackSuit': [value: string]
  refreshGameState: []
  selectLack: []
  switchUserView: [userId: string]
  discard: [tile: string]
  submitCandidateAction: [actionType: string, tile: string | null]
}>()

function updateLackSuit(event: Event) {
  emit('update:lackSuit', (event.target as HTMLSelectElement).value)
}

function handleSwitchUserView(userId: string) {
  emit('switchUserView', userId)
}

function handleSubmitCandidateAction(actionType: string, tile: string | null) {
  emit('submitCandidateAction', actionType, tile)
}

// 这是“对局工作区”级别的容器组件：统一组合手牌、动作、私有消息、公共桌面与事件时间线，
// 让 App 容器只保留接口、WebSocket 和状态清理逻辑。
</script>

<template>
  <section v-if="props.game" class="play-grid">
    <article class="panel game-panel">
      <div class="panel-head">
        <div>
          <p class="eyebrow">步骤 3</p>
          <h2>对局控制台</h2>
        </div>
        <span class="status-pill">{{ phaseLabelMap[props.game.phase] ?? props.game.phase }}</span>
      </div>

      <div class="room-meta">
        <div>
          <span class="meta-label">对局 ID</span>
          <strong>{{ props.game.gameId }}</strong>
        </div>
        <div>
          <span class="meta-label">当前视角</span>
          <strong>{{ props.currentViewLabel }}</strong>
        </div>
        <div>
          <span class="meta-label">剩余牌墙</span>
          <strong>{{ props.game.remainingWallCount }}</strong>
        </div>
      </div>

      <ViewSwitchPanel :options="props.viewUserOptions" :current-user-id="props.currentUserId" @switch="handleSwitchUserView" />

      <div class="btn-row vertical-on-mobile">
        <button class="secondary-btn" @click="emit('refreshGameState')">刷新对局</button>
        <label class="field compact-field">
          <span>定缺</span>
          <select :value="props.lackSuit" @change="updateLackSuit">
            <option value="WAN">万</option>
            <option value="TONG">筒</option>
            <option value="TIAO">条</option>
          </select>
        </label>
        <button class="primary-btn" :disabled="!props.canSelectLack" @click="emit('selectLack')">提交定缺</button>
      </div>

      <SelfHandPanel
        :self-seat="props.game.selfSeat"
        :current-seat-no="props.game.currentSeatNo"
        :can-discard="props.canDiscard"
        :recommended-discard-tile="props.recommendedDiscardTile"
        :teaching-explanation="props.privateTeaching?.explanation ?? null"
        @discard="emit('discard', $event)"
      />

      <GameActionDock
        :private-action="props.privateAction"
        :private-action-summary="props.privateActionSummary"
        :action-panel-hint="props.actionPanelHint"
        :turn-action-candidates="props.turnActionCandidates"
        :response-action-candidates="props.responseActionCandidates"
        :recommended-discard-tile="props.recommendedDiscardTile"
        :response-context-summary="props.responseContextSummary"
        @submit="handleSubmitCandidateAction"
      />
    </article>

    <article class="panel board-panel">
      <div class="panel-head">
        <div>
          <p class="eyebrow">步骤 4</p>
          <h2>消息与公共桌面</h2>
        </div>
        <span class="status-pill">{{ props.wsStatus }}</span>
      </div>

      <GameMessageStack
        :private-action="props.privateAction"
        :private-action-summary="props.privateActionSummary"
        :action-diagnostic-items="props.actionDiagnosticItems"
        :action-panel-hint="props.actionPanelHint"
        :private-teaching="props.privateTeaching"
        :recommended-discard-tile="props.recommendedDiscardTile"
        :teaching-hint="props.privateTeachingHint"
        :teaching-candidates="props.privateTeachingCandidates"
      />

      <PublicSeatBoard :seats="props.publicSeats" />

      <PublicEventTimeline
        :public-events="props.publicEvents"
        :latest-settlement-card="props.latestSettlementCard"
        :latest-settlement-score-changes="props.latestSettlementScoreChanges"
      />
    </article>
  </section>
</template>
