<template>
  <main style="font-family: system-ui, sans-serif; padding: 16px; max-width: 980px; margin: 0 auto;">
    <h1>RADIUS Dashboard</h1>
    <section style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start;">
      <div>
        <h2>Usuarios</h2>
        <form @submit.prevent="createUser" style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px;">
          <input v-model="form.username" placeholder="usuario" required />
          <input v-model="form.password" placeholder="contraseña" required />
          <input v-model="form.vlan" placeholder="VLAN" />
          <label><input type="checkbox" v-model="form.disabled" /> deshabilitado</label>
          <button type="submit">Crear / Actualizar</button>
        </form>
        <div v-if="loading.users">Cargando usuarios…</div>
        <table v-else style="width: 100%; border-collapse: collapse;">
          <thead>
            <tr>
              <th style="text-align:left">Usuario</th>
              <th style="text-align:left">VLAN</th>
              <th style="text-align:left">Estado</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="u in users" :key="u.username">
              <td>{{ u.username }}</td>
              <td>{{ u.vlan }}</td>
              <td>{{ u.disabled ? 'deshabilitado' : 'activo' }}</td>
              <td>
                <button @click="toggleDisable(u)">{{ u.disabled ? 'Habilitar' : 'Deshabilitar' }}</button>
                <button @click="removeUser(u)" style="margin-left: 6px">Eliminar</button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
      <div>
        <h2>Eventos</h2>
        <div style="margin-bottom: 8px; display:flex; gap:8px;">
          <button @click="refreshRequests">Refrescar</button>
          <button @click="clearRequests">Limpiar</button>
          <button @click="selfTest">Self test</button>
          <a :href="'/api/requests.csv'" target="_blank">Descargar CSV</a>
        </div>
        <div v-if="loading.requests">Cargando eventos…</div>
        <div v-else style="max-height: 420px; overflow: auto; border: 1px solid #ddd; padding: 8px;">
          <div v-for="ev in requests" :key="ev.id" style="border-bottom: 1px dashed #ddd; padding: 6px 0;">
            <div><b>{{ ev.ts }}</b> — {{ ev.type }}</div>
            <div v-if="ev.attrs" style="font-size: 12px; color: #444;">
              <span>User: {{ ev.attrs['User-Name'] || ev.attrs['User-Name*0'] }}</span>
              <span v-if="ev.attrs['NAS-IP-Address']"> — NAS: {{ ev.attrs['NAS-IP-Address'] }}</span>
              <span v-if="ev.attrs['Calling-Station-Id']"> — STA: {{ ev.attrs['Calling-Station-Id'] }}</span>
            </div>
            <div v-if="ev.decision">Decision: {{ ev.decision }}</div>
            <div v-if="ev.error" style="color: #a00;">Error: {{ ev.error }}</div>
          </div>
        </div>
      </div>
    </section>
  </main>
</template>

<script setup>
import { onMounted, reactive, ref } from 'vue';

const users = ref([]);
const requests = ref([]);
const loading = reactive({ users: false, requests: false });
const form = reactive({ username: '', password: '', vlan: '', disabled: false });

async function fetchUsers() {
  loading.users = true;
  try {
    const res = await fetch('/api/users');
    const data = await res.json();
    users.value = data.items || [];
  } finally { loading.users = false; }
}

async function fetchRequests() {
  loading.requests = true;
  try {
    const res = await fetch('/api/requests');
    const data = await res.json();
    requests.value = data.items || [];
  } finally { loading.requests = false; }
}

async function createUser() {
  const payload = { ...form };
  if (!payload.vlan) delete payload.vlan;
  await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) });
  form.username = '';
  form.password = '';
  form.vlan = '';
  form.disabled = false;
  await fetchUsers();
}

async function toggleDisable(u) {
  await fetch(`/api/users/${encodeURIComponent(u.username)}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ disabled: !u.disabled })
  });
  await fetchUsers();
}

async function removeUser(u) {
  if (!confirm(`Eliminar ${u.username}?`)) return;
  await fetch(`/api/users/${encodeURIComponent(u.username)}`, { method: 'DELETE' });
  await fetchUsers();
}

async function refreshRequests() { await fetchRequests(); }

async function clearRequests() {
  await fetch('/api/requests', { method: 'DELETE' });
  await fetchRequests();
}

async function selfTest() {
  await fetch('/test/radius', { method: 'POST' });
}

function setupSse() {
  const ev = new EventSource('/api/events');
  ev.addEventListener('message', (e) => {
    try {
      const data = JSON.parse(e.data);
      if (data && data.ts) requests.value.push(data);
    } catch {}
  });
  ev.addEventListener('clear', () => { requests.value = []; });
}

onMounted(async () => {
  await fetchUsers();
  await fetchRequests();
  setupSse();
});
</script>

<style>
html, body { margin: 0; padding: 0; }
table th, table td { padding: 4px 6px; border-bottom: 1px solid #eee; }
button { padding: 6px 10px; cursor: pointer; }
input { padding: 6px 8px; }
</style>
