<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, taskWorking, taskFor } 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
  // eslint-disable-next-line svelte/valid-compile
  const chatWorking = taskWorking(sessionId)
  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 mounts.
  // eslint-disable-next-line svelte/valid-compile
  const workspace = workspaceFor(sessionId)
  const planSteps = workspace.planSteps
  // eslint-disable-next-line svelte/valid-compile
  const chatTask = taskFor(sessionId)
  const openQuestion = workspace.openQuestion
  let loading = $state(true)

  // F7 (plan 2026-08-03): the rail used to mount on demand (hasContext gate),
  // which DESTROYED and remounted the ChatThread — losing the input draft and
  // scroll position — and reflowed the chat column the moment the first
  // activity/touched entity landed ("layout looks off when a chat goes from
  // empty to content"). The layout is now stable from the moment the window
  // opens: one Splitpanes, one ChatThread, the rail always present showing
  // its own empty state ("Waiting for activity…") until there's something to
  // show. A stable-but-initially-quiet rail is a better trade than a jumping
  // layout.

  // 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(32)
</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}
    <Splitpanes theme="oikos-theme" dblClickSplitter={false}>
      <Pane>
        <ChatThread
          messages={$chatMessages}
          streaming={$chatStreaming}
          working={$chatWorking}
          connectionState={$chatConnectionState}
          error={$chatError}
          chatErrors={$chatErrors}
          activityLog={sessionActivityLog}
          {sessionId}
          question={$openQuestion}
          planSteps={$planSteps}
          taskStatus={$chatTask?.status}
          lastActiveAt={$chatTask?.last_active_at}
          onSend={(text) => sendSessionMessage(sessionId, text)}
          onCancel={() => cancelSessionStream(sessionId)}
          onReconnect={() => loadSessionChat(sessionId)}
          onDismissError={dismissError}
        />
      </Pane>
      <Pane bind:size={railSize} minSize={24} maxSize={60}>
        <TaskContextPanel {sessionId} />
      </Pane>
    </Splitpanes>
  {/if}
</div>
