<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { sortedRoles, DEFAULT_PRESETS, roleImageUrl } from '../logic/roles'
import type { Preferences } from '../logic/assignment'
import type { HistoryEntry } from '../logic/storage'

const props = defineProps<{
  show: boolean
  history: HistoryEntry[]
  initialPlayerCount?: number
}>()

const emit = defineEmits<{
  close: []
  start: [payload: { rolesList: string[]; preferences: Preferences }]
}>()

const playerCount = ref(props.initialPlayerCount ?? 8)
const currentRoles = ref<string[]>([])
const preferences = ref<{ player: number; roles: string[] }[]>([])
const showAddPref = ref(false)
const newPref = ref<{ player: number | null; roles: string[] }>({ player: null, roles: [] })

const allRoles = sortedRoles()

watch(
  () => props.show,
  (s) => {
    if (s) {
      // reset preferences only; keep currentRoles + count for repeated games
      preferences.value = []
      showAddPref.value = false
      newPref.value = { player: null, roles: [] }
      if (props.initialPlayerCount) playerCount.value = props.initialPlayerCount
    }
  },
)

const canAddRole = computed(() => currentRoles.value.length < playerCount.value)
const canStart = computed(() => currentRoles.value.length === playerCount.value && playerCount.value >= 6)

const matchingPresets = computed(() => {
  const matches: { key: string; isHistory: boolean; roles: Record<string, number> }[] = []
  if (DEFAULT_PRESETS[playerCount.value]) {
    matches.push({ key: `preset-${playerCount.value}`, isHistory: false, roles: DEFAULT_PRESETS[playerCount.value] })
  }
  let count = 0
  for (let i = 0; i < props.history.length && count < 3; i++) {
    const h = props.history[i]
    if (h.playerCount === playerCount.value) {
      matches.push({ key: `history-${i}`, isHistory: true, roles: h.roles })
      count++
    }
  }
  return matches
})

const configuredRoles = computed(() => {
  return Array.from(new Set(currentRoles.value))
})

function decPlayers() {
  if (playerCount.value <= 6) return
  playerCount.value -= 1
  if (currentRoles.value.length > playerCount.value) {
    currentRoles.value = currentRoles.value.slice(0, playerCount.value)
  }
}
function incPlayers() {
  if (playerCount.value < 20) playerCount.value += 1
}

function addRole(role: string) {
  if (canAddRole.value) currentRoles.value.push(role)
}
function removeRole(role: string) {
  const idx = currentRoles.value.indexOf(role)
  if (idx >= 0) currentRoles.value.splice(idx, 1)
}
function roleCount(role: string): number {
  return currentRoles.value.filter((r) => r === role).length
}

function applyPreset(roles: Record<string, number>) {
  const list: string[] = []
  for (const [role, n] of Object.entries(roles)) {
    for (let i = 0; i < n; i++) list.push(role)
  }
  currentRoles.value = list
  preferences.value = []
  showAddPref.value = false
}

function selectPrefPlayer(p: number) {
  if (newPref.value.player === p) {
    newPref.value = { player: null, roles: [] }
    return
  }
  newPref.value.player = p
  const existing = preferences.value.find((x) => x.player === p)
  newPref.value.roles = existing ? [...existing.roles].filter((r) => configuredRoles.value.includes(r)) : []
}

function togglePrefRole(role: string) {
  const idx = newPref.value.roles.indexOf(role)
  if (idx >= 0) newPref.value.roles.splice(idx, 1)
  else newPref.value.roles.push(role)
}

function confirmPref() {
  if (newPref.value.player == null || newPref.value.roles.length === 0) return
  const valid = newPref.value.roles.filter((r) => configuredRoles.value.includes(r))
  if (valid.length === 0) return
  const idx = preferences.value.findIndex((p) => p.player === newPref.value.player)
  const entry = { player: newPref.value.player!, roles: valid }
  if (idx >= 0) preferences.value[idx] = entry
  else preferences.value.push(entry)
  cancelPref()
}
function cancelPref() {
  showAddPref.value = false
  newPref.value = { player: null, roles: [] }
}
function removePref(idx: number) {
  preferences.value.splice(idx, 1)
}

function start() {
  if (!canStart.value) return
  const prefDict: Preferences = {}
  for (const p of preferences.value) prefDict[p.player] = [...p.roles]
  emit('start', { rolesList: [...currentRoles.value], preferences: prefDict })
}
</script>

<template>
  <div v-if="show" class="overlay" @click.self="$emit('close')">
    <div class="modal">
      <header>
        <h2>开始新游戏</h2>
        <button class="x" @click="$emit('close')">✕</button>
      </header>

      <section>
        <label>玩家数量</label>
        <div class="counter">
          <button @click="decPlayers" :disabled="playerCount <= 6">−</button>
          <span>{{ playerCount }} 人</span>
          <button @click="incPlayers" :disabled="playerCount >= 20">+</button>
        </div>
      </section>

      <section>
        <label>当前配置 · {{ currentRoles.length }} / {{ playerCount }}</label>
        <div v-if="currentRoles.length === 0" class="empty">从下方选择角色</div>
        <div v-else class="grid">
          <button
            v-for="(role, idx) in currentRoles"
            :key="`${role}-${idx}`"
            class="role-tile"
            @click="removeRole(role)"
          >
            <img :src="roleImageUrl(role)" :alt="role" />
            <span>{{ role }}</span>
          </button>
        </div>
      </section>

      <section v-if="matchingPresets.length > 0">
        <label>预设</label>
        <div class="preset-row">
          <button
            v-for="p in matchingPresets"
            :key="p.key"
            :class="['preset-btn', { history: p.isHistory }]"
            @click="applyPreset(p.roles)"
          >
            <div class="preset-title">{{ p.isHistory ? '历史' : `${playerCount}人` }}</div>
            <div class="preset-tags">
              <span v-for="(n, r) in p.roles" :key="r">{{ r }}×{{ n }}</span>
            </div>
          </button>
        </div>
      </section>

      <section>
        <label>可用角色{{ canAddRole ? '' : '（已选满）' }}</label>
        <div class="grid available">
          <button
            v-for="role in allRoles"
            :key="role"
            :disabled="!canAddRole"
            :class="['role-tile', { selected: roleCount(role) > 0 }]"
            @click="addRole(role)"
          >
            <img :src="roleImageUrl(role)" :alt="role" />
            <span>{{ role }}</span>
            <em v-if="roleCount(role) > 0">×{{ roleCount(role) }}</em>
          </button>
        </div>
      </section>

      <section v-if="configuredRoles.length > 0">
        <label>角色偏好（可选）— 偏好角色 4x 权重</label>
        <div v-if="preferences.length > 0" class="pref-list">
          <div v-for="(p, idx) in preferences" :key="p.player" class="pref-row">
            <span>玩家 {{ p.player }} → {{ p.roles.join('、') }}</span>
            <button class="x" @click="removePref(idx)">×</button>
          </div>
        </div>
        <button v-if="!showAddPref" class="add-pref" @click="showAddPref = true">+ 添加偏好</button>

        <div v-if="showAddPref" class="add-pref-form">
          <div class="sub-label">选择玩家</div>
          <div class="player-row">
            <button
              v-for="i in playerCount"
              :key="i"
              :class="['player-btn', { selected: newPref.player === i }]"
              @click="selectPrefPlayer(i)"
            >
              玩家 {{ i }}
            </button>
          </div>
          <div v-if="newPref.player != null" class="sub-label">选择角色（可多选）</div>
          <div v-if="newPref.player != null" class="grid">
            <button
              v-for="role in configuredRoles"
              :key="role"
              :class="['role-tile', { selected: newPref.roles.includes(role) }]"
              @click="togglePrefRole(role)"
            >
              <img :src="roleImageUrl(role)" :alt="role" />
              <span>{{ role }}</span>
            </button>
          </div>
          <div class="pref-actions">
            <button @click="cancelPref" class="cancel">取消</button>
            <button @click="confirmPref" :disabled="newPref.player == null || newPref.roles.length === 0" class="ok">
              确认
            </button>
          </div>
        </div>
      </section>

      <footer>
        <button @click="$emit('close')" class="cancel">取消</button>
        <button @click="start" :disabled="!canStart" class="start">开始游戏</button>
      </footer>
    </div>
  </div>
</template>

<style scoped>
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  z-index: 1500;
  padding: 16px;
  overflow-y: auto;
}
.modal {
  background: #232336;
  border: 1px solid var(--border);
  border-radius: 12px;
  width: 100%;
  max-width: 720px;
  padding: 16px;
  margin: 16px 0 32px;
}
header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
h2 { margin: 0; font-size: 1.4rem; }
section { margin-bottom: 18px; }
label { display: block; margin-bottom: 8px; color: var(--fg-dim); font-weight: 500; }
.sub-label { color: var(--fg-dim); margin: 10px 0 6px; font-size: 0.9rem; }
.empty {
  padding: 14px;
  text-align: center;
  background: var(--bg-soft);
  border-radius: 8px;
  color: var(--fg-dim);
}
.counter {
  display: flex;
  align-items: center;
  gap: 16px;
  justify-content: center;
}
.counter span { font-size: 1.3rem; font-weight: bold; min-width: 80px; text-align: center; }
.counter button {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg-soft);
  color: var(--fg);
  font-size: 1.4rem;
}
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
  gap: 8px;
}
.grid.available .role-tile { border: 2px solid rgba(124, 58, 237, 0.4); }
.role-tile {
  background: var(--bg-soft);
  border: 2px solid transparent;
  border-radius: 8px;
  overflow: hidden;
  padding: 0;
  position: relative;
  color: var(--fg);
  cursor: pointer;
  transition: transform 0.15s;
}
.role-tile.selected { border-color: var(--ok); }
.role-tile img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  display: block;
}
.role-tile span {
  display: block;
  font-size: 0.78rem;
  padding: 4px 2px;
  background: rgba(0, 0, 0, 0.45);
  text-align: center;
}
.role-tile em {
  position: absolute;
  top: 4px;
  right: 4px;
  background: var(--ok);
  font-style: normal;
  font-size: 0.7rem;
  padding: 2px 6px;
  border-radius: 4px;
  color: white;
  font-weight: bold;
}
.preset-row { display: flex; flex-wrap: wrap; gap: 8px; }
.preset-btn {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  color: var(--fg);
  text-align: left;
}
.preset-btn.history { background: rgba(76, 175, 80, 0.12); border-color: rgba(76, 175, 80, 0.35); }
.preset-title { font-weight: bold; }
.preset-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; font-size: 0.78rem; }
.preset-tags span { background: rgba(255, 255, 255, 0.08); padding: 2px 6px; border-radius: 4px; }

.pref-list { display: flex; flex-direction: column; gap: 6px; }
.pref-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background: rgba(76, 175, 80, 0.12);
  border-radius: 6px;
}
.add-pref {
  background: rgba(33, 150, 243, 0.12);
  color: #4ea7f7;
  border: 1px solid rgba(33, 150, 243, 0.4);
  padding: 8px 14px;
  border-radius: 6px;
  margin-top: 8px;
}
.add-pref-form {
  margin-top: 12px;
  padding: 12px;
  background: var(--bg-soft);
  border-radius: 8px;
}
.player-row { display: flex; flex-wrap: wrap; gap: 6px; }
.player-btn {
  padding: 6px 10px;
  border-radius: 6px;
  border: 2px solid var(--border);
  background: var(--bg-soft);
  color: var(--fg);
}
.player-btn.selected { background: var(--accent); border-color: var(--accent); color: white; }
.pref-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 12px; }

footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

button.x {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  background: transparent;
  color: var(--fg-dim);
  border: 1px solid var(--border);
  font-size: 1.1rem;
}
button.cancel {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--fg);
  padding: 10px 18px;
  border-radius: 8px;
}
button.start, button.ok {
  background: var(--ok);
  border: none;
  color: white;
  padding: 10px 18px;
  border-radius: 8px;
  font-weight: bold;
}
button.start:disabled, button.ok:disabled { background: rgba(255, 255, 255, 0.15); color: rgba(255, 255, 255, 0.4); }
</style>
