<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useServerStore } from '@/stores/server'
import { useApi } from '@/composables/useApi'
import { useToastStore } from '@/stores/toast'
import { useThemeGame } from '@/composables/useThemeGame'
import Panel from '@/components/ds/data/Panel.vue'
import Button from '@/components/ds/core/Button.vue'
import Badge from '@/components/ds/core/Badge.vue'
import Icon from '@/components/ds/core/Icon.vue'
import IconButton from '@/components/ds/core/IconButton.vue'
import Input from '@/components/ds/forms/Input.vue'
import EmptyState from '@/components/ds/feedback/EmptyState.vue'
import Tabs from '@/components/ds/navigation/Tabs.vue'

const server = useServerStore()
const api = useApi()
const toast = useToastStore()
const { activeGame } = useThemeGame()
const playerIdLabel = computed(() => activeGame.value === 'rust' || activeGame.value === 'all' ? 'Steam ID' : 'Player ID')

interface Player {
  steam_id: string
  display_name: string
  is_online: boolean
  ping_ms: number | null
  connected_at: string | null
  playtime_seconds: number
  is_admin: boolean
  is_banned: boolean
}

const players = ref<Player[]>([])
const isLoading = ref(false)
const searchQuery = ref('')
const filterStatus = ref<'all' | 'online' | 'offline'>('all')

const filteredPlayers = computed(() => {
  let result = players.value

  if (filterStatus.value === 'online') {
    result = result.filter(p => p.is_online)
  } else if (filterStatus.value === 'offline') {
    result = result.filter(p => !p.is_online)
  }

  if (searchQuery.value.trim()) {
    const q = searchQuery.value.toLowerCase()
    result = result.filter(p =>
      p.display_name.toLowerCase().includes(q) ||
      p.steam_id.includes(q)
    )
  }

  return result.sort((a, b) => {
    if (a.is_online !== b.is_online) return a.is_online ? -1 : 1
    return a.display_name.localeCompare(b.display_name)
  })
})

const onlineCount = computed(() => players.value.filter(p => p.is_online).length)

const statusTabItems = computed(() => [
  { value: 'all', label: 'All', count: players.value.length },
  { value: 'online', label: 'Online', count: players.value.filter(p => p.is_online).length },
  { value: 'offline', label: 'Offline', count: players.value.filter(p => !p.is_online).length },
])

function formatPlaytime(seconds: number): string {
  const h = Math.floor(seconds / 3600)
  const m = Math.floor((seconds % 3600) / 60)
  if (h > 0) return `${h}h ${m}m`
  return `${m}m`
}

function formatConnectedTime(iso: string | null): string {
  if (!iso) return '—'
  const diff = Date.now() - new Date(iso).getTime()
  const m = Math.floor(diff / 60000)
  const h = Math.floor(m / 60)
  if (h > 0) return `${h}h ${m % 60}m`
  return `${m}m`
}

function playerStatusTone(player: Player): 'online' | 'offline' | 'warn' {
  if (player.is_banned) return 'warn'
  if (player.is_online) return 'online'
  return 'offline'
}

function playerStatusLabel(player: Player): string {
  if (player.is_banned) return 'Banned'
  if (player.is_online) return 'Online'
  return 'Offline'
}

async function fetchPlayers() {
  isLoading.value = true
  try {
    const data = await api.get<{ players: Player[] }>('/players')
    players.value = data.players
  } catch {
    toast.error('Failed to load player list')
  } finally {
    isLoading.value = false
  }
}

async function kickPlayer(steamId: string, name: string) {
  if (!confirm(`Kick ${name}?`)) return
  try {
    await server.sendCommand(`kick ${steamId}`)
    toast.success(`Kick command sent for ${name}`)
    await fetchPlayers()
  } catch {
    toast.error(`Failed to kick ${name}`)
  }
}

async function banPlayer(steamId: string, name: string) {
  if (!confirm(`Ban ${name}? This will also kick them.`)) return
  try {
    await server.sendCommand(`ban ${steamId}`)
    toast.success(`Ban command sent for ${name}`)
    await fetchPlayers()
  } catch {
    toast.error(`Failed to ban ${name}`)
  }
}

onMounted(() => {
  fetchPlayers()
})
</script>

<template>
  <div class="pv">
    <!-- Page head -->
    <div class="pv__head">
      <div class="pv__head-id">
        <div class="pv__head-chip">
          <Icon name="users" :size="20" :stroke-width="2" />
        </div>
        <div>
          <div class="t-eyebrow">Player management</div>
          <h1 class="pv__title">Players</h1>
        </div>
      </div>
      <div class="pv__head-actions">
        <div class="pv__stat-pill">
          <span class="pv__stat-num">{{ onlineCount }}</span>
          <span class="pv__stat-sep">/</span>
          <span class="pv__stat-total">{{ players.length }}</span>
          <Badge tone="online" :dot="true" :pulse="onlineCount > 0">Online</Badge>
        </div>
        <Button
          variant="secondary"
          size="sm"
          icon="refresh-cw"
          :loading="isLoading"
          :disabled="isLoading"
          @click="fetchPlayers"
        >Refresh</Button>
      </div>
    </div>

    <!-- Filters -->
    <div class="pv__filters">
      <Input
        v-model="searchQuery"
        icon="search"
        :placeholder="`Search by name or ${playerIdLabel}…`"
        size="sm"
        :mono="false"
        style="max-width: 320px;"
      />
      <Tabs v-model="filterStatus" :items="statusTabItems" />
    </div>

    <!-- Player table -->
    <Panel :flush-body="true">
      <!-- Empty state -->
      <EmptyState
        v-if="filteredPlayers.length === 0 && !isLoading"
        icon="users"
        :title="searchQuery ? 'No players found' : 'No players'"
        :description="searchQuery
          ? `No players matching &quot;${searchQuery}&quot;.`
          : 'No players found. Server may be offline or API not connected.'"
      />

      <!-- Loading state -->
      <div v-else-if="isLoading && filteredPlayers.length === 0" class="pv__loading">
        <Icon name="loader" :size="20" class="pv__spin" />
        <span>Loading players…</span>
      </div>

      <!-- Table -->
      <table v-else class="pv__table">
        <thead>
          <tr>
            <th>Player</th>
            <th>{{ playerIdLabel }}</th>
            <th>Status</th>
            <th>Session</th>
            <th>Playtime</th>
            <th>Ping</th>
            <th class="pv__th-right">Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr
            v-for="player in filteredPlayers"
            :key="player.steam_id"
          >
            <td>
              <div class="pv__player-name">
                <span class="pv__name">{{ player.display_name }}</span>
                <Badge v-if="player.is_admin" tone="accent" size="md">Admin</Badge>
              </div>
            </td>
            <td class="pv__mono">{{ player.steam_id }}</td>
            <td>
              <Badge
                :tone="playerStatusTone(player)"
                :dot="true"
                :pulse="player.is_online && !player.is_banned"
              >{{ playerStatusLabel(player) }}</Badge>
            </td>
            <td class="pv__secondary">
              {{ player.is_online ? formatConnectedTime(player.connected_at) : '—' }}
            </td>
            <td class="pv__secondary pv__mono">{{ formatPlaytime(player.playtime_seconds) }}</td>
            <td class="pv__secondary pv__mono">
              {{ player.is_online && player.ping_ms ? `${player.ping_ms}ms` : '—' }}
            </td>
            <td class="pv__td-right">
              <div v-if="player.is_online" class="pv__row-actions">
                <IconButton
                  icon="log-out"
                  variant="ghost"
                  size="sm"
                  label="Kick"
                  @click="kickPlayer(player.steam_id, player.display_name)"
                />
                <IconButton
                  icon="ban"
                  variant="danger"
                  size="sm"
                  label="Ban"
                  @click="banPlayer(player.steam_id, player.display_name)"
                />
              </div>
            </td>
          </tr>
        </tbody>
      </table>
    </Panel>
  </div>
</template>

<style scoped>
.pv { max-width: 1200px; margin: 0 auto; display: flex; flex-direction: column; gap: 16px; }

/* Page head */
.pv__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  flex-wrap: wrap; gap: 12px;
}
.pv__head-id { display: flex; align-items: center; gap: 12px; }
.pv__head-chip {
  width: 40px; height: 40px; flex: none; border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  color: var(--accent); background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-border);
}
.pv__title {
  font-size: var(--text-2xl); font-weight: 700; letter-spacing: -0.02em;
  color: var(--text-primary); margin-top: 3px;
}
.pv__head-actions { display: flex; align-items: center; gap: 12px; }

/* Stat pill */
.pv__stat-pill {
  display: flex; align-items: center; gap: 7px;
  font-family: var(--font-mono); font-size: var(--text-sm); font-variant-numeric: tabular-nums;
}
.pv__stat-num { font-weight: 700; color: var(--status-online); }
.pv__stat-sep { color: var(--text-muted); }
.pv__stat-total { color: var(--text-tertiary); }

/* Filters */
.pv__filters { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

/* Loading */
.pv__loading {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 48px; color: var(--text-tertiary); font-size: var(--text-sm);
}
@keyframes pv-spin { to { transform: rotate(360deg); } }
.pv__spin { animation: pv-spin 0.7s linear infinite; }

/* Table */
.pv__table { width: 100%; border-collapse: collapse; }
.pv__table th {
  padding: 10px 14px; text-align: left;
  font-size: var(--text-xs); font-weight: 600; color: var(--text-tertiary);
  text-transform: uppercase; letter-spacing: var(--tracking-wider);
  border-bottom: 1px solid var(--border-subtle);
}
.pv__table td {
  padding: 10px 14px; font-size: var(--text-sm);
  color: var(--text-primary); border-bottom: 1px solid var(--border-subtle);
}
.pv__table tbody tr:last-child td { border-bottom: 0; }
.pv__table tbody tr:hover td { background: var(--surface-hover); }

/* Col helpers */
.pv__th-right { text-align: right; }
.pv__td-right { text-align: right; }
.pv__mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--text-xs) !important; color: var(--text-secondary) !important; }
.pv__secondary { color: var(--text-secondary) !important; }

/* Player name cell */
.pv__player-name { display: flex; align-items: center; gap: 8px; }
.pv__name { font-weight: 500; }

/* Row actions */
.pv__row-actions { display: flex; align-items: center; justify-content: flex-end; gap: 2px; }
</style>
