// Synchronisation automatique du champ "path" avec le champ "name"
let pathAutoGenerated = true;
const nameInput = document.getElementById('name');
const pathInput = document.getElementById('path');

function generateRouteFromName(name) {
  return '/' + name.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
}

nameInput.addEventListener('input', function() {
  if (pathAutoGenerated || !pathInput.value) {
    pathInput.value = generateRouteFromName(nameInput.value);
    pathAutoGenerated = true;
  }
});
pathInput.addEventListener('input', function() {
  pathAutoGenerated = false;
});

function setNameAndAutoRoute(name) {
  nameInput.value = name || '';
  if (name) {
    pathInput.value = generateRouteFromName(name);
    pathAutoGenerated = true;
  }
}

function showAlert(msg, type = 'info', duration = 2500, context = '') {
  let alertBox = document.getElementById('customAlertBox');
  if (!alertBox) {
    alertBox = document.createElement('div');
    alertBox.id = 'customAlertBox';
    alertBox.style.position = 'fixed';
    alertBox.style.top = '50%';
    alertBox.style.left = '50%';
    alertBox.style.right = '';
    alertBox.style.transform = 'translate(-50%,-50%)';
    alertBox.style.zIndex = '9999';
    alertBox.style.minWidth = '220px';
    alertBox.style.maxWidth = '90vw';
    alertBox.style.padding = '18px 28px';
    alertBox.style.borderRadius = '12px';
    alertBox.style.boxShadow = '0 2px 16px #0002';
    alertBox.style.fontSize = '1.1em';
    alertBox.style.fontWeight = '500';
    alertBox.style.transition = 'opacity 0.3s';
    alertBox.style.opacity = '0';
    alertBox.style.pointerEvents = 'none';
    document.body.appendChild(alertBox);
  }
  let closeBtn = '';
  if (duration === 0) {
    closeBtn = `<div style='text-align:right;margin-top:12px'><button id='closeAlertBtn' style='background:var(--primary,#007bff);color:#fff;padding:6px 18px;border-radius:8px;border:none;cursor:pointer'>Fermer</button></div>`;
  }
  alertBox.innerHTML = `<b>${context ? context + ' : ' : ''}</b>${msg}${closeBtn}`;
  alertBox.style.background = type === 'error' ? 'var(--danger,#c00)' : (type === 'success' ? 'var(--primary,#007bff)' : 'var(--card-bg,#fff)');
  alertBox.style.color = type === 'error' ? '#fff' : (type === 'success' ? '#fff' : 'var(--text,#222)');
  alertBox.style.opacity = '1';
  alertBox.style.pointerEvents = 'auto';
  if (duration > 0) {
    setTimeout(() => { alertBox.style.opacity = '0'; alertBox.style.pointerEvents = 'none'; }, duration);
  } else {
    const btn = document.getElementById('closeAlertBtn');
    if (btn) {
      btn.onclick = () => {
        alertBox.style.opacity = '0';
        alertBox.style.pointerEvents = 'none';
      };
    }
  }
}

function showApiResponseFull(response, api = null) {
  let info = '';
  if (api) {
    info = `<div style='margin-bottom:12px;font-size:1.08em'><b>ID :</b> ${api.id} &nbsp; <b>Nom :</b> ${api.name} &nbsp; <b>Route :</b> <span style='color:#007bff'>${api.path}</span></div>`;
  }
  showAlert(`${info}<pre style='max-width:90vw;white-space:pre-wrap;word-break:break-all;'>${response}</pre>`, 'info', 0, 'Réponse complète');
}
window.showApiResponseFull = showApiResponseFull;

async function listApis() {
  const res = await fetch('/admin/apis');
  const data = await res.json();
  const tbody = document.querySelector('#apisTable tbody');
  tbody.innerHTML = '';
  for (const api of data) {
    if (api.project_id) continue;
    // Couleur méthode
    let methodColor = '#007bff';
    if (api.method === 'POST') methodColor = '#28a745';
    else if (api.method === 'PUT') methodColor = '#ffc107';
    else if (api.method === 'DELETE') methodColor = '#dc3545';
    else if (api.method === 'PATCH') methodColor = '#17a2b8';
    // Couleur status
    let statusColor = '#007bff';
    if (api.status_code === 201) statusColor = '#28a745'; // Créé
    else if (api.status_code === 204) statusColor = '#28a745'; // No Content
    else if (api.status_code === 400) statusColor = '#ffc107'; // Bad Request
    else if (api.status_code === 401) statusColor = '#ffc107'; // Unauthorized
    else if (api.status_code === 403) statusColor = '#ffc107'; // Forbidden
    else if (api.status_code === 404) statusColor = '#dc3545'; // Not Found
    else if (api.status_code === 500) statusColor = '#dc3545'; // Server Error
    else if (api.status_code >= 200 && api.status_code < 300) statusColor = '#28a745'; // succès
    else if (api.status_code >= 400 && api.status_code < 500) statusColor = '#ffc107'; // client
    else if (api.status_code >= 500) statusColor = '#dc3545'; // serveur
    else if (api.status_code >= 300 && api.status_code < 400) statusColor = '#17a2b8'; // redirection
    let responseStr = '';
    try {
      responseStr = typeof api.response_json === 'string' ? api.response_json : JSON.stringify(api.response_json);
    } catch(e) { responseStr = String(api.response_json); }
    let shortResponse = responseStr.length > 20 ? responseStr.slice(0,20) + '…' : responseStr;
    const tr = document.createElement('tr');
    tr.innerHTML = `
      <td>${api.id}</td>
      <td>${api.name}</td>
      <td>${api.path}</td>
      <td><span style='color:${methodColor};font-weight:bold'>${api.method}</span></td>
      <td>
        <span>${shortResponse}</span>
        ${responseStr.length > 20 ? `<button title='Voir la réponse complète' style='background:none;border:none;cursor:pointer;padding:0 4px;vertical-align:middle;' onclick='window.showApiResponseFull(${JSON.stringify(responseStr)}, ${JSON.stringify({id: api.id, name: api.name, path: api.path})})'><svg width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='#007bff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'></path><circle cx='12' cy='12' r='3'></circle></svg></button>` : ''}
      </td>
      <td><span style='color:${statusColor};font-weight:bold'>${api.status_code}</span></td>
      <td>${api.enabled ? '<span style="color:var(--primary)"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg></span>' : '<span style="color:var(--danger)"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></span>'}
      </td>
      <td>${api.delay_ms ?? ''}</td>
      <td>${api.api_key ?? ''}</td>
      <td>${api.base_url ?? ''}</td>
      <td>${api.quota ? `${api.quota}/${api.quota_period}` : 'Illimité'}</td>
      <td>
        <span style="display:flex;gap:8px;justify-content:center;align-items:center">
          <button title="Supprimer" style="background:none;border:none;padding:0;cursor:pointer">
            <span style="font-size:18px;color:var(--danger)"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></span>
          </button>
          <button title="Tester" style="background:none;border:none;padding:0;cursor:pointer">
            <span style="font-size:18px;color:var(--primary)"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12" y2="16"></line></svg></span>
          </button>
        </span>
      </td>
    `;
    tr.querySelector('button[title="Supprimer"]').onclick = ()=>deleteApi(api.id);
    tr.querySelector('button[title="Tester"]').onclick = ()=>testApi(api.path, api.method);
    tr.style.cursor = 'pointer';
    tr.onclick = (e) => {
      if (e.target.closest('button')) return;
      window.open(`/admin/apis/${api.id}/stats`, '_blank');
    };
    tbody.appendChild(tr);
  }
  // Ajout du scroll si la liste est longue
  const table = document.getElementById('apisTable');
  if (data.filter(api => !api.project_id).length >3) {
    table.parentElement.style.maxHeight = '420px';
    table.parentElement.style.overflowY = 'auto';
  } else {
    table.parentElement.style.maxHeight = '';
    table.parentElement.style.overflowY = '';
  }
  // Ajout du scroll-list-main sur le parent du tableau principal
  if (table && table.parentElement && !table.parentElement.classList.contains('scroll-list-main')) {
    table.parentElement.classList.add('scroll-list-main');
  }
}

async function deleteApi(id) {
  showConfirm(`Supprimer l'API #${id} ?`, async () => {
    const res = await fetch(`/admin/apis/${id}`, {method:'DELETE'});
    const result = await res.json();
    if (result.deleted) { showAlert('API supprimée', 'success', 2500, `API #${id}`); listApis(); }
    else { showAlert('Erreur suppression', 'error', 2500, `API #${id}`); }
  });
}
async function testApi(path, method) {
  if (method === 'GET') {
    window.open(path, '_blank');
  } else {
    const win = window.open('', '_blank');
    win.document.write(`
      <h2>Tester l'API (${method})</h2>
      <form id="testForm">
        <label>Body (JSON):<br><textarea id="body" rows="6" style="width:100%">{}</textarea></label><br>
        <label>Headers (JSON):<br><textarea id="headers" rows="2" style="width:100%">{}</textarea></label><br>
        <button type="submit">Envoyer</button>
      </form>
      <pre id="result"></pre>
      <script>
        document.getElementById('testForm').onsubmit = async function(e) {
          e.preventDefault();
          let body = document.getElementById('body').value;
          let headers = {};
          try { headers = JSON.parse(document.getElementById('headers').value || '{}'); } catch {}
          let options = { method: '${method}', headers };
          if (body && body !== '{}') options.body = body;
          try {
            const res = await fetch('${path}', options);
            const text = await res.text();
            document.getElementById('result').textContent = text;
          } catch (err) {
            document.getElementById('result').textContent = 'Erreur: ' + err;
          }
        };
      <\/script>
    `);
  }
}
document.getElementById('apiForm').onsubmit = async (e)=>{
  e.preventDefault();
  const payload = {
    name: document.getElementById('name').value.trim(),
    path: document.getElementById('path').value.trim(),
    method: document.getElementById('method').value.trim(),
    response_json: JSON.parse(document.getElementById('response_json').value || "{}"),
    status_code: parseInt(document.getElementById('status_code').value || "200"),
    enabled: document.getElementById('enabled').value === 'true',
    delay_ms: parseInt(document.getElementById('delay_ms').value || "0"),
    api_key: document.getElementById('api_key').value.trim(),
    base_url: document.getElementById('base_url').value.trim(),
    quota: parseInt(document.getElementById('quota').value || "0"),
    quota_period: document.getElementById('quota_period').value
  };
  const res = await fetch('/admin/apis', {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
  if (!res.ok) { showAlert('Erreur', 'error'); return; }
  showAlert('API créée ✅', 'success', 2500, `API ${payload.name}`);
  listApis();
}
document.getElementById('importApiBtn').onclick = async () => {
  const fileInput = document.getElementById('importApiFile');
  if (!fileInput.files.length) {
    showAlert('Sélectionnez un fichier à importer.', 'error');
    return;
  }
  const file = fileInput.files[0];
  let content = '';
  try {
    content = await file.text();
  } catch (e) {
    showAlert('Erreur lecture du fichier', 'error');
    return;
  }
  let apiData;
  try {
    apiData = JSON.parse(content);
  } catch (e) {
    showAlert('Le fichier n\'est pas un JSON valide.', 'error');
    return;
  }
  // Si le fichier contient un tableau d'APIs, on importe chaque API
  if (Array.isArray(apiData)) {
    for (const api of apiData) {
      const res = await fetch('/admin/apis', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(api)
      });
      if (!res.ok) {
        showAlert('Erreur lors de l\'import d\'une API.', 'error', 2500, `API ${api.name}`);
      }
    }
    showAlert('Import terminé (plusieurs APIs)', 'success');
  } else {
    // Sinon, on importe une seule API
    const res = await fetch('/admin/apis', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(apiData)
    });
    if (!res.ok) {
      showAlert('Erreur lors de l\'import de l\'API.', 'error', 2500, `API ${apiData.name}`);
      return;
    }
    showAlert('API importée', 'success', 2500, `API ${apiData.name}`);
  }
  listApis();
};
async function listProjects() {
  const res = await fetch('/admin/projects');
  const projects = await res.json();
  const resApis = await fetch('/admin/apis');
  const apis = await resApis.json();
  let html = '';
  for (const project of projects) {
    const apisCount = apis.filter(api => api.project_id === project.id).length;
    const isOpen = false; // initial state, will be toggled
    html += `<div class='project-card' style='border:1px solid #eee;border-radius:8px;padding:0;margin:8px 0'>
      <button class='toggle-btn' style='width:100%;text-align:left;background:none;border:none;padding:12px;font-size:18px;font-weight:bold;cursor:pointer;color:#111;display:flex;align-items:center;justify-content:space-between;'>
        <span style='color:#111;display:flex;align-items:center;'>
          ${project.icon ? `<img src="/admin/projects/${project.id}/icon" style="height:24px;width:24px;vertical-align:middle;border-radius:4px;margin-right:8px">` : ''}
          ${project.name}
          <span style='margin-left:12px;font-size:0.95em;color:#555;background:#eee;border-radius:8px;padding:2px 10px'>${apisCount} API${apisCount>1?'s':''}</span>
        </span>
        <span class='toggle-svg' data-project='${project.id}' style='margin-left:8px;'>
          <svg width='22' height='22' viewBox='0 0 24 24' fill='none' stroke='#888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'></polyline></svg>
        </span>
        <small>(ID: ${project.id})</small>
      </button>
      <button onclick='removeProject(${project.id})' style='float:right;background:none;border:none;color:var(--danger);font-size:18px;cursor:pointer' title='Supprimer le projet'>
        <svg width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='red' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='3 6 5 6 21 6'></polyline><path d='M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m5 0V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2'></path><line x1='10' y1='11' x2='10' y2='17'></line><line x1='14' y1='11' x2='14' y2='17'></line></svg>
      </button>
      <div class='project-details' style='display:none;padding:12px;'>
        <span>${project.description || ''}</span><br>
        <b>APIs associées :</b>
        <table style='width:100%;border-collapse:collapse;margin-top:8px'>
          <thead><tr>
            <th>ID</th><th>Nom</th><th>Chemin</th><th>Méthode</th><th>Réponse</th><th>Status</th><th>Activée</th><th>Délai (ms)</th><th>API Key</th><th>Base URL</th><th>Quota</th><th>Actions</th>
          </tr></thead>
          <tbody id='apisForProject${project.id}'></tbody>
        </table>
        <label>Associer une API : <input type='number' id='apiToAdd${project.id}' placeholder='ID API'></label>
        <button onclick='addApiToProject(${project.id})'>Associer</button>
      </div>
    </div>`;
  }
  document.getElementById('projectsList').innerHTML = html;
  document.querySelectorAll('.project-card .toggle-btn').forEach((btn, idx) => {
    btn.onclick = function() {
      const details = btn.parentElement.querySelector('.project-details');
      const svg = btn.querySelector('.toggle-svg svg');
      if (details.style.display === 'none') {
        details.style.display = 'block';
        svg.style.transform = 'rotate(180deg)';
      } else {
        details.style.display = 'none';
        svg.style.transform = 'rotate(0deg)';
      }
    };
  });
  for (const project of projects) {
    renderApisForProject(project.id, apis.filter(api => api.project_id === project.id));
  }
}
function renderApisForProject(projectId, apis) {
  let html = '';
  for (const api of apis) {
    // Couleur méthode
    let methodColor = '#007bff';
    if (api.method === 'POST') methodColor = '#28a745';
    else if (api.method === 'PUT') methodColor = '#ffc107';
    else if (api.method === 'DELETE') methodColor = '#dc3545';
    else if (api.method === 'PATCH') methodColor = '#17a2b8';
    // Couleur status
    let statusColor = '#007bff';
    if (api.status_code === 201) statusColor = '#28a745';
    else if (api.status_code === 204) statusColor = '#28a745';
    else if (api.status_code === 400) statusColor = '#ffc107';
    else if (api.status_code === 401) statusColor = '#ffc107';
    else if (api.status_code === 403) statusColor = '#ffc107';
    else if (api.status_code === 404) statusColor = '#dc3545';
    else if (api.status_code === 500) statusColor = '#dc3545';
    else if (api.status_code >= 200 && api.status_code < 300) statusColor = '#28a745';
    else if (api.status_code >= 400 && api.status_code < 500) statusColor = '#ffc107';
    else if (api.status_code >= 500) statusColor = '#dc3545';
    else if (api.status_code >= 300 && api.status_code < 400) statusColor = '#17a2b8';
    let responseStr = '';
    try {
      responseStr = typeof api.response_json === 'string' ? api.response_json : JSON.stringify(api.response_json);
    } catch(e) { responseStr = String(api.response_json); }
    let shortResponse = responseStr.length > 20 ? responseStr.slice(0,20) + '…' : responseStr;
    html += `<tr>
      <td>${api.id}</td>
      <td>${api.name}</td>
      <td>${api.path}</td>
      <td><span style='color:${methodColor};font-weight:bold'>${api.method}</span></td>
      <td>
        <span>${shortResponse}</span>
        ${responseStr.length > 20 ? `<button title='Voir la réponse complète' style='background:none;border:none;cursor:pointer;padding:0 4px;vertical-align:middle;' onclick='window.showApiResponseFull(${JSON.stringify(responseStr)}, ${JSON.stringify({id: api.id, name: api.name, path: api.path})})'><svg width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='#007bff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'></path><circle cx='12' cy='12' r='3'></circle></svg></button>` : ''}
      </td>
      <td><span style='color:${statusColor};font-weight:bold'>${api.status_code}</span></td>
      <td>${api.enabled ? '<span style="color:var(--primary)"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg></span>' : '<span style="color:var(--danger)"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></span>'}
      </td>
      <td>${api.delay_ms ?? ''}</td>
      <td>${api.api_key ?? ''}</td>
      <td>${api.base_url ?? ''}</td>
      <td>${api.quota ? `${api.quota}/${api.quota_period}` : 'Illimité'}</td>
      <td>
        <button onclick='removeApiFromProject(${projectId},${api.id})' title='Dissocier cette API' style='background:none;border:none;cursor:pointer;'>
          <svg width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='orange' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><line x1='18' y1='6' x2='6' y2='18'></line><line x1='6' y1='6' x2='18' y2='18'></line></svg>
        </button>
      </td>
    </tr>`;
  }
  const tbody = document.getElementById('apisForProject'+projectId);
  tbody.innerHTML = html;
  // Ajout du scroll-list sur le parent du tableau
  const table = tbody.parentElement.parentElement;
  if (!table.parentElement.classList.contains('scroll-list')) {
    table.parentElement.classList.add('scroll-list');
  }
  if (apis.length > 8) {
    table.parentElement.style.maxHeight = '340px';
    table.parentElement.style.overflowY = 'auto';
  } else {
    table.parentElement.style.maxHeight = '';
    table.parentElement.style.overflowY = '';
  }
}
document.getElementById('projectForm').onsubmit = async (e)=>{
  e.preventDefault();
  const payload = {
    name: document.getElementById('projectName').value.trim(),
    description: document.getElementById('projectDesc').value.trim()
  };
  const res = await fetch('/admin/projects', {method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
  if (!res.ok) { showAlert('Erreur', 'error'); return; }
  showAlert('Projet créé ✅', 'success', 2500, `Projet ${payload.name}`);
  listProjects();
}
async function removeProject(projectId) {
  showConfirm(`Supprimer le projet #${projectId} ? Toutes les APIs associées seront dissociées.`, async () => {
    const res = await fetch(`/admin/projects/${projectId}`, {method:'DELETE'});
    if (!res.ok) { showAlert('Erreur suppression projet', 'error', 2500, `Projet #${projectId}`); return; }
    showAlert('Projet supprimé', 'success', 2500, `Projet #${projectId}`);
    listProjects();
    listApis();
  });
}
async function removeApiFromProject(projectId, apiId) {
  showConfirm(`Dissocier l'API #${apiId} du projet #${projectId} ?`, async () => {
    const res = await fetch(`/admin/projects/${projectId}/apis/${apiId}`, {method:'DELETE'});
    if (!res.ok) { showAlert('Erreur dissociation API', 'error', 2500, `API #${apiId} / Projet #${projectId}`); return; }
    showAlert('API dissociée du projet', 'success', 2500, `API #${apiId} / Projet #${projectId}`);
    listProjects();
    listApis();
  });
}
async function addApiToProject(projectId) {
  const input = document.getElementById('apiToAdd'+projectId);
  const apiId = parseInt(input.value);
  if (!apiId) { showAlert('ID API invalide', 'error', 2500, `Projet #${projectId}`); return; }
  const res = await fetch(`/admin/projects/${projectId}/apis/${apiId}`, {method:'POST'});
  const result = await res.json();
  if (result.added) {
    showAlert('API associée au projet', 'success', 2500, `API #${apiId} → Projet #${projectId}`);
    listProjects();
    listApis();
    input.value = '';
  } else {
    showAlert('Erreur association API', 'error', 2500, `API #${apiId} → Projet #${projectId}`);
  }
}
function showConfirm(msg, onYes) {
  let confirmBox = document.getElementById('customConfirmBox');
  if (!confirmBox) {
    confirmBox = document.createElement('div');
    confirmBox.id = 'customConfirmBox';
    confirmBox.style.position = 'fixed';
    confirmBox.style.top = '50%';
    confirmBox.style.left = '50%';
    confirmBox.style.transform = 'translate(-50%,-50%)';
    confirmBox.style.zIndex = '10000';
    confirmBox.style.background = 'var(--card-bg,#fff)';
    confirmBox.style.color = 'var(--text,#222)';
    confirmBox.style.padding = '32px 28px';
    confirmBox.style.borderRadius = '14px';
    confirmBox.style.boxShadow = '0 2px 24px #0003';
    confirmBox.style.fontSize = '1.1em';
    confirmBox.style.fontWeight = '500';
    confirmBox.style.display = 'none';
    confirmBox.innerHTML = `<div id='confirmMsg'></div><div style='margin-top:24px;text-align:right'><button id='confirmYes' style='margin-right:12px;background:var(--primary,#007bff);color:#fff'>Oui</button><button id='confirmNo' style='background:var(--danger,#c00);color:#fff'>Non</button></div>`;
    document.body.appendChild(confirmBox);
  }
  confirmBox.querySelector('#confirmMsg').textContent = msg;
  confirmBox.style.display = 'block';
  confirmBox.querySelector('#confirmYes').onclick = () => {
    confirmBox.style.display = 'none';
    onYes();
  };
  confirmBox.querySelector('#confirmNo').onclick = () => {
    confirmBox.style.display = 'none';
  };
}
function toggleTheme() {
  const root = document.documentElement;
  if (root.getAttribute('data-theme') === 'dark') {
    root.setAttribute('data-theme', 'light');
    localStorage.setItem('theme', 'light');
  } else {
    root.setAttribute('data-theme', 'dark');
    localStorage.setItem('theme', 'dark');
  }
}
window.onload = function() {
  const theme = localStorage.getItem('theme') || 'light';
  document.documentElement.setAttribute('data-theme', theme);
  listApis(); listProjects();
};
document.getElementById('reloadBtn').onclick = async ()=>{ await fetch('/admin/reload',{method:'POST'}); showAlert('Routes rechargées', 'success'); }

// Coloration méthode et status dans le formulaire d’API
const methodSelect = document.getElementById('method');
if (methodSelect) {
  methodSelect.onchange = function() {
    let color = '#007bff';
    if (this.value === 'POST') color = '#28a745';
    else if (this.value === 'PUT') color = '#ffc107';
    else if (this.value === 'DELETE') color = '#dc3545';
    else if (this.value === 'PATCH') color = '#17a2b8';
    this.style.color = color;
    this.style.fontWeight = 'bold';
  };
  methodSelect.onchange();
}
const statusInput = document.getElementById('status_code');
if (statusInput) {
  statusInput.oninput = function() {
    let val = parseInt(this.value);
    let color = '#007bff';
    if (val === 201 || val === 204) color = '#28a745';
    else if (val === 400 || val === 401 || val === 403) color = '#ffc107';
    else if (val === 404 || val === 500) color = '#dc3545';
    else if (val >= 200 && val < 300) color = '#28a745';
    else if (val >= 400 && val < 500) color = '#ffc107';
    else if (val >= 500) color = '#dc3545';
    else if (val >= 300 && val < 400) color = '#17a2b8';
    this.style.color = color;
    this.style.fontWeight = 'bold';
  };
  statusInput.oninput();
}

// Coloration dynamique dans le formulaire d'API
['method','status_code'].forEach(id => {
  const el = document.getElementById(id);
  if (el) {
    el.addEventListener('input', function() {
      let color = '#007bff';
      if (id === 'method') {
        if (el.value === 'POST') color = '#28a745';
        else if (el.value === 'PUT') color = '#ffc107';
        else if (el.value === 'DELETE') color = '#dc3545';
        else if (el.value === 'PATCH') color = '#17a2b8';
      } else {
        const val = parseInt(el.value);
        if (val === 201 || val === 204) color = '#28a745';
        else if (val === 400 || val === 401 || val === 403) color = '#ffc107';
        else if (val === 404 || val === 500) color = '#dc3545';
        else if (val >= 200 && val < 300) color = '#28a745';
        else if (val >= 400 && val < 500) color = '#ffc107';
        else if (val >= 500) color = '#dc3545';
        else if (val >= 300 && val < 400) color = '#17a2b8';
      }
      el.style.color = color;
      el.style.fontWeight = 'bold';
    });
    el.dispatchEvent(new Event('input'));
  }
}
);
