{% extends "base.html" %}

{% block content %}
  <section class="section">
    <div class="container">
      <h1 class="title is-4">System Maintenance</h1>
      <p class="subtitle is-6">Superuser tools for data cleanup (current user scope).</p>

      {% if notice_message %}
        <article class="notification is-{{ notice_level|default:'info' }} is-light">
          {{ notice_message }}
        </article>
      {% endif %}

      <div class="columns is-multiline">
        <div class="column is-12">
          <article class="box">
            <h2 class="title is-6">Purge Non-OSINT Data</h2>
            <p class="is-size-7 has-text-grey" style="margin-bottom: 0.65rem;">
              Removes message/workspace/AI/mitigation runtime rows but keeps OSINT setup objects.
            </p>
            <div class="tags" style="margin-bottom: 0.75rem;">
              <span class="tag is-light">Chat Sessions: {{ counts.chat_sessions }}</span>
              <span class="tag is-light">Messages: {{ counts.messages }}</span>
              <span class="tag is-light">Queued: {{ counts.queued_messages }}</span>
              <span class="tag is-light">Events: {{ counts.message_events }}</span>
              <span class="tag is-info is-light">Behavioral Events: {{ counts.behavioral_event_rows }}</span>
              <span class="tag is-light">Event Shadow Rows: {{ counts.conversation_event_shadow_rows }}</span>
              <span class="tag is-light">Workspace: {{ counts.workspace_conversations }}</span>
              <span class="tag is-light">Snapshots: {{ counts.workspace_snapshots }}</span>
              <span class="tag is-light">AI Requests: {{ counts.ai_requests }}</span>
              <span class="tag is-light">AI Results: {{ counts.ai_results }}</span>
              <span class="tag is-light">Memory: {{ counts.memory_items }}</span>
              <span class="tag is-light">Mitigation Plans: {{ counts.mitigation_plans }}</span>
            </div>
            <form method="post">
              {% csrf_token %}
              <input type="hidden" name="action" value="purge_non_osint">
              <button type="submit" class="button is-danger is-light">Purge Non-OSINT</button>
            </form>
          </article>
        </div>

        <div class="column is-12">
          <article class="box">
            <h2 class="title is-6">Diagnostics Quick Checks</h2>
            <p class="is-size-7 has-text-grey" style="margin-bottom: 0.65rem;">
              Run projection shadow, event ledger smoke, and trace diagnostics from one place.
            </p>
            <div class="columns is-multiline">
              <div class="column is-12-tablet is-3-desktop">
                <form id="projection-shadow-form">
                  <label class="label is-size-7">Projection Shadow</label>
                  <div class="field">
                    <div class="control">
                      <input class="input is-small" name="session_lookup" placeholder="name | id | service | identifier" list="diagnostics-session-options" required>
                      <input type="hidden" name="session_id">
                    </div>
                    <p class="help is-size-7" title="Use this when a thread looks wrong in Compose and you need to compare DB messages vs event projection.">Pick a session to compare message table vs event projection.</p>
                  </div>
                  <div class="field">
                    <div class="control">
                      <input class="input is-small" name="detail_limit" value="25" type="number" min="0" max="200">
                    </div>
                  </div>
                  <button class="button is-small is-link is-light" type="submit">Run Shadow</button>
                </form>
              </div>
              <div class="column is-12-tablet is-3-desktop">
                <form id="event-ledger-smoke-form">
                  <label class="label is-size-7">Event Ledger Smoke</label>
                  <div class="field">
                    <div class="control">
                      <input class="input is-small" name="minutes" value="120" type="number" min="1" max="10080">
                    </div>
                    <p class="help is-size-7" title="Use this to check that recent traffic is actually writing canonical events.">Checks whether recent actions were written to the behavioral event ledger in Manticore, with Django shadow rows as fallback context.</p>
                  </div>
                  <div class="field">
                    <div class="control">
                      <input class="input is-small" name="service" placeholder="service" list="diagnostics-service-options">
                    </div>
                  </div>
                  <div class="field">
                    <div class="control">
                      <input class="input is-small" name="require_types" placeholder="message_created,reaction_added" list="diagnostics-event-type-options">
                    </div>
                    <p class="help is-size-7" title="If set, response includes missing required event types so you can quickly spot dual-write gaps.">Optional required event types (comma-separated).</p>
                  </div>
                  <button class="button is-small is-link is-light" type="submit">Run Smoke</button>
                </form>
              </div>
              <div class="column is-12-tablet is-3-desktop">
                <form id="trace-diagnostics-form">
                  <label class="label is-size-7">Trace Diagnostics</label>
                  <div class="field">
                    <div class="control">
                      <input class="input is-small" name="trace_id" placeholder="select recent trace id or paste one" list="diagnostics-trace-options" required>
                    </div>
                    <p class="help is-size-7" title="Use this to reconstruct ingress -> persistence -> fanout path and jump to projection-shadow for linked sessions.">Use a trace id from the dropdown (recent traces), Event Ledger Smoke `sample[].trace_id`, or UR logs.</p>
                  </div>
                  <button class="button is-small is-link is-light" type="submit">Lookup Trace</button>
                </form>
              </div>
              <div class="column is-12-tablet is-3-desktop">
                <form id="memory-search-form">
                  <label class="label is-size-7">Memory Search</label>
                  <div class="field">
                    <div class="control">
                      <input class="input is-small" name="q" placeholder="search memory text" required>
                    </div>
                    <p class="help is-size-7" title="Use this for fast retrieval over AI memory/wiki text; backend can be django or manticore.">Query memory index and inspect top matches.</p>
                  </div>
                  <div class="field">
                    <div class="control">
                      <input class="input is-small" name="statuses" placeholder="active" value="active">
                    </div>
                  </div>
                  <button class="button is-small is-link is-light" type="submit">Query Memory</button>
                  <button class="button is-small is-light" type="button" id="memory-search-status">Backend Status</button>
                </form>
              </div>
            </div>
            <datalist id="diagnostics-session-options">
              {% for row in diagnostics_options.sessions %}
                <option value="{{ row.label }}" data-session-id="{{ row.id }}"></option>
              {% endfor %}
            </datalist>
            <datalist id="diagnostics-trace-options">
              {% for trace_id in diagnostics_options.trace_ids %}
                <option value="{{ trace_id }}"></option>
              {% endfor %}
            </datalist>
            <datalist id="diagnostics-service-options">
              {% for service in diagnostics_options.services %}
                <option value="{{ service }}"></option>
              {% endfor %}
            </datalist>
            <datalist id="diagnostics-event-type-options">
              {% for event_type in diagnostics_options.event_types %}
                <option value="{{ event_type }}"></option>
              {% endfor %}
            </datalist>
            <div class="buttons are-small" style="margin-bottom: 0.5rem;">
              <button id="diagnostics-select-all" type="button" class="button is-light">Select All</button>
              <button id="diagnostics-copy" type="button" class="button is-light">Copy</button>
            </div>
            <pre id="diagnostics-output" class="is-size-7" style="max-height: 20rem; overflow:auto; background:#f7f7f7; padding:0.75rem; border-radius:8px;"></pre>
          </article>
        </div>

        <div class="column is-12">
          <article class="box">
            <h2 class="title is-6">Purge OSINT Setup Categories</h2>
            <p class="is-size-7 has-text-grey" style="margin-bottom: 0.65rem;">
              Category-specific cleanup controls.
            </p>
            <div class="buttons are-small" style="margin-bottom: 0.75rem;">
              <form method="post" style="margin: 0;">
                {% csrf_token %}
                <input type="hidden" name="action" value="purge_osint_people">
                <button type="submit" class="button is-warning is-light">Purge People ({{ counts.osint_people }})</button>
              </form>
              <form method="post" style="margin: 0;">
                {% csrf_token %}
                <input type="hidden" name="action" value="purge_osint_identifiers">
                <button type="submit" class="button is-warning is-light">Purge Identifiers ({{ counts.osint_identifiers }})</button>
              </form>
              <form method="post" style="margin: 0;">
                {% csrf_token %}
                <input type="hidden" name="action" value="purge_osint_groups">
                <button type="submit" class="button is-warning is-light">Purge Groups ({{ counts.osint_groups }})</button>
              </form>
              <form method="post" style="margin: 0;">
                {% csrf_token %}
                <input type="hidden" name="action" value="purge_osint_personas">
                <button type="submit" class="button is-warning is-light">Purge Personas ({{ counts.osint_personas }})</button>
              </form>
            </div>
          </article>
        </div>
      </div>
    </div>
  </section>
  <script>
    (function () {
      const out = document.getElementById("diagnostics-output");
      const shadowForm = document.getElementById("projection-shadow-form");
      const smokeForm = document.getElementById("event-ledger-smoke-form");
      const traceForm = document.getElementById("trace-diagnostics-form");
      const memoryForm = document.getElementById("memory-search-form");
      const memoryStatusBtn = document.getElementById("memory-search-status");
      const selectAllBtn = document.getElementById("diagnostics-select-all");
      const copyBtn = document.getElementById("diagnostics-copy");
      const sessionOptionMap = new Map();
      const sessionDatalist = document.getElementById("diagnostics-session-options");
      if (sessionDatalist) {
        sessionDatalist.querySelectorAll("option").forEach(function (opt) {
          const key = (opt.value || "").trim();
          const sessionId = (opt.dataset.sessionId || "").trim();
          if (key && sessionId) {
            sessionOptionMap.set(key, sessionId);
          }
        });
      }

      function write(text) {
        if (out) {
          out.textContent = text;
        }
      }

      function outputText() {
        return out ? (out.textContent || "") : "";
      }

      function selectOutputText() {
        if (!out) return;
        const range = document.createRange();
        range.selectNodeContents(out);
        const selection = window.getSelection();
        if (!selection) return;
        selection.removeAllRanges();
        selection.addRange(range);
      }

      async function copyOutputText() {
        const text = outputText();
        if (!text) return;
        try {
          await navigator.clipboard.writeText(text);
          write(text + "\n\n[Copied]");
          return;
        } catch (err) {
          const area = document.createElement("textarea");
          area.value = text;
          area.style.position = "fixed";
          area.style.opacity = "0";
          document.body.appendChild(area);
          area.focus();
          area.select();
          try {
            document.execCommand("copy");
            write(text + "\n\n[Copied]");
          } finally {
            document.body.removeChild(area);
          }
        }
      }

      async function runGet(url, params) {
        const query = new URLSearchParams(params);
        const response = await fetch(`${url}?${query.toString()}`, { headers: { "Accept": "application/json" } });
        const payload = await response.json();
        return { status: response.status, payload };
      }

      shadowForm.addEventListener("submit", async function (ev) {
        ev.preventDefault();
        write("Running projection shadow...");
        const form = new FormData(shadowForm);
        const sessionLookup = (form.get("session_lookup") || "").toString().trim();
        const sessionId = sessionOptionMap.get(sessionLookup) || sessionLookup;
        const result = await runGet("{% url 'system_projection_shadow' %}", {
          session_id: sessionId,
          detail_limit: (form.get("detail_limit") || "25").toString().trim(),
        });
        write(JSON.stringify(result, null, 2));
      });

      smokeForm.addEventListener("submit", async function (ev) {
        ev.preventDefault();
        write("Running event ledger smoke...");
        const form = new FormData(smokeForm);
        const result = await runGet("{% url 'system_event_ledger_smoke' %}", {
          minutes: (form.get("minutes") || "120").toString().trim(),
          service: (form.get("service") || "").toString().trim(),
          require_types: (form.get("require_types") || "").toString().trim(),
        });
        write(JSON.stringify(result, null, 2));
      });

      traceForm.addEventListener("submit", async function (ev) {
        ev.preventDefault();
        write("Running trace diagnostics...");
        const form = new FormData(traceForm);
        const result = await runGet("{% url 'system_trace_diagnostics' %}", {
          trace_id: (form.get("trace_id") || "").toString().trim(),
        });
        write(JSON.stringify(result, null, 2));
      });

      memoryForm.addEventListener("submit", async function (ev) {
        ev.preventDefault();
        write("Running memory search...");
        const form = new FormData(memoryForm);
        const result = await runGet("{% url 'system_memory_search_query' %}", {
          q: (form.get("q") || "").toString().trim(),
          statuses: (form.get("statuses") || "active").toString().trim(),
          limit: "20",
        });
        write(JSON.stringify(result, null, 2));
      });

      if (memoryStatusBtn) {
        memoryStatusBtn.addEventListener("click", async function () {
          write("Checking memory search backend...");
          const result = await runGet("{% url 'system_memory_search_status' %}", {});
          write(JSON.stringify(result, null, 2));
        });
      }

      if (selectAllBtn) {
        selectAllBtn.addEventListener("click", function () {
          selectOutputText();
        });
      }
      if (copyBtn) {
        copyBtn.addEventListener("click", function () {
          copyOutputText();
        });
      }
    })();
  </script>
{% endblock %}
