<script lang="ts">
  // Floating-window content for a task/session — self-contained per
  // sessionId via chat.ts's chatFor()/loadSessionChat()/sendSessionMessage()
  // and workspace.ts's workspaceFor()/startSessionWorkspace(), so several of
  // these can be open (and independently live) at once.
  import { onDestroy, onMount } from 'svelte'
  import { Pane, Splitpanes } from 'svelte-splitpanes'
  import { chatFor, loadSessionChat, sendSessionMessage, cancelSessionStream, stopSessionPolling, dismissError, chatErrors } from '$lib/stores/chat'
  import { activityLogFor } from '$lib/stores/activity'
  import { workspaceFor, startSessionWorkspace } from '$lib/stores/workspace'
  import ChatThread from '$lib/components/ChatThread.svelte'
  import TaskContextPanel from '$lib/components/TaskContextPanel.svelte'

  let { sessionId }: { sessionId: string } = $props()

  // Svelte's `$store` auto-subscription only works on a plain identifier
  // bound directly to a store, not a member expression — chatFor() returns
  // an object of stores, so pull each one out into its own identifier here.
  // sessionId is a stable prop (one per window mount, never changes), so
  // capturing it at init is safe and intended.
  // eslint-disable-next-line svelte/valid-compile
  const chat = chatFor(sessionId)
  const chatMessages = chat.messages
  const chatStreaming = chat.streaming
  const chatConnectionState = chat.connectionState
  const chatError = chat.error
  const chatNotFound = chat.notFound
  // eslint-disable-next-line svelte/valid-compile
  const sessionActivityLog = activityLogFor(sessionId)
  // Started here (rather than left to TaskContextPanel's own onMount) so the
  // workspace is already tracking touched entities/plan/questions before the
  // context rail ever mounts — it needs that live even while the rail stays
  // hidden (see hasContext below).
  // eslint-disable-next-line svelte/valid-compile
  const workspace = workspaceFor(sessionId)
  // eslint-disable-next-line svelte/valid-compile
  const touchedEntities = workspace.touched
  // eslint-disable-next-line svelte/valid-compile
  const openQuestion = workspace.openQuestion
  let loading = $state(true)

  // The context rail (Scope/Activity) is only worth its screen space once
  // there's something in it — a brand-new task otherwise opens to an empty
  // "entities appear here" placeholder next to an equally empty activity
  // list. Show it the moment either has real content, and keep it shown
  // from then on (no flicker back to hidden if e.g. touched entities later
  // expire). An open question does NOT gate this anymore — it renders
  // inline in the chat thread itself (see ChatThread's `question` prop
  // below), not in this rail.
  let hasContext = $state(false)
  $effect(() => {
    if (!hasContext && ($sessionActivityLog.length > 0 || $touchedEntities.length > 0)) {
      hasContext = true
    }
  })

  // startSessionWorkspace's cleanup is registered via onDestroy below rather
  // than returned from this callback — onMount ignores a returned function
  // once the callback is async (its return value is a Promise, not the
  // cleanup itself).
  const stopWorkspace = startSessionWorkspace(sessionId)

  onMount(async () => {
    await loadSessionChat(sessionId)
    loading = false
  })

  onDestroy(() => {
    stopSessionPolling(sessionId)
    stopWorkspace()
  })

  // Resizable right rail — sized smaller by default since task windows open
  // narrower than the full page.
  let railSize = $state(24)
</script>

<div class="flex h-full min-h-0">
  {#if loading}
    <div class="flex flex-1 items-center justify-center text-xs text-muted-foreground">Loading…</div>
  {:else if $chatNotFound}
    <div class="flex flex-1 flex-col items-center justify-center gap-1 p-6 text-center">
      <p class="text-sm text-muted-foreground">Task not found.</p>
      <p class="text-xs text-muted-foreground/70">It may have been deleted.</p>
    </div>
  {:else if hasContext}
    <Splitpanes theme="oikos-theme" dblClickSplitter={false}>
      <Pane>
        <ChatThread
          messages={$chatMessages}
          streaming={$chatStreaming}
          connectionState={$chatConnectionState}
          error={$chatError}
          chatErrors={$chatErrors}
          activityLog={sessionActivityLog}
          {sessionId}
          question={$openQuestion}
          onSend={(text) => sendSessionMessage(sessionId, text)}
          onCancel={() => cancelSessionStream(sessionId)}
          onReconnect={() => loadSessionChat(sessionId)}
          onDismissError={dismissError}
        />
      </Pane>
      <Pane bind:size={railSize} minSize={18} maxSize={40}>
        <TaskContextPanel {sessionId} />
      </Pane>
    </Splitpanes>
  {:else}
    <ChatThread
      messages={$chatMessages}
      streaming={$chatStreaming}
      connectionState={$chatConnectionState}
      error={$chatError}
      chatErrors={$chatErrors}
      activityLog={sessionActivityLog}
      {sessionId}
      question={$openQuestion}
      onSend={(text) => sendSessionMessage(sessionId, text)}
      onCancel={() => cancelSessionStream(sessionId)}
      onReconnect={() => loadSessionChat(sessionId)}
      onDismissError={dismissError}
    />
  {/if}
</div>
