{% extends "base.html" %}
{% block content %}

<style>
  .token-table th { font-weight: 600; text-transform: uppercase; font-size: 0.7rem; letter-spacing: 0.05em; }
  .badge-active { background: #dcfce7; color: #166534; }
  .badge-suspended { background: #fef3c7; color: #92400e; }
  .badge-expired { background: #fee2e2; color: #991b1b; }
  html.dark .badge-active { background: #052e16; color: #86efac; }
  html.dark .badge-suspended { background: #451a03; color: #fcd34d; }
  html.dark .badge-expired { background: #450a0a; color: #fca5a5; }
  .clipboard-copied { animation: flash-green 1.5s ease-out; }
  @keyframes flash-green { 0% { background: #bbf7d0; } 100% { background: transparent; } }
</style>

<div class="px-6 pt-5 pb-4">
  <div class="flex items-center justify-between gap-2 mb-4">
    <h1 class="text-lg sm:text-xl font-semibold text-gray-900 dark:text-gray-100">Agent API — Token Management</h1>
    <button onclick="openCreateModal()" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">
      + Create Token
    </button>
  </div>

  <!-- Stats bar -->
  <div id="stats-bar" class="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-4"></div>

  <!-- Tokens table -->
  <div class="overflow-x-auto bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700">
    <table class="token-table w-full text-sm text-left">
      <thead class="bg-gray-50 dark:bg-gray-750 text-gray-500 dark:text-gray-400">
        <tr>
          <th class="px-4 py-3">Name</th>
          <th class="px-4 py-3">Token</th>
          <th class="px-4 py-3">Quota</th>
          <th class="px-4 py-3">Models</th>
          <th class="px-4 py-3">Status</th>
          <th class="px-4 py-3">Expires</th>
          <th class="px-4 py-3">Last Used</th>
          <th class="px-4 py-3 w-36">Actions</th>
        </tr>
      </thead>
      <tbody id="tokens-tbody" class="divide-y divide-gray-100 dark:divide-gray-700"></tbody>
    </table>
    <div id="empty-state" class="hidden p-8 text-center text-gray-400 text-sm">No tokens yet. Click "+ Create Token" to get started.</div>
  </div>
</div>

<!-- ====== Create / Edit Modal ====== -->
<div id="token-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/50">
  <div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-full max-w-lg mx-4 max-h-[90vh] overflow-y-auto">
    <div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700 flex justify-between items-center">
      <h2 id="modal-title" class="text-lg font-semibold text-gray-900 dark:text-gray-100">Create Token</h2>
      <button onclick="closeModal()" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200">&times;</button>
    </div>
    <div class="px-6 py-4 space-y-4">
      <input type="hidden" id="edit-token-id" value="">
      <div>
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Name *</label>
        <input type="text" id="token-name" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-indigo-300 focus:border-indigo-400" placeholder="e.g. My App Token">
      </div>
      <div>
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Quota Limit <span class="text-gray-400 font-normal">(daily requests, blank = unlimited)</span></label>
        <input type="number" id="token-quota" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100" placeholder="e.g. 1000" min="1">
      </div>
      <div>
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Expires At <span class="text-gray-400 font-normal">(ISO 8601, blank = never)</span></label>
        <input type="text" id="token-expires" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100" placeholder="e.g. 2026-12-31T23:59:59Z">
      </div>
      <div>
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Allowed Models</label>
        <div id="model-checkboxes" class="space-y-1 max-h-40 overflow-y-auto border border-gray-200 dark:border-gray-600 rounded-lg p-2"></div>
        <p class="text-xs text-gray-400 mt-1">If none selected, all models are allowed.</p>
      </div>
      <div id="status-field" class="hidden">
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Status</label>
        <select id="token-status" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100">
          <option value="active">Active</option>
          <option value="suspended">Suspended</option>
        </select>
      </div>
      <div id="created-token-box" class="hidden p-4 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg">
        <p class="text-sm font-medium text-green-800 dark:text-green-300 mb-2">Token created! Copy it now — it won't be shown again.</p>
        <div class="flex gap-2">
          <input type="text" id="created-token-value" readonly class="flex-1 px-3 py-2 bg-white dark:bg-gray-700 border border-green-300 dark:border-green-600 rounded-lg text-sm font-mono text-gray-900 dark:text-gray-100">
          <button onclick="copyCreatedToken()" class="px-3 py-2 text-sm font-medium text-white bg-green-600 rounded-lg hover:bg-green-700 transition">Copy</button>
        </div>
      </div>
    </div>
    <div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 flex justify-end gap-2">
      <button onclick="closeModal()" class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition">Cancel</button>
      <button id="modal-save-btn" onclick="saveToken()" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">Save</button>
    </div>
  </div>
</div>

<!-- ====== Delete Confirm Modal ====== -->
<div id="delete-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/50">
  <div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-full max-w-sm mx-4 p-6">
    <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">Delete Token?</h3>
    <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">This action is permanent. API clients using this token will lose access.</p>
    <div class="flex justify-end gap-2">
      <button onclick="closeDeleteModal()" class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition">Cancel</button>
      <button id="delete-confirm-btn" class="px-4 py-2 text-sm font-medium text-white bg-red-600 rounded-lg hover:bg-red-700 transition">Delete</button>
    </div>
  </div>
</div>

<!-- ====== Reset Token Modal ====== -->
<div id="reset-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/50">
  <div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-full max-w-lg mx-4 p-6">
    <div id="reset-before">
      <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">Reset Token?</h3>
      <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">API clients using the old key will lose access immediately. This action cannot be undone.</p>
      <div class="flex justify-end gap-2">
        <button onclick="closeResetModal()" class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition">Cancel</button>
        <button id="reset-confirm-btn" class="px-4 py-2 text-sm font-medium text-white bg-amber-600 rounded-lg hover:bg-amber-700 transition">Reset</button>
      </div>
    </div>
    <div id="reset-after" class="hidden">
      <h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2">Token Reset</h3>
      <p class="text-sm font-medium text-amber-800 dark:text-amber-300 mb-2">Token reset complete! Copy the new key now — the old key is invalidated.</p>
      <div class="flex gap-2 mb-4">
        <input type="text" id="reset-token-value" readonly class="flex-1 px-3 py-2 bg-white dark:bg-gray-700 border border-amber-300 dark:border-amber-600 rounded-lg text-sm font-mono text-gray-900 dark:text-gray-100">
        <button onclick="copyResetToken()" class="px-3 py-2 text-sm font-medium text-white bg-amber-600 rounded-lg hover:bg-amber-700 transition">Copy</button>
      </div>
      <div class="flex justify-end">
        <button onclick="doneReset()" class="px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-lg hover:bg-indigo-700 transition">Done</button>
      </div>
    </div>
  </div>
</div>

<script>
// ---- State ----
let tokens = [];
let modelAgentMap = {};
let deleteTargetId = null;

// ---- Init ----
document.addEventListener('DOMContentLoaded', () => {
  loadModelAgentMap().then(() => loadTokens());
});

async function loadModelAgentMap() {
  const res = await fetch('/api/agentapi/admin/model-agent-map');
  const data = await res.json();
  modelAgentMap = data.map || {};
}

async function loadTokens() {
  const res = await fetch('/api/agentapi/admin/tokens');
  const data = await res.json();
  tokens = data.tokens || [];
  renderTokens();
  renderStats();
}

// ---- Stats Bar ----
function renderStats() {
  const active = tokens.filter(t => t.status === 'active').length;
  const suspended = tokens.filter(t => t.status === 'suspended').length;
  const total = tokens.length;
  const unlimited = tokens.filter(t => t.quota_limit === null).length;
  document.getElementById('stats-bar').innerHTML = `
    <div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-3 text-center">
      <div class="text-2xl font-bold text-gray-900 dark:text-gray-100">${total}</div>
      <div class="text-xs text-gray-500">Total Tokens</div>
    </div>
    <div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-3 text-center">
      <div class="text-2xl font-bold text-green-600">${active}</div>
      <div class="text-xs text-gray-500">Active</div>
    </div>
    <div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-3 text-center">
      <div class="text-2xl font-bold text-amber-600">${suspended}</div>
      <div class="text-xs text-gray-500">Suspended</div>
    </div>
    <div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-3 text-center">
      <div class="text-2xl font-bold text-gray-900 dark:text-gray-100">${unlimited}</div>
      <div class="text-xs text-gray-500">Unlimited</div>
    </div>`;
}

// ---- Render Tokens Table ----
function renderTokens() {
  const tbody = document.getElementById('tokens-tbody');
  const empty = document.getElementById('empty-state');
  if (tokens.length === 0) {
    tbody.innerHTML = '';
    empty.classList.remove('hidden');
    return;
  }
  empty.classList.add('hidden');
  tbody.innerHTML = tokens.map(t => {
    const statusClass = t.status === 'active' ? 'badge-active' : 'badge-suspended';
    const quotaText = t.quota_limit ? `${t.quota_used}/${t.quota_limit}` : `${t.quota_used}/∞`;
    const modelsText = formatAllowedModels(t.allowed_models);
    const expiresText = t.expires_at ? new Date(t.expires_at).toLocaleDateString() : 'Never';
    const isExpired = t.expires_at && new Date(t.expires_at) < new Date();
    const lastUsed = t.last_used_at ? timeAgo(t.last_used_at) : 'Never';
    return `<tr class="hover:bg-gray-50 dark:hover:bg-gray-750">
      <td class="px-4 py-3 font-medium text-gray-900 dark:text-gray-100">${esc(t.name)}</td>
      <td class="px-4 py-3 font-mono text-xs text-gray-500">${esc(t.token_prefix)}&hellip;</td>
      <td class="px-4 py-3 text-gray-600 dark:text-gray-300">${quotaText}</td>
      <td class="px-4 py-3 text-xs text-gray-500">${esc(modelsText)}</td>
      <td class="px-4 py-3"><span class="inline-block px-2 py-0.5 rounded-full text-xs font-medium ${statusClass} ${isExpired ? 'badge-expired' : ''}">${isExpired ? 'expired' : t.status}</span></td>
      <td class="px-4 py-3 text-xs text-gray-500">${expiresText}</td>
      <td class="px-4 py-3 text-xs text-gray-500">${lastUsed}</td>
      <td class="px-4 py-3">
        <div class="flex gap-1">
          <button onclick="openEditModal(${t.id})" class="px-2 py-1 text-xs text-indigo-600 dark:text-indigo-400 hover:bg-indigo-50 dark:hover:bg-indigo-900/30 rounded transition" title="Edit">Edit</button>
          <button onclick="askReset(${t.id})" class="px-2 py-1 text-xs text-amber-600 dark:text-amber-400 hover:bg-amber-50 dark:hover:bg-amber-900/30 rounded transition" title="Reset">Reset</button>
          <button onclick="askDelete(${t.id})" class="px-2 py-1 text-xs text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/30 rounded transition" title="Delete">Del</button>
        </div>
      </td>
    </tr>`;
  }).join('');
}

function formatAllowedModels(allowed) {
  if (!allowed || allowed.length === 0 || (allowed.length === 1 && allowed[0] === '*')) return 'All';
  return allowed.join(', ');
}

// ---- Modal ----
function openCreateModal() {
  document.getElementById('modal-title').textContent = 'Create Token';
  document.getElementById('edit-token-id').value = '';
  document.getElementById('token-name').value = '';
  document.getElementById('token-quota').value = '';
  document.getElementById('token-expires').value = '';
  document.getElementById('status-field').classList.add('hidden');
  document.getElementById('created-token-box').classList.add('hidden');
  document.getElementById('modal-save-btn').textContent = 'Create';
  renderModelCheckboxes(null);
  document.getElementById('token-modal').classList.remove('hidden');
}

function openEditModal(id) {
  const t = tokens.find(t => t.id === id);
  if (!t) return;
  document.getElementById('modal-title').textContent = 'Edit Token';
  document.getElementById('edit-token-id').value = t.id;
  document.getElementById('token-name').value = t.name;
  document.getElementById('token-quota').value = t.quota_limit || '';
  document.getElementById('token-expires').value = t.expires_at || '';
  document.getElementById('token-status').value = t.status;
  document.getElementById('status-field').classList.remove('hidden');
  document.getElementById('created-token-box').classList.add('hidden');
  document.getElementById('modal-save-btn').textContent = 'Save';
  renderModelCheckboxes(t.allowed_models);
  document.getElementById('token-modal').classList.remove('hidden');
}

function closeModal() {
  document.getElementById('token-modal').classList.add('hidden');
}

function renderModelCheckboxes(selectedModels) {
  const container = document.getElementById('model-checkboxes');
  const models = Object.keys(modelAgentMap).sort();
  if (models.length === 0) {
    container.innerHTML = '<p class="text-xs text-gray-400 p-2">No models configured. Add mappings in MODEL_AGENT_MAP plugin variable.</p>';
    return;
  }
  const sel = selectedModels && selectedModels.length > 0 && selectedModels[0] !== '*' ? selectedModels : [];
  container.innerHTML = models.map(m => `
    <label class="flex items-center gap-2 px-2 py-1 hover:bg-gray-50 dark:hover:bg-gray-750 rounded cursor-pointer text-sm text-gray-700 dark:text-gray-300">
      <input type="checkbox" value="${esc(m)}" class="model-cb rounded" ${sel.length === 0 || sel.includes(m) ? 'checked' : ''}>
      ${esc(m)} <span class="text-xs text-gray-400 ml-auto">→ ${esc(modelAgentMap[m])}</span>
    </label>`).join('');
}

function getCheckedModels() {
  const cbs = document.querySelectorAll('.model-cb:checked');
  const selected = Array.from(cbs).map(cb => cb.value);
  // If all are checked, treat as wildcard
  const allModels = Object.keys(modelAgentMap);
  return selected.length === allModels.length ? [] : selected;
}

async function saveToken() {
  const id = document.getElementById('edit-token-id').value;
  const name = document.getElementById('token-name').value.trim();
  if (!name) { alert('Name is required.'); return; }

  const body = { name };
  const quotaVal = document.getElementById('token-quota').value.trim();
  if (quotaVal) body.quota_limit = parseInt(quotaVal);
  else body.quota_limit = null;

  const expiresVal = document.getElementById('token-expires').value.trim();
  body.expires_at = expiresVal || null;

  const checkedModels = getCheckedModels();
  body.allowed_models = checkedModels.length > 0 ? checkedModels : null;

  if (id) {
    body.status = document.getElementById('token-status').value;
    const res = await fetch(`/api/agentapi/admin/tokens/${id}`, {
      method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(body)
    });
    if (!res.ok) { const err = await res.json(); alert(err.error || 'Update failed'); return; }
    closeModal();
    loadTokens();
  } else {
    const res = await fetch('/api/agentapi/admin/tokens', {
      method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(body)
    });
    if (!res.ok) { const err = await res.json(); alert(err.error || 'Create failed'); return; }
    const data = await res.json();
    // Show the created token
    const pt = data.plaintext;
    document.getElementById('created-token-value').value = pt;
    document.getElementById('created-token-box').classList.remove('hidden');
    document.getElementById('modal-save-btn').textContent = 'Done';
    document.getElementById('modal-save-btn').onclick = () => { closeModal(); loadTokens(); };
  }
}

function copyCreatedToken() {
  const input = document.getElementById('created-token-value');
  input.select();
  document.execCommand('copy');
  input.classList.add('clipboard-copied');
  setTimeout(() => input.classList.remove('clipboard-copied'), 1500);
}

// ---- Delete ----
function askDelete(id) {
  deleteTargetId = id;
  document.getElementById('delete-modal').classList.remove('hidden');
  document.getElementById('delete-confirm-btn').onclick = confirmDelete;
}

function closeDeleteModal() {
  document.getElementById('delete-modal').classList.add('hidden');
  deleteTargetId = null;
}

async function confirmDelete() {
  if (!deleteTargetId) return;
  const res = await fetch(`/api/agentapi/admin/tokens/${deleteTargetId}`, { method: 'DELETE' });
  if (!res.ok && res.status !== 204) { alert('Delete failed'); return; }
  closeDeleteModal();
  loadTokens();
}

// ---- Reset Token ----
let resetTargetId = null;

function askReset(id) {
  resetTargetId = id;
  document.getElementById('reset-before').classList.remove('hidden');
  document.getElementById('reset-after').classList.add('hidden');
  document.getElementById('reset-token-value').value = '';
  document.getElementById('reset-modal').classList.remove('hidden');
  document.getElementById('reset-confirm-btn').onclick = confirmReset;
}

function closeResetModal() {
  document.getElementById('reset-modal').classList.add('hidden');
  resetTargetId = null;
}

async function confirmReset() {
  if (!resetTargetId) return;
  const res = await fetch(`/api/agentapi/admin/tokens/${resetTargetId}/reset`, {
    method: 'POST'
  });
  if (!res.ok) { const err = await res.json(); alert(err.error || 'Reset failed'); return; }
  const data = await res.json();
  document.getElementById('reset-before').classList.add('hidden');
  document.getElementById('reset-token-value').value = data.plaintext;
  document.getElementById('reset-after').classList.remove('hidden');
}

function copyResetToken() {
  const input = document.getElementById('reset-token-value');
  input.select();
  document.execCommand('copy');
  input.classList.add('clipboard-copied');
  setTimeout(() => input.classList.remove('clipboard-copied'), 1500);
}

function doneReset() {
  closeResetModal();
  loadTokens();
}

// ---- Utilities ----
function esc(s) { return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); }

function timeAgo(iso) {
  const now = Date.now();
  const then = new Date(iso).getTime();
  const diff = Math.floor((now - then) / 1000);
  if (diff < 60) return 'just now';
  if (diff < 3600) return `${Math.floor(diff/60)}m ago`;
  if (diff < 86400) return `${Math.floor(diff/3600)}h ago`;
  return `${Math.floor(diff/86400)}d ago`;
}
</script>
{% endblock %}
