<!-- Vista: API Keys — credenciales scoped para /api/v2 -->
<div x-data="apiKeysApp()" x-init="init()" @keydown.escape.window="closeModal()" class="bg-white rounded-lg shadow">

    <div x-show="loading" class="fixed inset-0 bg-gray-800 bg-opacity-75 flex justify-center items-center z-50">
        <img src="../img/loading.gif" alt="Cargando..." class="w-16 h-16" />
    </div>

    <div class="container mx-auto p-6 w-full">

        <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6">
            <div>
                <h1 class="text-2xl font-bold">API Keys</h1>
                <p class="text-xs text-slate-500 mt-0.5">Credenciales para <code>/api/v2</code> restringidas a una IP y a un alcance puntual — alternativa a compartir la llave maestra (<code>ADMIN_API_KEY</code>).</p>
            </div>
            <button @click="openAdd()"
                class="flex items-center gap-2 text-white text-sm font-medium px-4 py-2 rounded-lg"
                style="background-color:#8eb02f"
                onmouseover="this.style.backgroundColor='#6d8c24'"
                onmouseout="this.style.backgroundColor='#8eb02f'">
                <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                    <path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4"/>
                </svg>
                Nueva API key
            </button>
        </div>

        <div x-show="errorMsg" x-cloak class="mb-4 p-3 bg-red-50 border border-red-200 rounded-lg text-sm text-red-700" x-text="errorMsg"></div>
        <div x-show="successMsg" x-cloak class="mb-4 p-3 bg-green-50 border border-green-200 rounded-lg text-sm text-green-700" x-text="successMsg"></div>
        <div class="mb-4 p-3 bg-amber-50 border border-amber-200 rounded-lg text-xs text-amber-700">
            Solo estos scopes restringen de verdad hoy: <strong>oss</strong>, <strong>query_runner</strong>, <strong>usuarios</strong>, <strong>pasarelas</strong>. El resto de <code>/api/v2</code> sigue funcionando únicamente con la llave maestra (fase 2 pendiente).
        </div>

        <div class="overflow-x-auto">
            <table class="table-auto w-full text-sm">
                <thead class="border-b border-gray-200 text-left text-xs font-semibold text-gray-500 uppercase">
                    <tr>
                        <th class="py-2 px-3">Nombre</th>
                        <th class="py-2 px-3">Token</th>
                        <th class="py-2 px-3">IP permitida</th>
                        <th class="py-2 px-3">Scopes</th>
                        <th class="py-2 px-3">Último uso</th>
                        <th class="py-2 px-3">Estado</th>
                        <th class="py-2 px-3 text-right">Acciones</th>
                    </tr>
                </thead>
                <tbody class="divide-y divide-gray-100">
                    <template x-if="items.length === 0">
                        <tr><td colspan="7" class="py-8 text-center text-gray-400">Sin API keys registradas</td></tr>
                    </template>
                    <template x-for="item in items" :key="item.ID">
                        <tr class="hover:bg-gray-50 transition">
                            <td class="py-2 px-3 font-medium" x-text="item.nombre"></td>
                            <td class="py-2 px-3 font-mono text-xs text-gray-400" x-text="item.token_preview"></td>
                            <td class="py-2 px-3 font-mono text-xs text-gray-600" x-text="item.ip_permitida"></td>
                            <td class="py-2 px-3">
                                <div class="flex flex-wrap gap-1">
                                    <template x-for="s in (item.scopes || '').split(',').filter(x => x.trim())" :key="s">
                                        <span class="px-2 py-0.5 rounded-full text-xs font-semibold bg-[#e9f0cf] text-[#5a7a1e]" x-text="s.trim()"></span>
                                    </template>
                                </div>
                            </td>
                            <td class="py-2 px-3 text-xs text-gray-500">
                                <span x-show="item.ultimo_uso_at" x-text="item.ultimo_uso_at ? new Date(item.ultimo_uso_at).toLocaleString() + ' · ' + item.ultimo_uso_ip : ''"></span>
                                <span x-show="!item.ultimo_uso_at" class="text-gray-300">Nunca usada</span>
                            </td>
                            <td class="py-2 px-3">
                                <span :class="item.activa ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'"
                                    class="px-2 py-0.5 rounded-full text-xs font-semibold"
                                    x-text="item.activa ? 'Activa' : 'Inactiva'"></span>
                            </td>
                            <td class="py-2 px-3 text-right">
                                <div class="flex justify-end gap-2">
                                    <button @click="openEdit(item)"
                                        class="text-xs text-blue-600 hover:text-blue-800 font-medium transition">Editar</button>
                                    <button @click="confirmRegenerar(item.ID)"
                                        class="text-xs text-amber-600 hover:text-amber-800 font-medium transition">Regenerar token</button>
                                    <button @click="confirmDelete(item.ID)"
                                        class="text-xs text-red-500 hover:text-red-700 font-medium transition">Eliminar</button>
                                </div>
                            </td>
                        </tr>
                    </template>
                </tbody>
            </table>
        </div>
    </div>

    <!-- Modal crear / editar -->
    <div x-show="showModal" x-cloak class="fixed inset-0 bg-black/50 flex items-center justify-center z-40 p-4">
        <div @click.outside="closeModal()" class="bg-white rounded-xl shadow-xl w-full max-w-lg p-6">
            <h2 class="text-lg font-bold mb-4" x-text="editItem ? 'Editar API key' : 'Nueva API key'"></h2>
            <form @submit.prevent="save()">
                <div class="grid grid-cols-1 gap-4">
                    <div>
                        <label class="block text-xs font-medium text-gray-600 mb-1">Nombre *</label>
                        <input x-model="form.nombre" type="text" required placeholder="Ej: Integración vCard"
                            class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-[#8eb02f]" />
                    </div>
                    <div>
                        <label class="block text-xs font-medium text-gray-600 mb-1">IP permitida * (IP exacta o CIDR)</label>
                        <input x-model="form.ip_permitida" type="text" required placeholder="190.10.20.30 o 190.10.0.0/16"
                            class="w-full border border-gray-300 rounded-lg px-3 py-2 text-sm font-mono focus:outline-none focus:ring-1 focus:ring-[#8eb02f]" />
                        <p class="text-[10px] text-gray-400 mt-1">Obligatoria — sin ella la llave no puede usarse desde ningún lado.</p>
                    </div>
                    <div>
                        <label class="block text-xs font-medium text-gray-600 mb-2">Scopes *</label>
                        <div class="border border-gray-200 rounded-lg p-3 space-y-2 bg-gray-50">
                            <template x-for="s in ['oss', 'query_runner', 'usuarios', 'pasarelas']" :key="s">
                                <label class="flex items-center gap-2 cursor-pointer select-none">
                                    <input type="checkbox" :checked="form.scopes.includes(s)"
                                        @change="toggleScope(s)" class="rounded text-[#8eb02f] focus:ring-[#8eb02f]">
                                    <span class="text-sm text-gray-700" x-text="s"></span>
                                </label>
                            </template>
                        </div>
                    </div>
                    <div class="flex items-center gap-2">
                        <input x-model="form.activa" type="checkbox" id="ak_activa" class="rounded" />
                        <label for="ak_activa" class="text-sm text-gray-700">Activa</label>
                    </div>
                </div>

                <div x-show="formError" class="mt-3 p-2 bg-red-50 border border-red-200 rounded text-xs text-red-600" x-text="formError"></div>

                <div class="flex justify-end gap-3 mt-5">
                    <button type="button" @click="closeModal()"
                        class="px-4 py-2 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition">Cancelar</button>
                    <button type="submit" :disabled="saving"
                        class="px-4 py-2 text-sm text-white rounded-lg transition disabled:opacity-50"
                        style="background-color:#8eb02f"
                        onmouseover="this.style.backgroundColor='#6d8c24'"
                        onmouseout="this.style.backgroundColor='#8eb02f'">
                        <span x-text="saving ? 'Guardando...' : (editItem ? 'Actualizar' : 'Crear')"></span>
                    </button>
                </div>
            </form>
        </div>
    </div>

    <!-- Modal token generado -->
    <div x-show="tokenResult" x-cloak class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
        <div class="bg-white rounded-xl shadow-xl w-full max-w-lg p-6">
            <h2 class="text-lg font-bold mb-1">⚠️ Guarda este token ahora</h2>
            <p class="text-xs text-gray-500 mb-4">No se volverá a mostrar completo.</p>
            <div class="flex gap-2">
                <input readonly :value="tokenResult && tokenResult.token" class="w-full border border-gray-300 rounded-lg px-3 py-2 text-xs font-mono bg-gray-50">
                <button @click="copiar(tokenResult.token)" class="px-3 py-2 text-xs border border-gray-300 rounded-lg hover:bg-gray-50">Copiar</button>
            </div>
            <div class="flex justify-end mt-5">
                <button @click="tokenResult = null; load()" class="px-4 py-2 text-sm text-white rounded-lg" style="background-color:#8eb02f">Listo, ya lo guardé</button>
            </div>
        </div>
    </div>

    <!-- Modal confirmar regenerar -->
    <div x-show="regenerarId" x-cloak class="fixed inset-0 bg-black/50 flex items-center justify-center z-40 p-4">
        <div class="bg-white rounded-xl shadow-xl w-full max-w-sm p-6 text-center">
            <p class="text-gray-700 font-semibold mb-1">¿Regenerar token?</p>
            <p class="text-xs text-gray-500 mb-5">El token actual dejará de funcionar de inmediato.</p>
            <div class="flex justify-center gap-3">
                <button @click="regenerarId = null" class="px-4 py-2 text-sm border border-gray-300 rounded-lg hover:bg-gray-50">Cancelar</button>
                <button @click="doRegenerar()" :disabled="saving"
                    class="px-4 py-2 text-sm bg-amber-600 text-white rounded-lg hover:bg-amber-700 transition disabled:opacity-50">
                    <span x-text="saving ? 'Regenerando...' : 'Regenerar'"></span>
                </button>
            </div>
        </div>
    </div>

    <!-- Modal confirmar eliminación -->
    <div x-show="deleteId" x-cloak class="fixed inset-0 bg-black/50 flex items-center justify-center z-40 p-4">
        <div class="bg-white rounded-xl shadow-xl w-full max-w-sm p-6 text-center">
            <p class="text-gray-700 font-semibold mb-1">¿Eliminar API key?</p>
            <p class="text-xs text-gray-500 mb-5">Esta acción no se puede deshacer.</p>
            <div class="flex justify-center gap-3">
                <button @click="deleteId = null" class="px-4 py-2 text-sm border border-gray-300 rounded-lg hover:bg-gray-50">Cancelar</button>
                <button @click="doDelete()" :disabled="saving"
                    class="px-4 py-2 text-sm bg-red-600 text-white rounded-lg hover:bg-red-700 transition disabled:opacity-50">
                    <span x-text="saving ? 'Eliminando...' : 'Eliminar'"></span>
                </button>
            </div>
        </div>
    </div>
</div>

<script>
function apiKeysApp() {
    return {
        loading: false, saving: false,
        items: [],
        showModal: false, editItem: null, deleteId: null, regenerarId: null, tokenResult: null,
        errorMsg: '', successMsg: '', formError: '',
        form: { nombre: '', ip_permitida: '', scopes: [], activa: true },

        async init() { await this.load() },

        async load() {
            this.loading = true; this.errorMsg = ''
            const res = await fetch('/app/api-keys/list')
            const data = await res.json()
            this.loading = false
            if (!res.ok) { this.errorMsg = data.error || 'Error cargando datos'; return }
            this.items = data.items || []
        },

        toggleScope(s) {
            const idx = this.form.scopes.indexOf(s)
            if (idx >= 0) { this.form.scopes.splice(idx, 1) } else { this.form.scopes.push(s) }
        },

        openAdd() {
            this.editItem = null
            this.form = { nombre: '', ip_permitida: '', scopes: [], activa: true }
            this.formError = ''
            this.showModal = true
        },
        openEdit(item) {
            this.editItem = item
            this.form = {
                nombre: item.nombre,
                ip_permitida: item.ip_permitida || '',
                scopes: (item.scopes || '').split(',').map(s => s.trim()).filter(s => s),
                activa: item.activa,
            }
            this.formError = ''
            this.showModal = true
        },
        closeModal() { this.showModal = false; this.editItem = null; this.formError = '' },

        async save() {
            this.saving = true; this.formError = ''
            const url = this.editItem ? `/app/api-keys/${this.editItem.ID}` : '/app/api-keys'
            const method = this.editItem ? 'PUT' : 'POST'
            const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(this.form) })
            const data = await res.json()
            this.saving = false
            if (!res.ok) { this.formError = data.error || 'Error guardando'; return }
            this.closeModal()
            if (data.token) {
                this.tokenResult = data
            } else {
                this.successMsg = 'API key actualizada'
                setTimeout(() => this.successMsg = '', 3000)
                await this.load()
            }
        },

        confirmRegenerar(id) { this.regenerarId = id },
        async doRegenerar() {
            this.saving = true
            const res = await fetch(`/app/api-keys/${this.regenerarId}/regenerar-token`, { method: 'POST' })
            const data = await res.json()
            this.saving = false
            this.regenerarId = null
            if (!res.ok) { this.errorMsg = data.error || 'Error regenerando token'; return }
            this.tokenResult = data
        },

        confirmDelete(id) { this.deleteId = id },
        async doDelete() {
            this.saving = true
            const res = await fetch(`/app/api-keys/${this.deleteId}`, { method: 'DELETE' })
            this.saving = false
            this.deleteId = null
            if (!res.ok) { this.errorMsg = 'Error eliminando'; return }
            this.successMsg = 'API key eliminada'
            setTimeout(() => this.successMsg = '', 3000)
            await this.load()
        },

        copiar(texto) {
            if (!texto) return
            navigator.clipboard.writeText(texto)
            this.successMsg = 'Copiado al portapapeles'
            setTimeout(() => this.successMsg = '', 2000)
        }
    }
}
</script>
