<template>
  <div>
    <div class="page-header">
      <div class="page-title">
        <h2>API Keys</h2>
        <span class="subtitle">Long-lived tokens for non-interactive service access — scoped by permission mask</span>
      </div>
      <NychButton @click="showCreate = true" label="+ New Key" />
    </div>

    <div class="table-card">
      <div class="table-card-header">
        <span class="count">{{ keys.length }} {{ keys.length === 1 ? 'key' : 'keys' }}</span>
      </div>
      <div v-if="loading" class="loading-overlay">
        <div class="loading-spinner"></div>
        <span>Loading…</span>
      </div>
      <template v-else-if="keys.length"><div class="table-scroll"><table class="data-table">
        <thead>
          <tr>
            <th>Name</th>
            <th>Prefix</th>
            <th>Role</th>
            <th>Mask</th>
            <th>Created</th>
            <th>Expires</th>
            <th>Last used</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="k in keys" :key="k.id">
            <td class="name-cell">{{ k.name }}</td>
            <td><code class="prefix-cell">mrc_{{ k.key_prefix }}…</code></td>
            <td><span class="role-badge" :class="roleBadgeClass(k.permissions_mask)">{{ roleName(k.permissions_mask) }}</span></td>
            <td><code>{{ k.permissions_mask }}</code></td>
            <td class="date-cell">{{ fmtDate(k.created_at) }}</td>
            <td class="date-cell">{{ k.expires_at ? fmtDate(k.expires_at) : '—' }}</td>
            <td class="date-cell">{{ k.last_used_at ? fmtDate(k.last_used_at) : 'Never' }}</td>
            <td class="actions-cell">
              <NychButton size="small" severity="danger" @click="revoke(k.id, k.name)" label="Revoke" />
            </td>
          </tr>
        </tbody>
      </table></div></template>
      <div class="empty-state" v-else>
        <span class="empty-icon">⚿</span>
        <span class="empty-label">No API keys</span>
        <span class="empty-hint">Create a key to allow service-to-service access without user credentials.</span>
      </div>
    </div>

    <!-- Create dialog -->
    <NychDialog v-model:visible="showCreate" header="New API Key" :modal="true" :draggable="false" style="width: min(560px, 95vw)">
      <form @submit.prevent="submitCreate" class="dialog-form">
        <div class="field">
          <label>Name</label>
          <NychInputText v-model="form.name" placeholder="e.g. CI pipeline, data importer" fluid />
        </div>
        <div class="field">
          <label>Role</label>
          <NychSelect v-model="form.permissions_mask" :options="ROLES" optionLabel="label" optionValue="value" placeholder="Select a role" fluid />
          <p class="hint">{{ ROLES.find(r => r.value === form.permissions_mask)?.description ?? '' }}</p>
        </div>
        <div class="field">
          <label>Expires <span class="optional">(optional — leave blank for no expiry)</span></label>
          <NychInputText v-model="form.expires_at" type="datetime-local" fluid />
        </div>
        <NychButton type="submit" :disabled="!form.name || !form.permissions_mask" fluid label="Generate Key" />
      </form>
    </NychDialog>

    <!-- Key reveal dialog — shown once after creation -->
    <NychDialog v-model:visible="showReveal" header="API Key Created" :modal="true" :draggable="false" :closable="false" style="width: min(600px, 95vw)">
      <div class="reveal-body">
        <NychMessage severity="warn" class="reveal-warning">
          Copy this key now — it will <strong>not</strong> be shown again.
        </NychMessage>
        <div class="key-display">
          <code class="key-text">{{ newKey }}</code>
          <button type="button" class="copy-btn" :class="{ copied }" @click="copyKey" title="Copy to clipboard">
            {{ copied ? '✓' : '⎘' }}
          </button>
        </div>
        <NychButton fluid @click="closeReveal" label="I've saved the key" />
      </div>
    </NychDialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useAuthStore } from '../../stores/auth'

const auth = useAuthStore()
const keys = ref<any[]>([])
const showCreate = ref(false)
const showReveal = ref(false)
const newKey = ref('')
const copied = ref(false)
const form = ref({ name: '', permissions_mask: '', expires_at: '' })
const loading = ref(false)

const ROLES = [
  { label: 'Viewer',      value: '1',  description: 'Read-only access to API data' },
  { label: 'Editor',      value: '7',  description: 'Read, write, and delete via API' },
  { label: 'Query Admin', value: '15', description: 'Editor + manage SQL query registry' },
  { label: 'Ops Admin',   value: '23', description: 'Editor + manage query cache' },
  { label: 'Admin',       value: '31', description: 'All above combined' },
  { label: 'Super Admin', value: '63', description: 'Full access including users, permissions, and blacklist' },
]

function roleName(mask: string) {
  return ROLES.find(r => r.value === mask)?.label ?? 'Custom'
}

function roleBadgeClass(mask: string) {
  const map: Record<string, string> = {
    '1': 'role-viewer', '7': 'role-editor',
    '15': 'role-query', '23': 'role-ops',
    '31': 'role-admin', '63': 'role-super',
  }
  return map[mask] ?? 'role-custom'
}

function fmtDate(iso: string) {
  return new Date(iso).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })
}

async function load() {
  loading.value = true
  try {
    const res = await fetch('/api/admin/api-keys', { headers: auth.authHeaders() })
    keys.value = await res.json()
  } finally {
    loading.value = false
  }
}

async function submitCreate() {
  const body: any = {
    name: form.value.name,
    permissions_mask: form.value.permissions_mask,
  }
  if (form.value.expires_at) {
    body.expires_at = new Date(form.value.expires_at).toISOString()
  }
  const res = await fetch('/api/admin/api-keys', {
    method: 'POST',
    headers: { ...auth.authHeaders(), 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  })
  const data = await res.json()
  showCreate.value = false
  form.value = { name: '', permissions_mask: '', expires_at: '' }
  newKey.value = data.key
  copied.value = false
  showReveal.value = true
  load()
}

async function revoke(id: number, name: string) {
  if (!confirm(`Revoke key "${name}"? Any services using it will lose access immediately.`)) return
  await fetch(`/api/admin/api-keys/${id}`, { method: 'DELETE', headers: auth.authHeaders() })
  load()
}

async function copyKey() {
  await navigator.clipboard.writeText(newKey.value)
  copied.value = true
  setTimeout(() => { copied.value = false }, 2000)
}

function closeReveal() {
  showReveal.value = false
  newKey.value = ''
}

onMounted(load)
</script>

<style scoped>
.name-cell   { font-weight: 600; color: var(--text-high); }
.prefix-cell { font-size: 0.8rem; color: var(--text-muted); }
.date-cell   { color: var(--text-muted); font-size: 0.82rem; font-family: var(--font-mono); }

.role-badge {
  display: inline-block;
  padding: 0.2rem 0.65rem;
  border-radius: 20px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.role-viewer { background: var(--info-subtle);    color: var(--info);    border: 1px solid var(--info-border); }
.role-editor { background: var(--success-subtle); color: var(--success); border: 1px solid var(--success-border); }
.role-query  { background: var(--warn-subtle);    color: var(--warn);    border: 1px solid var(--warn-border); }
.role-ops    { background: var(--warn-subtle);    color: var(--warn);    border: 1px solid var(--warn-border); }
.role-admin  { background: color-mix(in srgb, var(--primary) 12%, var(--surface-1)); color: var(--primary); border: 1px solid color-mix(in srgb, var(--primary) 35%, var(--border)); }
.role-super  { background: var(--primary); color: var(--primary-fg); border: 1px solid var(--primary); }
.role-custom { background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border); }

/* Key reveal */
.reveal-body {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding-top: 0.25rem;
}

.reveal-warning {
  width: 100%;
}

.key-display {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.75rem 1rem;
}

.key-text {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--text-high);
  word-break: break-all;
  background: none;
  border: none;
  padding: 0;
}

.copy-btn {
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  border-radius: 5px;
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-muted);
  font-size: 1rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
}
.copy-btn:hover { border-color: var(--primary); color: var(--primary); }
.copy-btn.copied { border-color: var(--success); color: var(--success); background: var(--success-subtle); }
</style>
