{% extends 'base.html' %}
{% load i18n %}

{% block title %}Nginx IP Ban Manager{% endblock %}

{% block content %}
<div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-6">

  <!-- Header -->
  <div class="flex items-center gap-3">
    <a href="{% url 'mini-apps-list' %}" class="text-gray-400 hover:text-gray-600">
      <i class="fas fa-arrow-left"></i>
    </a>
    <div>
      <h1 class="text-xl font-bold text-gray-900 flex items-center gap-2">
        <i class="fas fa-ban text-red-500"></i> Nginx IP Ban Manager
      </h1>
      <p class="text-sm text-gray-400 mt-0.5">
        Manages <code class="bg-gray-100 px-1 rounded text-xs">block-cidrs-manual</code>
        in the <code class="bg-gray-100 px-1 rounded text-xs">ingress-nginx-controller</code> ConfigMap
      </p>
    </div>
  </div>

  <!-- Error banner -->
  {% if error %}
  <div id="error-banner" class="px-4 py-3 rounded-md text-sm border bg-red-50 text-red-800 border-red-200">
    <i class="fas fa-exclamation-triangle mr-2"></i>{{ error }}
  </div>
  {% endif %}

  <!-- AJAX feedback -->
  <div id="feedback" class="hidden px-4 py-2 rounded-md text-sm border"></div>

  <!-- Add IPs -->
  <div class="bg-white shadow-sm rounded-lg border border-gray-200 overflow-hidden">
    <div class="px-6 py-4 bg-gray-50 border-b border-gray-200">
      <h2 class="text-sm font-semibold text-gray-700">
        <i class="fas fa-plus-circle text-red-500 mr-1"></i> Ban IP(s) / CIDR(s)
      </h2>
      <p class="text-xs text-gray-400 mt-0.5">
        Enter one or more IPs or CIDRs, comma- or newline-separated.
        Examples: <code class="bg-gray-100 px-1 rounded">1.2.3.4</code>,
        <code class="bg-gray-100 px-1 rounded">5.6.7.0/24</code>
      </p>
    </div>
    <div class="p-6">
      <textarea id="add-ips-input" rows="3"
                placeholder="1.2.3.4&#10;5.6.7.0/24&#10;8.8.8.8, 9.9.9.9"
                class="w-full border border-gray-300 rounded-md px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-red-400 focus:border-transparent"></textarea>
      <div class="mt-3 flex items-center gap-3">
        <button id="add-btn"
                class="inline-flex items-center px-5 py-2 bg-red-600 text-white text-sm font-medium rounded-md hover:bg-red-700 transition-colors">
          <i class="fas fa-ban mr-2"></i> Ban IPs
        </button>
        <span class="text-xs text-gray-400">Duplicates are skipped automatically.</span>
      </div>
    </div>
  </div>

  <!-- Banned IPs list -->
  <div class="bg-white shadow-sm rounded-lg border border-gray-200 overflow-hidden">
    <div class="px-6 py-4 bg-gray-50 border-b border-gray-200 flex items-center justify-between">
      <h2 class="text-sm font-semibold text-gray-700">
        <i class="fas fa-list text-gray-500 mr-1"></i>
        Currently Banned
        <span id="count-badge"
              class="ml-2 inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-700">
          {{ blocked|length }}
        </span>
      </h2>
    </div>

    <div id="ip-list">
      {% if blocked %}
      <ul class="divide-y divide-gray-100">
        {% for ip in blocked %}
        <li class="flex items-center justify-between px-6 py-3 hover:bg-gray-50" data-ip="{{ ip }}">
          <span class="font-mono text-sm text-gray-800">{{ ip }}</span>
          <button class="remove-btn text-xs text-red-500 hover:text-red-700 font-medium transition-colors"
                  data-ip="{{ ip }}">
            <i class="fas fa-times mr-1"></i>Remove
          </button>
        </li>
        {% endfor %}
      </ul>
      {% else %}
      <p id="empty-msg" class="px-6 py-8 text-sm text-gray-400 text-center">
        <i class="fas fa-check-circle text-green-400 mr-2"></i>No IPs are currently banned.
      </p>
      {% endif %}
    </div>
  </div>

</div>

<script>
(function () {
  const csrfToken = '{{ csrf_token }}';
  const feedbackEl = document.getElementById('feedback');
  const listEl = document.getElementById('ip-list');
  const countBadge = document.getElementById('count-badge');

  function showFeedback(msg, isError) {
    feedbackEl.textContent = msg;
    feedbackEl.className = isError
      ? 'px-4 py-2 rounded-md text-sm border bg-red-50 text-red-800 border-red-200'
      : 'px-4 py-2 rounded-md text-sm border bg-green-50 text-green-800 border-green-200';
    feedbackEl.classList.remove('hidden');
    clearTimeout(feedbackEl._t);
    feedbackEl._t = setTimeout(() => feedbackEl.classList.add('hidden'), 4000);
  }

  function renderList(blocked) {
    countBadge.textContent = blocked.length;
    if (blocked.length === 0) {
      listEl.innerHTML = '<p id="empty-msg" class="px-6 py-8 text-sm text-gray-400 text-center"><i class="fas fa-check-circle text-green-400 mr-2"></i>No IPs are currently banned.</p>';
      return;
    }
    const rows = blocked.map(ip =>
      `<li class="flex items-center justify-between px-6 py-3 hover:bg-gray-50" data-ip="${escHtml(ip)}">
         <span class="font-mono text-sm text-gray-800">${escHtml(ip)}</span>
         <button class="remove-btn text-xs text-red-500 hover:text-red-700 font-medium transition-colors" data-ip="${escHtml(ip)}">
           <i class="fas fa-times mr-1"></i>Remove
         </button>
       </li>`
    ).join('');
    listEl.innerHTML = `<ul class="divide-y divide-gray-100">${rows}</ul>`;
    listEl.querySelectorAll('.remove-btn').forEach(btn => btn.addEventListener('click', handleRemove));
  }

  function escHtml(str) {
    return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
  }

  async function post(data) {
    const body = new URLSearchParams({csrfmiddlewaretoken: csrfToken, ...data});
    const resp = await fetch(window.location.pathname, {method: 'POST', body});
    return resp.json();
  }

  // Add
  document.getElementById('add-btn').addEventListener('click', async () => {
    const input = document.getElementById('add-ips-input');
    const val = input.value.trim();
    if (!val) return;
    try {
      const data = await post({action: 'add', ips: val});
      if (data.ok) {
        input.value = '';
        renderList(data.blocked);
        showFeedback(`✓ Banned ${data.added} new IP(s). Total: ${data.blocked.length}.`, false);
      } else {
        showFeedback('Error: ' + data.error, true);
      }
    } catch (e) {
      showFeedback('Network error: ' + e, true);
    }
  });

  // Remove (delegated for dynamically rendered rows)
  listEl.addEventListener('click', handleRemoveDelegated);

  async function handleRemoveDelegated(e) {
    const btn = e.target.closest('.remove-btn');
    if (!btn) return;
    await handleRemove.call(btn, e);
  }

  async function handleRemove(e) {
    const ip = this.dataset.ip;
    if (!confirm(`Remove "${ip}" from the ban list?`)) return;
    try {
      const data = await post({action: 'remove', ip});
      if (data.ok) {
        renderList(data.blocked);
        showFeedback(`✓ Removed ${ip}.`, false);
      } else {
        showFeedback('Error: ' + data.error, true);
      }
    } catch (e) {
      showFeedback('Network error: ' + e, true);
    }
  }

  // Wire up initial remove buttons
  listEl.querySelectorAll('.remove-btn').forEach(btn => btn.addEventListener('click', handleRemove));
})();
</script>
{% endblock %}
