<template>
  <div class="terminal-page">
    <div class="page-header flex items-center justify-between">
      <h2>{{ t('nav.terminal') }}</h2>
      <div class="flex gap-sm">
        <input v-model="customHost" class="neu-input" placeholder="host:port (défaut: config)" style="width:200px" />
        <button class="neu-btn neu-btn--primary" @click="reconnect">
          {{ connected ? t('terminal.reconnect') : t('terminal.connect') }}
        </button>
      </div>
    </div>

    <div class="neu-card terminal-container">
      <div class="terminal-status flex items-center gap-sm">
        <span :class="['ws-dot', connected ? 'ws-dot--connected' : 'ws-dot--disconnected']" />
        <span class="text-muted" style="font-size:11px">
          {{ connected ? t('terminal.connected', { host: currentHost }) : t('terminal.disconnected') }}
        </span>
      </div>
      <!-- Conteneur xterm.js -->
      <div ref="terminalContainer" class="terminal-xterm" />
    </div>
  </div>
</template>

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

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

const terminalContainer = ref<HTMLElement | null>(null)
const customHost = ref('')
const connected = ref(false)
const currentHost = ref('')

let terminal: Terminal | null = null
let fitAddon: FitAddon | null = null
let ws: WebSocket | null = null

onMounted(() => {
  // Initialiser xterm.js
  terminal = new Terminal({
    theme: {
      background: 'var(--neu-bg, #1a1d2e)',
      foreground: '#e2e6f6',
      cursor: '#6c8ef4',
    },
    fontFamily: '"Courier New", Courier, monospace',
    fontSize: 13,
    cursorBlink: true,
    scrollback: 1000,
  })

  fitAddon = new FitAddon()
  terminal.loadAddon(fitAddon)
  terminal.open(terminalContainer.value!)
  fitAddon.fit()

  // Observer le redimensionnement
  const ro = new ResizeObserver(() => fitAddon?.fit())
  if (terminalContainer.value) ro.observe(terminalContainer.value)

  // Connexion automatique
  connect()
})

onUnmounted(() => {
  ws?.close()
  terminal?.dispose()
})

function connect() {
  ws?.close()

  const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
  const hostParam = customHost.value ? `&host=${encodeURIComponent(customHost.value)}` : ''
  const url = `${proto}//${window.location.host}/ws/terminal?token=${authStore.accessToken}${hostParam}`

  ws = new WebSocket(url)
  ws.binaryType = 'arraybuffer'

  ws.onopen = () => {
    connected.value = true
    currentHost.value = customHost.value || 'ssh_host configuré'
    terminal?.write('\r\n\x1b[32mConnecté au terminal SSH\x1b[0m\r\n\r\n')
  }

  ws.onclose = () => {
    connected.value = false
    terminal?.write('\r\n\x1b[31mDéconnecté\x1b[0m\r\n')
  }

  ws.onmessage = (event) => {
    if (event.data instanceof ArrayBuffer) {
      terminal?.write(new Uint8Array(event.data))
    } else {
      terminal?.write(event.data)
    }
  }

  ws.onerror = () => {
    terminal?.write('\r\n\x1b[31mErreur de connexion WebSocket\x1b[0m\r\n')
  }

  // Envoyer les frappes clavier au serveur SSH
  terminal?.onData((data) => {
    if (ws?.readyState === WebSocket.OPEN) {
      ws.send(data)
    }
  })

  // Envoyer le resize au serveur
  terminal?.onResize(({ cols, rows }) => {
    if (ws?.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({ type: 'resize', cols, rows }))
    }
  })
}

function reconnect() {
  terminal?.clear()
  connect()
}
</script>

<style scoped>
.terminal-page { height: 100%; display: flex; flex-direction: column; max-width: 1200px; }

.page-header { margin-bottom: var(--neu-space-lg); flex-shrink: 0; }
.page-header h2 { font-size: var(--neu-font-xl); color: var(--neu-text); }
.text-muted { color: var(--neu-text-muted); }

.terminal-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: var(--neu-space-sm);
}

.terminal-status {
  padding: var(--neu-space-xs) var(--neu-space-sm);
  border-bottom: 1px solid var(--neu-border);
  margin-bottom: var(--neu-space-sm);
  flex-shrink: 0;
}

.terminal-xterm {
  flex: 1;
  min-height: 400px;
}

.ws-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.ws-dot--connected { background: var(--neu-success); animation: neu-pulse 2s infinite; }
.ws-dot--disconnected { background: var(--neu-text-muted); }
</style>
