<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { AuthExpiredError, type AuthSession } from '../api/authed-request'
import { createRoom, joinRoom, listRooms, type RoomItem } from '../api/mahjong'
import { getUserInfo, type UserInfo } from '../api/user'
import refreshIcon from '../assets/images/icons/refresh.svg'
import { setActiveRoom } from '../store'
import type { RoomPlayerState } from '../store/state'
import type { StoredAuth } from '../types/session'
import { clearAuth, readStoredAuth, writeStoredAuth } from '../utils/auth-storage'
import { wsClient } from '../ws/client'
import { buildWsUrl } from '../ws/url'

const router = useRouter()

const roomLoading = ref(false)
const roomSubmitting = ref(false)
const rooms = ref<RoomItem[]>([])
const roomTotal = ref(0)
const errorMessage = ref('')
const successMessage = ref('')

const showCreateModal = ref(false)
const showCreatedModal = ref(false)
const createdRoom = ref<RoomItem | null>(null)
const userInfo = ref<UserInfo | null>(null)
const userInfoLoading = ref(false)
const showFullPhone = ref(false)

const createRoomForm = ref({
  name: '',
  gameType: 'chengdu',
  maxPlayers: 4,
})

const quickJoinRoomId = ref('')
const auth = ref<StoredAuth | null>(readStoredAuth())

const inviteLink = computed(() => {
  if (!createdRoom.value) {
    return ''
  }

  const url = new URL(window.location.href)
  url.searchParams.set('room_id', createdRoom.value.room_id)
  return url.toString()
})

const displayName = computed(() => {
  return (
    (typeof userInfo.value?.nickname === 'string' && userInfo.value.nickname) ||
    (typeof userInfo.value?.username === 'string' && userInfo.value.username) ||
    auth.value?.user?.nickname ||
    auth.value?.user?.username ||
    'Guest'
  )
})

const currentUserId = computed(() => {
  const candidate =
    userInfo.value?.userID ??
    userInfo.value?.user_id ??
    userInfo.value?.id ??
    auth.value?.user?.id

  if (typeof candidate === 'string') {
    return candidate
  }

  if (typeof candidate === 'number') {
    return String(candidate)
  }

  return ''
})

const displayPhone = computed(() => {
  return typeof userInfo.value?.phone === 'string' ? userInfo.value.phone : ''
})

const displayUserId = computed(() => {
  const candidate =
    userInfo.value?.userID ??
    userInfo.value?.user_id ??
    userInfo.value?.id ??
    auth.value?.user?.id

  if (typeof candidate === 'string') {
    return candidate
  }

  if (typeof candidate === 'number') {
    return String(candidate)
  }

  return ''
})

const displayEmail = computed(() => {
  return typeof userInfo.value?.email === 'string' ? userInfo.value.email : ''
})

const maskedPhone = computed(() => {
  const phone = displayPhone.value
  if (phone.length < 7) {
    return phone
  }

  return `${phone.slice(0, 3)}****${phone.slice(-4)}`
})

function gameTypeLabel(type: string): string {
  if (type === 'chengdu') {
    return '四川麻将'
  }

  if (type === 'xueliu') {
    return '血流成河'
  }

  return type
}

function isMyRoom(room: RoomItem): boolean {
  return Boolean(currentUserId.value) && room.owner_id === currentUserId.value
}

function mapRoomPlayers(room: RoomItem): RoomPlayerState[] {
  return (room.players ?? [])
    .map((item, fallbackIndex) => ({
      index: Number.isFinite(item.index) ? item.index : fallbackIndex,
      playerId: item.player_id,
      displayName:
        (typeof item.player_name === 'string' && item.player_name) ||
        (typeof item.PlayerName === 'string' && item.PlayerName) ||
        (item.player_id === currentUserId.value ? displayName.value : undefined),
      ready: Boolean(item.ready),
      hand: [],
      melds: [],
      outTiles: [],
      hasHu: false,
    }))
    .filter((item) => Boolean(item.playerId))
}

function toSession(source: StoredAuth): AuthSession {
  return {
    token: source.token,
    tokenType: source.tokenType,
    refreshToken: source.refreshToken,
    expiresIn: source.expiresIn,
  }
}

function syncAuth(next: AuthSession): void {
  if (!auth.value) {
    return
  }

  auth.value = {
    ...auth.value,
    token: next.token,
    tokenType: next.tokenType ?? auth.value.tokenType,
    refreshToken: next.refreshToken ?? auth.value.refreshToken,
    expiresIn: next.expiresIn,
  }
  writeStoredAuth(auth.value)
}

function logoutToLogin(): void {
  clearAuth()
  auth.value = null
  void router.replace('/login')
}

function currentSession(): AuthSession | null {
  if (!auth.value) {
    logoutToLogin()
    return null
  }

  return toSession(auth.value)
}

function connectGameWs(): void {
  const token = auth.value?.token
  if (!token) {
    return
  }
  wsClient.connect(buildWsUrl(token), token)
}

async function refreshRooms(): Promise<void> {
  const session = currentSession()
  if (!session) {
    return
  }

  roomLoading.value = true
  errorMessage.value = ''
  try {
    const result = await listRooms(session, syncAuth)
    rooms.value = result.items ?? []
    roomTotal.value = result.total ?? rooms.value.length
  } catch (error) {
    if (error instanceof AuthExpiredError) {
      logoutToLogin()
      return
    }
    errorMessage.value = error instanceof Error ? error.message : '获取房间列表失败'
  } finally {
    roomLoading.value = false
  }
}

function openCreateModal(): void {
  errorMessage.value = ''
  successMessage.value = ''
  showCreateModal.value = true
}

function closeCreateModal(): void {
  showCreateModal.value = false
}

async function submitCreateRoom(): Promise<void> {
  const session = currentSession()
  if (!session) {
    return
  }

  errorMessage.value = ''
  successMessage.value = ''

  if (!createRoomForm.value.name.trim()) {
    errorMessage.value = '请输入房间名'
    return
  }

  roomSubmitting.value = true
  try {
    const room = await createRoom(
      session,
      {
        name: createRoomForm.value.name.trim(),
        gameType: createRoomForm.value.gameType,
        maxPlayers: Number(createRoomForm.value.maxPlayers),
      },
      syncAuth,
    )

    createdRoom.value = room
    setActiveRoom({
      roomId: room.room_id,
      roomName: room.name,
      gameType: room.game_type,
      ownerId: room.owner_id,
      maxPlayers: room.max_players,
      playerCount: room.player_count,
      status: room.status,
      createdAt: room.created_at,
      updatedAt: room.updated_at,
      players: mapRoomPlayers(room),
    })
    quickJoinRoomId.value = room.room_id
    createRoomForm.value.name = ''
    showCreateModal.value = false
    showCreatedModal.value = true
    await refreshRooms()
  } catch (error) {
    if (error instanceof AuthExpiredError) {
      logoutToLogin()
      return
    }
    errorMessage.value = error instanceof Error ? error.message : '创建房间失败'
  } finally {
    roomSubmitting.value = false
  }
}

async function handleJoinRoom(room?: { roomId?: string; roomName?: string }): Promise<void> {
  const session = currentSession()
  if (!session) {
    return
  }

  errorMessage.value = ''
  successMessage.value = ''

  const targetRoomId = (room?.roomId ?? quickJoinRoomId.value).trim()
  if (!targetRoomId) {
    errorMessage.value = '请输入房间ID'
    return
  }

  roomSubmitting.value = true
  try {
    const joinedRoom = await joinRoom(session, { roomId: targetRoomId }, syncAuth)
    setActiveRoom({
      roomId: joinedRoom.room_id,
      roomName: joinedRoom.name,
      gameType: joinedRoom.game_type,
      ownerId: joinedRoom.owner_id,
      maxPlayers: joinedRoom.max_players,
      playerCount: joinedRoom.player_count,
      status: joinedRoom.status,
      createdAt: joinedRoom.created_at,
      updatedAt: joinedRoom.updated_at,
      players: mapRoomPlayers(joinedRoom),
    })
    quickJoinRoomId.value = joinedRoom.room_id
    successMessage.value = `已加入房间：${joinedRoom.room_id}`
    await refreshRooms()
    connectGameWs()
    await router.push({
      path: `/game/chengdu/${joinedRoom.room_id}`,
      query: joinedRoom.name ? { roomName: joinedRoom.name } : undefined,
    })
  } catch (error) {
    if (error instanceof AuthExpiredError) {
      logoutToLogin()
      return
    }
    errorMessage.value = error instanceof Error ? error.message : '加入房间失败'
  } finally {
    roomSubmitting.value = false
  }
}

async function copyText(text: string, okText: string): Promise<void> {
  if (!text) {
    return
  }

  try {
    await navigator.clipboard.writeText(text)
    successMessage.value = okText
  } catch {
    errorMessage.value = '复制失败，请手动复制'
  }
}

function closeCreatedModal(): void {
  showCreatedModal.value = false
}

async function enterCreatedRoom(): Promise<void> {
  if (!createdRoom.value) {
    return
  }

  showCreatedModal.value = false
  setActiveRoom({
    roomId: createdRoom.value.room_id,
    roomName: createdRoom.value.name,
    gameType: createdRoom.value.game_type,
    ownerId: createdRoom.value.owner_id,
    maxPlayers: createdRoom.value.max_players,
    playerCount: createdRoom.value.player_count,
    status: createdRoom.value.status,
    createdAt: createdRoom.value.created_at,
    updatedAt: createdRoom.value.updated_at,
    players: mapRoomPlayers(createdRoom.value),
  })
  connectGameWs()
  await router.push({
    path: `/game/chengdu/${createdRoom.value.room_id}`,
    query: { roomName: createdRoom.value.name },
  })
}

async function loadUserInfo(): Promise<void> {
  const session = currentSession()
  if (!session) {
    return
  }

  userInfoLoading.value = true
  try {
    userInfo.value = await getUserInfo(session, syncAuth)
  } catch (error) {
    if (error instanceof AuthExpiredError) {
      logoutToLogin()
      return
    }
    errorMessage.value = error instanceof Error ? error.message : '获取用户信息失败'
  } finally {
    userInfoLoading.value = false
  }
}

onMounted(async () => {
  if (!auth.value) {
    await router.replace('/login')
    return
  }

  await loadUserInfo()
  await refreshRooms()
})
</script>

<template>
  <section class="hall-page hall-wood-bg">
    <header class="hall-header hall-topbar">
      <div class="brand-block">
        <div class="hall-logo">雀</div>
        <div>
          <h1>麻将游戏大厅</h1>
          <p class="sub-title">Mahjong Club - Chengdu Table</p>
        </div>
      </div>
      <div class="user-chip">
        <p>{{ userInfoLoading ? '加载用户中...' : '玩家信息' }}</p>
        <strong>用户名：{{ displayName }}</strong>
        <small v-if="displayUserId">ID: {{ displayUserId }}</small>
        <small v-if="displayEmail">邮箱: {{ displayEmail }}</small>
        <small v-if="displayPhone">
          电话: {{ showFullPhone ? displayPhone : maskedPhone }}
          <button class="text-btn" type="button" @click="showFullPhone = !showFullPhone">
            {{ showFullPhone ? '隐藏' : '显示' }}
          </button>
        </small>
      </div>
    </header>

    <section class="hall-grid hall-grid-8-4">
      <article class="panel room-list-panel">
        <div class="room-panel-header">
          <h2>房间列表</h2>
          <button class="icon-btn" type="button" :disabled="roomLoading" @click="refreshRooms">
            <img class="icon-btn-image" :src="refreshIcon" alt="刷新房间列表" />
          </button>
        </div>

        <div v-if="roomLoading" class="empty-state">正在加载房间...</div>
        <div v-else-if="rooms.length === 0" class="empty-state">暂无可加入房间，先创建一个吧。</div>
        <ul v-else class="room-list">
          <li v-for="room in rooms" :key="room.room_id" class="room-card">
            <div class="room-meta">
              <p class="room-name">{{ room.name }}</p>
              <p class="room-tags">
                <span>{{ gameTypeLabel(room.game_type) }}</span>
                <span>{{ room.player_count }}/{{ room.max_players }}</span>
                <span v-if="isMyRoom(room)" class="owner-tag">房主（我）</span>
              </p>
              <p class="room-id">ID: {{ room.room_id }}</p>
            </div>
            <button
              class="primary-btn"
              type="button"
              :disabled="roomSubmitting"
              @click="handleJoinRoom({ roomId: room.room_id, roomName: room.name })"
            >
              进入
            </button>
          </li>
        </ul>

        <div class="room-actions-footer">
          <button class="primary-btn wide-btn" type="button" @click="openCreateModal">创建房间</button>
          <button class="ghost-btn wide-btn" type="button" @click="logoutToLogin">退出大厅</button>
        </div>
      </article>

      <aside class="panel side-panel">
        <h2>大厅信息</h2>
        <p class="hint-text">当前房间总数：{{ roomTotal }}</p>
        <p class="hint-text">推荐玩法：四川麻将 / 血流成河</p>

        <h3>快速加入</h3>
        <form class="join-line" @submit.prevent="handleJoinRoom()">
          <input v-model.trim="quickJoinRoomId" type="text" placeholder="输入 room_id" />
          <button class="primary-btn" type="submit" :disabled="roomSubmitting">加入</button>
        </form>
      </aside>
    </section>

    <p v-if="errorMessage" class="message error">{{ errorMessage }}</p>
    <p v-if="successMessage" class="message success">{{ successMessage }}</p>

    <div v-if="showCreateModal" class="modal-mask" @click.self="closeCreateModal">
      <section class="modal-card modal-600">
        <h2>创建房间</h2>
        <form class="form" @submit.prevent="submitCreateRoom">
          <label class="field">
            <span>房间名</span>
            <input v-model.trim="createRoomForm.name" type="text" maxlength="24" placeholder="例如：test001" />
          </label>
          <label class="field">
            <span>玩法</span>
            <select v-model="createRoomForm.gameType">
              <option value="chengdu">四川麻将</option>
              <option value="xueliu">血流成河</option>
            </select>
          </label>

          <fieldset class="radio-group">
            <legend>人数</legend>
            <label><input v-model.number="createRoomForm.maxPlayers" type="radio" :value="2" /> 2人</label>
            <label><input v-model.number="createRoomForm.maxPlayers" type="radio" :value="3" /> 3人</label>
            <label><input v-model.number="createRoomForm.maxPlayers" type="radio" :value="4" /> 4人</label>
          </fieldset>

          <div class="modal-actions">
            <button class="ghost-btn" type="button" @click="closeCreateModal">取消</button>
            <button class="primary-btn" type="submit" :disabled="roomSubmitting">
              {{ roomSubmitting ? '创建中...' : '创建' }}
            </button>
          </div>
        </form>
      </section>
    </div>

    <div v-if="showCreatedModal && createdRoom" class="modal-mask" @click.self="closeCreatedModal">
      <section class="modal-card modal-600">
        <h2>房间创建成功</h2>

        <div class="copy-line">
          <span>房间ID：{{ createdRoom.room_id }}</span>
          <button class="ghost-btn" type="button" @click="copyText(createdRoom.room_id, '房间ID已复制')">复制</button>
        </div>

        <div class="copy-line">
          <span>邀请链接：{{ inviteLink }}</span>
          <button class="ghost-btn" type="button" @click="copyText(inviteLink, '邀请链接已复制')">复制</button>
        </div>

        <div class="modal-actions">
          <button class="primary-btn" type="button" @click="enterCreatedRoom">进入房间</button>
        </div>
      </section>
    </div>
  </section>
</template>
