<script>
  import { get } from "../../lib/api.js";
  import { onMount } from "svelte";

  let logs = $state([]);
  let stats = $state(null);
  let loading = $state(false);
  let filter = $state("all");
  let ipFilter = $state("");
  let startDate = $state("");
  let endDate = $state("");
  let filterError = $state("");

  onMount(loadAll);

  async function loadAll() {
    loading = true;
    await Promise.all([loadStats(), loadLogs()]);
    loading = false;
  }

  async function loadStats() {
    try {
      stats = await get("/security/stats");
    } catch (e) {
      console.error("Failed to load security stats:", e);
    }
  }

  function buildLogsQuery() {
    const params = new URLSearchParams({ limit: "300" });
    if (filter !== "all") params.set("type", filter);
    if (ipFilter.trim()) params.set("ip", ipFilter.trim());
    if (startDate) params.set("start_date", startDate);
    if (endDate) params.set("end_date", endDate);
    return params.toString();
  }

  function validateFilters() {
    if (startDate && endDate && startDate > endDate) {
      filterError = "From date must be on or before To date";
      return false;
    }
    filterError = "";
    return true;
  }

  async function loadLogs() {
    if (!validateFilters()) {
      logs = [];
      return;
    }

    try {
      const res = await get(`/security/logs?${buildLogsQuery()}`);
      logs = res.logs;
    } catch (e) {
      console.error("Failed to load security logs:", e);
    }
  }

  async function applyTypeFilter(nextFilter) {
    filter = nextFilter;
    await loadLogs();
  }

  async function applyIpFilter(ip) {
    ipFilter = ip;
    await loadLogs();
  }

  async function clearFilters() {
    filter = "all";
    ipFilter = "";
    startDate = "";
    endDate = "";
    filterError = "";
    await loadLogs();
  }

  let maxTimelineCount = $derived(
    stats ? Math.max(1, ...stats.timeline.map(t => t.count)) : 1
  );

  let hasActiveFilters = $derived(
    filter !== "all" || !!ipFilter.trim() || !!startDate || !!endDate
  );

  function isBlockedScannerEvent(entry) {
    if (entry.type !== "unauthorized") return false;

    const message = (entry.message || "").toLowerCase();
    return [
      "/.git/",
      "phpinfo",
      "debug.log",
      "laravel.log",
      "stripe",
      "swagger.json",
      "wp-config",
      "credentials",
      "secrets",
      "config",
      "@vite",
      "manifest.json",
    ].some((needle) => message.includes(needle));
  }

  const logTypeFilters = ["all", "auth_failure", "suspicious_request", "unauthorized"];
  const logTypeButtonLabels = {
    all: "All",
    auth_failure: "Auth",
    suspicious_request: "Requests",
    unauthorized: "Blocked",
  };

  const typeLabels = { auth_failure: "Auth", suspicious_request: "Request", unauthorized: "Blocked", error: "Error" };
  const typeColors = {
    auth_failure: "text-red-400",
    suspicious_request: "text-amber-400",
    unauthorized: "text-orange-400",
    error: "text-surface-500"
  };
</script>

<div class="space-y-6">
  <div class="flex items-center justify-between">
    <h2 class="text-lg font-bold text-surface-800 dark:text-surface-100">Security</h2>
    <button onclick={loadAll} disabled={loading} class="px-3 py-1.5 text-xs font-medium text-primary-600 bg-primary-50 hover:bg-primary-100 rounded-lg transition-colors disabled:opacity-50 dark:bg-primary-900/30 dark:text-primary-300">
      {loading ? "Loading..." : "Refresh"}
    </button>
  </div>

  <!-- Stats cards -->
  {#if stats}
    <div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
      <div class="bg-white dark:bg-surface-800 rounded-xl border border-surface-200 dark:border-surface-700 p-5 shadow-sm">
        <p class="text-xs font-medium text-surface-400 uppercase tracking-wider">Failed Logins (24h)</p>
        <p class="text-2xl font-bold text-red-600 dark:text-red-400 mt-1">{stats.failed_logins_24h}</p>
      </div>
      <div class="bg-white dark:bg-surface-800 rounded-xl border border-surface-200 dark:border-surface-700 p-5 shadow-sm">
        <p class="text-xs font-medium text-surface-400 uppercase tracking-wider">Suspicious Requests</p>
        <p class="text-2xl font-bold text-amber-600 dark:text-amber-400 mt-1">{stats.suspicious_requests}</p>
      </div>
      <div class="bg-white dark:bg-surface-800 rounded-xl border border-surface-200 dark:border-surface-700 p-5 shadow-sm">
        <p class="text-xs font-medium text-surface-400 uppercase tracking-wider">Unique IPs</p>
        <p class="text-2xl font-bold text-surface-700 dark:text-surface-200 mt-1">{stats.unique_ips}</p>
      </div>
    </div>
  {/if}

  <!-- Timeline chart -->
  {#if stats?.timeline}
    <div class="bg-white dark:bg-surface-800 rounded-xl border border-surface-200 dark:border-surface-700 p-5 shadow-sm">
      <h3 class="text-sm font-semibold text-surface-700 dark:text-surface-200 mb-3">Activity (Last 24h)</h3>
      <div class="flex items-end gap-1 h-24">
        {#each [...stats.timeline].reverse() as bar}
          <div class="flex-1 flex flex-col items-center justify-end h-full">
            <div
              class="w-full rounded-t transition-all {bar.count > 0 ? 'bg-primary-500 dark:bg-primary-400' : 'bg-surface-100 dark:bg-surface-700'}"
              style="height: {bar.count > 0 ? Math.max(8, (bar.count / maxTimelineCount) * 100) : 4}%"
              title="{bar.hours_ago}h ago: {bar.count} events"
            ></div>
          </div>
        {/each}
      </div>
      <div class="flex justify-between mt-1">
        <span class="text-[10px] text-surface-400">24h ago</span>
        <span class="text-[10px] text-surface-400">now</span>
      </div>
    </div>
  {/if}

  <!-- Top IPs -->
  {#if stats?.top_ips?.length}
    <div class="bg-white dark:bg-surface-800 rounded-xl border border-surface-200 dark:border-surface-700 p-5 shadow-sm">
      <h3 class="text-sm font-semibold text-surface-700 dark:text-surface-200 mb-3">Top IPs</h3>
      <div class="space-y-2">
        {#each stats.top_ips as entry}
          <div class="flex items-center gap-3 text-sm">
            <button onclick={() => applyIpFilter(entry.ip)} class="text-xs font-mono text-surface-600 hover:text-primary-600 dark:text-surface-300 dark:hover:text-primary-300 w-36 shrink-0 text-left transition-colors">{entry.ip}</button>
            <div class="flex-1 bg-surface-100 dark:bg-surface-700 rounded-full h-2 overflow-hidden">
              <div class="bg-red-500 dark:bg-red-400 h-full rounded-full" style="width: {(entry.count / stats.top_ips[0].count) * 100}%"></div>
            </div>
            <span class="text-xs text-surface-500 w-8 text-right">{entry.count}</span>
          </div>
        {/each}
      </div>
    </div>
  {/if}

  <!-- Log table -->
  <div class="bg-white dark:bg-surface-800 rounded-xl border border-surface-200 dark:border-surface-700 p-5 shadow-sm">
    <div class="flex items-start justify-between gap-3 mb-3">
      <div>
        <h3 class="text-sm font-semibold text-surface-700 dark:text-surface-200">Event Log</h3>
        <p class="text-xs text-surface-400 mt-1">Filter recent events by type, IP, or date range.</p>
      </div>
      {#if hasActiveFilters}
        <button onclick={clearFilters} class="px-2.5 py-1 text-xs rounded-md transition-colors bg-surface-100 text-surface-500 hover:bg-surface-200 dark:bg-surface-700 dark:text-surface-300 dark:hover:bg-surface-600">
          Clear filters
        </button>
      {/if}
    </div>

    <div class="flex flex-wrap gap-1.5 mb-3">
      {#each logTypeFilters as f}
        <button onclick={() => applyTypeFilter(f)} class="px-2.5 py-1 text-xs rounded-md transition-colors {filter === f ? 'bg-surface-800 text-white dark:bg-surface-200 dark:text-surface-900' : 'bg-surface-100 text-surface-500 hover:bg-surface-200 dark:bg-surface-700 dark:text-surface-300 dark:hover:bg-surface-600'}">
          {logTypeButtonLabels[f]}
        </button>
      {/each}
    </div>

    <div class="grid grid-cols-1 sm:grid-cols-3 gap-3 mb-3">
      <label class="block">
        <span class="block text-xs font-medium text-surface-500 mb-1">Filter by IP</span>
        <input
          type="text"
          bind:value={ipFilter}
          placeholder="e.g. 1.2.3.4"
          onkeydown={async (e) => { if (e.key === 'Enter') await loadLogs(); }}
          class="w-full px-3 py-2 text-sm border border-surface-200 dark:border-surface-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-surface-700 dark:text-white"
        />
      </label>
      <label class="block">
        <span class="block text-xs font-medium text-surface-500 mb-1">From</span>
        <input
          type="date"
          bind:value={startDate}
          onchange={loadLogs}
          class="w-full px-3 py-2 text-sm border border-surface-200 dark:border-surface-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-surface-700 dark:text-white"
        />
      </label>
      <label class="block">
        <span class="block text-xs font-medium text-surface-500 mb-1">To</span>
        <input
          type="date"
          bind:value={endDate}
          onchange={loadLogs}
          class="w-full px-3 py-2 text-sm border border-surface-200 dark:border-surface-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-surface-700 dark:text-white"
        />
      </label>
    </div>

    <div class="flex items-center gap-2 mb-3">
      <button onclick={loadLogs} class="px-3 py-1.5 text-xs font-medium text-primary-600 bg-primary-50 hover:bg-primary-100 rounded-lg transition-colors dark:bg-primary-900/30 dark:text-primary-300">
        Apply filters
      </button>
      {#if ipFilter.trim()}
        <button onclick={() => applyIpFilter(ipFilter.trim())} class="px-2.5 py-1 text-xs rounded-md transition-colors bg-surface-100 text-surface-500 hover:bg-surface-200 dark:bg-surface-700 dark:text-surface-300 dark:hover:bg-surface-600">
          Use typed IP
        </button>
      {/if}
    </div>

    {#if filterError}
      <p class="text-sm text-rose-500 mb-3">{filterError}</p>
    {/if}

    {#if logs.length > 0}
      <div class="max-h-96 overflow-auto rounded-lg bg-surface-950 p-3 space-y-0.5">
        {#each logs as e}
          <div class="text-xs font-mono flex gap-2 leading-5">
            <span class="{typeColors[e.type] || 'text-surface-500'} w-12 shrink-0">{typeLabels[e.type] || e.type}</span>
            <span class="text-surface-500 shrink-0">{e.timestamp}</span>
            {#if e.ip}
              <button onclick={() => applyIpFilter(e.ip)} class="text-surface-400 hover:text-primary-300 shrink-0 w-28 text-left transition-colors">{e.ip}</button>
            {/if}
            {#if e.username}
              <span class="text-red-400 shrink-0">{e.username}</span>
            {/if}
            {#if isBlockedScannerEvent(e)}
              <span class="shrink-0 rounded-md bg-orange-500/15 px-1.5 py-0.5 text-[10px] font-medium text-orange-300 border border-orange-500/30">scanner</span>
            {/if}
            <span class="text-surface-300 truncate">{e.message}</span>
          </div>
        {/each}
      </div>
    {:else if !loading}
      <p class="text-sm text-surface-400">{hasActiveFilters ? "No security events match the current filters" : "No security events found"}</p>
    {/if}
  </div>
</div>
