<!-- #region TaskLogPanel [C:3] [TYPE Component] [SEMANTICS log, panel, filter, autoscroll, list] -->
<!-- @BRIEF Component component: components/tasks/TaskLogPanel.svelte -->
<!-- @LAYER UI -->
<!--
@SEMANTICS: task, log, panel, filter, list
@PURPOSE: Combines log filtering and display into a single cohesive light-themed panel.
@LAYER UI
@RELATION USES -> [LogFilterBar]
@RELATION USES -> [LogEntryRow]
@INVARIANT: Must always display logs in chronological order and respect auto-scroll preference.
@UX_STATE: Empty -> Displays "No logs" message
@UX_STATE: Populated -> Displays list of LogEntryRow components
@UX_STATE: AutoScroll -> Automatically scrolls to bottom on new logs
-->
<script lang="ts">
  import { onMount, tick } from "svelte";
  import LogFilterBar from "./LogFilterBar.svelte";
  import LogEntryRow from "./LogEntryRow.svelte";

  let {
    logs = [],
    autoScroll = $bindable(true),
    onfilterchange = () => {},
  } = $props();
  let scrollContainer;
  let selectedSource = $state("all");
  let selectedLevel = $state("all");
  let searchText = $state("");

  let filteredLogs = $derived(
    filterLogs(logs, selectedLevel, selectedSource, searchText),
  );

  function filterLogs(allLogs, level, source, search) {
    return allLogs.filter((log) => {
      if (
        level &&
        level !== "all" &&
        log.level?.toUpperCase() !== level.toUpperCase()
      )
        return false;
      if (
        source &&
        source !== "all" &&
        log.source?.toLowerCase() !== source.toLowerCase()
      )
        return false;
      if (search && !log.message?.toLowerCase().includes(search.toLowerCase()))
        return false;
      return true;
    });
  }

  let availableSources = $derived([
    ...new Set(logs.map((l) => l.source).filter(Boolean)),
  ]);

  function handleFilterChange(event) {
    const { source, level, search } = event;
    selectedSource = source || "all";
    selectedLevel = level || "all";
    searchText = search || "";
    onfilterchange({ source, level, search });
  }

  function scrollToBottom() {
    if (autoScroll && scrollContainer) {
      scrollContainer.scrollTop = scrollContainer.scrollHeight;
    }
  }

  function toggleAutoScroll() {
    autoScroll = !autoScroll;
    if (autoScroll) scrollToBottom();
  }

  // Use $effect instead of afterUpdate for runes mode
  $effect(() => {
    filteredLogs.length;
    tick().then(scrollToBottom);
  });

  onMount(() => {
    scrollToBottom();
  });
</script>

<div class="flex flex-col h-full bg-white overflow-hidden rounded-lg border border-gray-200 shadow-sm">
  <!-- Filter Bar -->
  <LogFilterBar {availableSources} onfilterchange={handleFilterChange} />

  <!-- Log List -->
  <div
    bind:this={scrollContainer}
    class="flex-1 overflow-y-auto overflow-x-hidden"
  >
    {#if filteredLogs.length === 0}
      <div
        class="flex flex-col items-center justify-center py-12 px-4 text-gray-300 gap-3"
      >
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="32"
          height="32"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="1.5"
        >
          <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" />
          <polyline points="14 2 14 8 20 8" />
          <line x1="16" y1="13" x2="8" y2="13" />
          <line x1="16" y1="17" x2="8" y2="17" />
          <polyline points="10 9 9 9 8 9" />
        </svg>
        <span class="text-sm text-gray-400">No logs available</span>
      </div>
    {:else}
      {#each filteredLogs as log}
        <LogEntryRow {log} />
      {/each}
    {/if}
  </div>

  <!-- Footer Stats -->
  <div
    class="flex items-center justify-between py-1.5 px-4 border-t border-gray-200 bg-gray-50"
  >
    <span class="font-mono text-xs text-gray-400">
      {filteredLogs.length}{filteredLogs.length !== logs.length
        ? ` / ${logs.length}`
        : ""} entries
    </span>
    <button
      class="flex items-center gap-1.5 bg-transparent border-none text-xs cursor-pointer py-1 px-1.5 rounded transition-all hover:bg-gray-200 hover:text-gray-700
        {autoScroll ? 'text-primary font-medium' : 'text-gray-400'}"
      onclick={toggleAutoScroll}
      aria-label="Toggle auto-scroll"
    >
      {#if autoScroll}
        <span
          class="inline-block w-1.5 h-1.5 rounded-full bg-primary animate-pulse"
        ></span>
      {/if}
      Auto-scroll {autoScroll ? "on" : "off"}
    </button>
  </div>
</div>
<!-- #endregion TaskLogPanel -->
