<template>
  <div class="updates-page">
    <div class="page-header">
      <h2>{{ t('nav.updates') }}</h2>
      <p class="text-muted">{{ t('updates.desc') }}</p>
    </div>

    <!-- Sélection de la cible -->
    <div class="neu-card target-card">
      <h3>{{ t('updates.selectTarget') }}</h3>
      <div class="targets">
        <button
          v-for="target in targets"
          :key="target.value"
          :class="['neu-btn', selectedTarget === target.value ? 'neu-btn--primary' : '']"
          @click="selectedTarget = target.value"
        >
          {{ t(target.label) }}
        </button>
      </div>
      <button
        class="neu-btn neu-btn--success"
        :disabled="!selectedTarget || running"
        @click="startUpdate"
        style="margin-top: var(--neu-space-md);"
      >
        {{ running ? t('updates.running') : t('updates.start') }}
      </button>
    </div>

    <!-- Terminal de sortie -->
    <div v-if="currentJob" class="neu-card output-card">
      <div class="output-header flex items-center justify-between">
        <h3>{{ t('updates.output') }}</h3>
        <span :class="['neu-badge', jobStatus === 'success' ? 'neu-badge--success' : jobStatus === 'error' ? 'neu-badge--danger' : 'neu-badge--warning']">
          {{ t(`updates.status.${jobStatus}`) }}
        </span>
      </div>
      <div class="output-terminal neu-inset" ref="terminalEl">
        <pre class="output-text">{{ outputText }}</pre>
      </div>
    </div>

    <!-- Historique -->
    <div class="neu-card">
      <h3>{{ t('updates.history') }}</h3>
      <div v-if="history.length === 0" class="empty-state">
        <p class="text-muted">{{ t('updates.noHistory') }}</p>
      </div>
      <div v-else class="history-list">
        <div v-for="entry in history" :key="entry.job_id" class="history-item">
          <div class="history-meta flex items-center gap-sm">
            <span :class="['neu-badge', entry.status === 'success' ? 'neu-badge--success' : entry.status === 'error' ? 'neu-badge--danger' : 'neu-badge--warning']">
              {{ t(`updates.status.${entry.status}`) }}
            </span>
            <span class="history-target">{{ entry.target }}</span>
            <span class="text-muted history-date">{{ formatDate(entry.started_at) }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAuthStore } from '@/stores/auth.store'

const { t } = useI18n()
const authStore = useAuthStore()

const selectedTarget = ref('host')
const running = ref(false)
const currentJob = ref<string | null>(null)
const outputText = ref('')
const jobStatus = ref('running')
const history = ref<any[]>([])
const terminalEl = ref<HTMLElement | null>(null)

let wsConnection: WebSocket | null = null

const targets = [
  { value: 'host', label: 'updates.targetHost' },
  { value: 'all', label: 'updates.targetAll' },
]

onMounted(loadHistory)
onUnmounted(() => wsConnection?.close())

async function loadHistory() {
  const res = await fetch('/api/updates/history', {
    headers: { Authorization: `Bearer ${authStore.accessToken}` },
  })
  if (res.ok) history.value = await res.json() || []
}

async function startUpdate() {
  running.value = true
  outputText.value = ''
  jobStatus.value = 'running'

  const res = await fetch('/api/updates/run', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${authStore.accessToken}`,
    },
    body: JSON.stringify({ target: selectedTarget.value }),
  })

  if (!res.ok) {
    running.value = false
    return
  }

  const data = await res.json()
  currentJob.value = data.job_id

  // Connecter le WebSocket de streaming
  const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
  wsConnection = new WebSocket(`${proto}//${window.location.host}/ws/updates/${data.job_id}?token=${authStore.accessToken}`)

  wsConnection.onmessage = async (event) => {
    const msg = JSON.parse(event.data)

    if (msg.type === 'update_output' && msg.payload?.chunk) {
      outputText.value += msg.payload.chunk
      await nextTick()
      if (terminalEl.value) {
        terminalEl.value.scrollTop = terminalEl.value.scrollHeight
      }
    } else if (msg.type === 'update_done') {
      jobStatus.value = 'success'
      running.value = false
      wsConnection?.close()
      loadHistory()
    } else if (msg.type === 'update_error') {
      jobStatus.value = 'error'
      running.value = false
      wsConnection?.close()
    }
  }
}

function formatDate(iso: string): string {
  return new Date(iso).toLocaleString()
}
</script>

<style scoped>
.updates-page { max-width: 900px; display: flex; flex-direction: column; gap: var(--neu-space-lg); }

.page-header h2 { font-size: var(--neu-font-xl); color: var(--neu-text); }
.text-muted { color: var(--neu-text-muted); }

.target-card h3, .output-card h3 { margin-bottom: var(--neu-space-md); color: var(--neu-text); }

.targets { display: flex; flex-wrap: wrap; gap: var(--neu-space-sm); }

.output-header { margin-bottom: var(--neu-space-sm); }

.output-terminal {
  height: 400px;
  overflow-y: auto;
  padding: var(--neu-space-md);
  font-family: 'Courier New', monospace;
  font-size: 12px;
}

.output-text {
  color: var(--neu-success);
  white-space: pre-wrap;
  word-break: break-all;
  margin: 0;
}

.empty-state { padding: var(--neu-space-md) 0; }

.history-list { display: flex; flex-direction: column; gap: var(--neu-space-sm); }

.history-item { padding: var(--neu-space-sm) 0; border-bottom: 1px solid var(--neu-border); }
.history-item:last-child { border-bottom: none; }

.history-target { font-size: var(--neu-font-sm); color: var(--neu-text); font-family: monospace; }
.history-date { font-size: var(--neu-font-xs); }
</style>
