<script setup lang="ts">
/**
 * ServerCard — server instance summary card.
 * Sets :data-game so per-game accent token re-skins apply via the global [data-game] selector.
 * Status drives the dot + left rail color.
 * `offline` dims the card and swaps the power IconButton to a Start action.
 * Pending state shows when status==='online' && cpu==null && ram==null.
 */
import { computed } from '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 ResourceMeter from './ResourceMeter.vue'

export interface StatItem {
  label: string
  value: string | number
}

const props = withDefaults(
  defineProps<{
    game?: string
    gameIcon?: string
    name: string
    region?: string
    map?: string
    version?: string
    status?: 'online' | 'offline' | 'starting' | 'wiping' | 'updating'
    players?: { cur: number; max: number }
    cpu?: number
    ram?: number
    ramSub?: string
    ip?: string
    stats?: StatItem[]
  }>(),
  {
    game: 'rust',
    gameIcon: 'box',
    status: 'online',
    players: () => ({ cur: 0, max: 0 }),
  },
)

const emit = defineEmits<{
  console: []
  settings: []
  power: []
}>()

interface StatusEntry {
  tone: 'online' | 'offline' | 'warn' | 'info' | 'starting' | 'wiping' | 'neutral' | 'accent'
  label: string
  pulse: boolean
}

const DEFAULT_STATUS: StatusEntry = { tone: 'online', label: 'Online', pulse: true }

const STATUS_MAP: Record<string, StatusEntry> = {
  online:   { tone: 'online',   label: 'Online',   pulse: true },
  offline:  { tone: 'offline',  label: 'Offline',  pulse: false },
  starting: { tone: 'starting', label: 'Booting',  pulse: true },
  wiping:   { tone: 'wiping',   label: 'Wiping',   pulse: true },
  updating: { tone: 'starting', label: 'Updating', pulse: true },
}

const st = computed<StatusEntry>(() => STATUS_MAP[props.status ?? 'online'] ?? DEFAULT_STATUS)
const offline = computed(() => props.status === 'offline')

const statList = computed<StatItem[]>(() => {
  if (props.stats) return props.stats
  const items: StatItem[] = [
    { label: 'Players', value: `${props.players?.cur ?? 0} / ${props.players?.max ?? 0}` },
  ]
  if (props.version) {
    items.push({ label: 'Build', value: props.version })
  }
  return items
})

const pending = computed(
  () => props.status === 'online' && props.cpu == null && props.ram == null,
)

const showMeters = computed(
  () => !offline.value && (props.cpu != null || props.ram != null),
)
</script>

<template>
  <div
    :data-game="game"
    :class="['cc-server', offline && 'cc-server--offline']"
  >
    <!-- Head -->
    <div class="cc-server__head">
      <div class="cc-server__game">
        <Icon :name="gameIcon" :size="18" :stroke-width="2" />
      </div>
      <div class="cc-server__id">
        <div class="cc-server__name">
          {{ name }}
          <Badge :tone="st.tone" dot :pulse="st.pulse">{{ st.label }}</Badge>
        </div>
        <div class="cc-server__meta">
          <span v-if="region">{{ region }}</span>
          <span v-if="map">{{ map }}</span>
          <span v-if="ip">{{ ip }}</span>
        </div>
      </div>
      <div class="cc-server__actions">
        <IconButton icon="terminal" variant="ghost" size="sm" label="Console" @click="emit('console')" />
        <IconButton icon="settings" variant="ghost" size="sm" label="Settings" @click="emit('settings')" />
        <IconButton
          :icon="offline ? 'play' : 'power'"
          :variant="offline ? 'accent' : 'ghost'"
          size="sm"
          :label="offline ? 'Start' : 'Power'"
          @click="emit('power')"
        />
      </div>
    </div>

    <!-- Body -->
    <div class="cc-server__body">
      <div class="cc-server__stats">
        <div v-for="(s, i) in statList" :key="i" class="cc-server__stat">
          <b>{{ s.value }}</b>
          <span>{{ s.label }}</span>
        </div>
      </div>

      <div v-if="showMeters" class="cc-server__meters">
        <ResourceMeter v-if="cpu != null" label="CPU" :value="cpu" />
        <ResourceMeter v-if="ram != null" label="RAM" :value="ram" :sub="ramSub" />
      </div>

      <div v-if="pending" class="cc-server__pending">
        <Icon name="loader" :size="13" :stroke-width="2.5" />
        Telemetry pending · agent monitoring
      </div>
    </div>
  </div>
</template>

<style>
.cc-server { position: relative; background: var(--surface-base); border-radius: var(--radius-lg); box-shadow: var(--ring-default); overflow: hidden; transition: var(--transition-colors); }
.cc-server::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--accent); opacity: .9; }
.cc-server:hover { box-shadow: inset 0 0 0 1px var(--border-strong); }
.cc-server--offline::before { background: var(--status-offline); }
.cc-server--offline { opacity: .82; }
.cc-server__head { display: flex; align-items: center; gap: 12px; padding: 14px 14px 12px 17px; }
.cc-server__game { width: 34px; height: 34px; border-radius: var(--radius-md); flex: none; 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); }
.cc-server__id { flex: 1; min-width: 0; }
.cc-server__name { font-size: var(--text-base); font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 8px; }
.cc-server__meta { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-tertiary); margin-top: 2px; display: flex; gap: 10px; }
.cc-server__body { padding: 0 14px 13px 17px; display: flex; flex-direction: column; gap: 11px; }
.cc-server__stats { display: flex; gap: 18px; }
.cc-server__stat { display: flex; flex-direction: column; gap: 1px; }
.cc-server__stat b { font-family: var(--font-mono); font-weight: 600; font-size: var(--text-sm); color: var(--text-primary); font-variant-numeric: tabular-nums; }
.cc-server__stat span { font-size: 10px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .06em; }
.cc-server__meters { display: flex; gap: 14px; }
.cc-server__meters > * { flex: 1; }
.cc-server__pending { display: flex; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); }
.cc-server__pending .cc-icon { color: var(--status-starting); }
.cc-server__actions { display: flex; gap: 5px; }
</style>
