<template>
  <div>
    <div class="page-header">
      <div class="page-title">
        <h2>Route Blacklist</h2>
        <span class="subtitle">Glob patterns blocking API routes — matched against path and HTTP method</span>
      </div>
      <NychButton @click="showCreate = true">+ Add Pattern</NychButton>
    </div>

    <div class="table-card">
      <div class="table-card-header">
        <span class="count">{{ entries.length }} {{ entries.length === 1 ? 'entry' : 'entries' }}</span>
      </div>
      <template v-if="entries.length"><div class="table-scroll"><table class="data-table">
        <thead>
          <tr>
            <th>Pattern</th>
            <th>Method</th>
            <th>Status</th>
            <th>Reason</th>
            <th>Bypass mask</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="e in entries" :key="e.id">
            <td><code>{{ e.pattern }}</code></td>
            <td>
              <div class="method-cell">
                <template v-if="e.method">
                  <span v-for="m in e.method.split(',')" :key="m" class="method-badge">{{ m.trim() }}</span>
                </template>
                <span v-else class="dim">ALL</span>
              </div>
            </td>
            <td>
              <span class="status-badge" :class="e.active ? 'status-active' : 'status-inactive'">
                {{ e.active ? 'Active' : 'Disabled' }}
              </span>
            </td>
            <td class="reason-cell">{{ e.reason ?? '—' }}</td>
            <td><span v-if="e.bypass_mask" class="bit-badge">{{ e.bypass_mask }}</span><span v-else class="dim">—</span></td>
            <td class="actions-cell">
              <NychButton size="small" @click="openEdit(e)">Edit</NychButton>
              <NychButton size="small" severity="danger" @click="deleteEntry(e.id)">Delete</NychButton>
            </td>
          </tr>
        </tbody>
      </table></div></template>
      <div class="empty-state" v-else>
        <span class="empty-icon">⊘</span>
        <span class="empty-label">Blacklist is empty</span>
        <span class="empty-hint">All routes are currently open. Add a pattern to block access.</span>
      </div>
    </div>

    <NychDialog v-model:visible="showEdit" header="Edit Blacklist Entry" :modal="true" :draggable="false" style="width: min(640px, 95vw)">
      <form @submit.prevent="submitEdit" class="dialog-form">
        <div class="field">
          <label>Pattern</label>
          <NychInputText v-model="editForm.pattern" fluid />
        </div>
        <div class="field">
          <label>HTTP Methods <span class="optional">(none = all methods)</span></label>
          <MethodSelect v-model="editForm.methods" :options="HTTP_METHODS" placeholder="All methods" />
        </div>
        <div class="field">
          <label>Reason <span class="optional">(optional)</span></label>
          <NychInputText v-model="editForm.reason" fluid />
        </div>
        <div class="field">
          <label>Bypass permission mask <span class="optional">(optional)</span></label>
          <NychInputText v-model="editForm.bypass_mask" placeholder="32" fluid />
        </div>
        <div class="field">
          <label>Status</label>
          <NychSelect v-model="editForm.active" :options="[{ label: 'Active', value: true }, { label: 'Disabled', value: false }]" optionLabel="label" optionValue="value" fluid />
        </div>
        <NychButton type="submit" fluid>Save Changes</NychButton>
      </form>
    </NychDialog>

    <NychDialog v-model:visible="showCreate" header="New Blacklist Entry" :modal="true" :draggable="false" style="width: min(640px, 95vw)">
      <form @submit.prevent="submitCreate" class="dialog-form">
        <div class="field">
          <label>Pattern</label>
          <NychInputText v-model="form.pattern" placeholder="/api/sensitive/**" fluid />
          <p class="hint">Use <code>*</code> for one segment, <code>**</code> for any depth.</p>
        </div>
        <div class="field">
          <label>HTTP Methods <span class="optional">(none = all methods)</span></label>
          <MethodSelect v-model="form.methods" :options="HTTP_METHODS" placeholder="All methods" />
        </div>
        <div class="field">
          <label>Reason <span class="optional">(optional)</span></label>
          <NychInputText v-model="form.reason" placeholder="Why is this route blocked?" fluid />
        </div>
        <div class="field">
          <label>Bypass permission mask <span class="optional">(optional)</span></label>
          <NychInputText v-model="form.bypass_mask" placeholder="32" fluid />
          <p class="hint">Permission bit that allows callers to bypass this rule. Leave blank to block everyone.</p>
        </div>
        <NychButton type="submit" fluid>Add to Blacklist</NychButton>
      </form>
    </NychDialog>
  </div>
</template>

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

const auth = useAuthStore()
const entries = ref<any[]>([])
const showCreate = ref(false)
const showEdit = ref(false)
const editId = ref<number | null>(null)
const editForm = ref({ pattern: '', methods: [] as string[], reason: '', bypass_mask: '', active: true })
const form = ref({ pattern: '', methods: [] as string[], reason: '', bypass_mask: '' })

const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']

async function load() {
  const res = await fetch('/api/blacklist', { headers: auth.authHeaders() })
  entries.value = await res.json()
}

function methodsToString(methods: string[]): string | null {
  return methods.length ? methods.join(',') : null
}

function stringToMethods(s: string | null | undefined): string[] {
  return s ? s.split(',').map(m => m.trim()).filter(Boolean) : []
}

async function submitCreate() {
  await fetch('/api/blacklist', {
    method: 'POST',
    headers: { ...auth.authHeaders(), 'Content-Type': 'application/json' },
    body: JSON.stringify({
      pattern: form.value.pattern,
      method: methodsToString(form.value.methods),
      reason: form.value.reason || null,
      bypass_mask: form.value.bypass_mask || null,
      active: true,
    }),
  })
  showCreate.value = false
  form.value = { pattern: '', methods: [], reason: '', bypass_mask: '' }
  load()
}

function openEdit(e: any) {
  editId.value = e.id
  editForm.value = {
    pattern: e.pattern,
    methods: stringToMethods(e.method),
    reason: e.reason ?? '',
    bypass_mask: e.bypass_mask ?? '',
    active: e.active,
  }
  showEdit.value = true
}

async function submitEdit() {
  await fetch(`/api/blacklist/${editId.value}`, {
    method: 'PUT',
    headers: { ...auth.authHeaders(), 'Content-Type': 'application/json' },
    body: JSON.stringify({
      pattern: editForm.value.pattern,
      method: methodsToString(editForm.value.methods),
      reason: editForm.value.reason || null,
      bypass_mask: editForm.value.bypass_mask || null,
      active: editForm.value.active,
    }),
  })
  showEdit.value = false
  load()
}

async function deleteEntry(id: number) {
  if (!confirm('Delete this blacklist entry?')) return
  await fetch(`/api/blacklist/${id}`, { method: 'DELETE', headers: auth.authHeaders() })
  load()
}

onMounted(load)
</script>

<style scoped>
.reason-cell { color: var(--text-muted); font-size: 0.85rem; }
.dim { color: var(--text-dim); font-size: 0.8rem; font-family: var(--font-mono); }

.method-cell { display: flex; gap: 0.25rem; flex-wrap: wrap; align-items: center; }

.bit-badge {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  background: var(--surface-2);
  border: 1px solid var(--border-lo);
  color: var(--text-label);
}

.method-badge {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  background: var(--surface-2);
  border: 1px solid var(--border-lo);
  color: var(--text-label);
}

.status-badge {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  border-radius: 20px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.status-active   { background: var(--danger-subtle); color: var(--danger);  border: 1px solid var(--danger-border); }
.status-inactive { background: var(--surface-2);     color: var(--text-dim); border: 1px solid var(--border-lo); }
</style>
