<script lang="ts">
  import { onMount } from 'svelte'
  import { startWorkspace, planSteps, currentTask, touched } from '$lib/stores/workspace'
  import { activityLog } from '$lib/stores/activity'
  import { streaming } from '$lib/stores/chat'
  import OperatorQuestion from './OperatorQuestion.svelte'
  import SessionGraph from './SessionGraph.svelte'
  import ActivityTimeline from './ActivityTimeline.svelte'
  import ChevronDownIcon from '@lucide/svelte/icons/chevron-down'
  import ChevronRightIcon from '@lucide/svelte/icons/chevron-right'
  import MilestoneIcon from '@lucide/svelte/icons/milestone'
  import Spinner from './Spinner.svelte'
  import CircleIcon from '@lucide/svelte/icons/circle'
  import CircleCheckIcon from '@lucide/svelte/icons/circle-check'
  import CircleXIcon from '@lucide/svelte/icons/circle-x'
  import CircleSlashIcon from '@lucide/svelte/icons/circle-slash'
  import CirclePauseIcon from '@lucide/svelte/icons/circle-pause'

  onMount(() => startWorkspace())

  let scopeOpen = $state(true)
  let planOpen = $state(true)
  let activityOpen = $state(true)

  // Resize: distribute height across the 3 content areas.
  // Heights stored in px, minus header sizes. Default even split.
  let heights = $state([300, 200, 200])
  let resizing = $state(-1)
  let resizeStartY = $state(0)
  let resizeStartH = $state<[number, number]>([0, 0])

  function onPointerDown(i: number, e: PointerEvent) {
    e.preventDefault()
    resizing = i
    resizeStartY = e.clientY
    resizeStartH = [heights[i], heights[i + 1]]
    window.addEventListener('pointermove', onPointerMove)
    window.addEventListener('pointerup', onPointerUp)
  }

  function onPointerMove(e: PointerEvent) {
    if (resizing < 0) return
    const dy = e.clientY - resizeStartY
    const minH = 80
    // Clamp each section to minimum
    const newA = Math.max(minH, resizeStartH[0] + dy)
    const newB = Math.max(minH, resizeStartH[1] - dy)
    const newHeights = [...heights]
    newHeights[resizing] = newA
    newHeights[resizing + 1] = newB
    heights = newHeights
  }

  function onPointerUp() {
    resizing = -1
    window.removeEventListener('pointermove', onPointerMove)
    window.removeEventListener('pointerup', onPointerUp)
  }

  // Plan collapsed status
  const planDone = $derived($planSteps.filter((s) => s.status === 'done').length)
  const planTotal = $derived($planSteps.length)
  const planPct = $derived(planTotal > 0 ? Math.round((planDone / planTotal) * 100) : 0)

  // When there are no plan steps, the empty state depends on WHY: a task that's
  // actively planning (or streaming its first turn) is genuinely waiting for one,
  // but a finished task that never planned (a read-only lookup, a direct answer)
  // will never get one — a perpetual "Awaiting plan…" there is misleading.
  const planPhase = $derived.by<'drafting' | 'none' | 'idle'>(() => {
    const st = $currentTask?.status
    if (st === 'done' || st === 'failed' || st === 'abandoned') return 'none'
    if (st === 'planning' || $streaming) return 'drafting'
    return 'idle'
  })

  // Activity collapsed status
  const activityRunning = $derived($activityLog.filter((e) => e.status === 'running').length)
  const activityCount = $derived($activityLog.length)
</script>

<div class="flex h-full min-h-0 flex-col">
  <OperatorQuestion />

  <!-- Scope -->
  <div class="flex shrink-0 flex-col border-b">
    <button
      type="button"
      class="flex items-center gap-1.5 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-wider text-muted-foreground hover:text-foreground"
      onclick={() => (scopeOpen = !scopeOpen)}
    >
      {#if scopeOpen}<ChevronDownIcon class="size-3" />{:else}<ChevronRightIcon class="size-3" />{/if}
      <span>Scope</span>
      {#if !scopeOpen}
        <span class="ml-auto font-normal normal-case">{$touched.length ? `${$touched.length} entit${$touched.length === 1 ? 'y' : 'ies'}` : 'Graph'}</span>
      {/if}
    </button>
    {#if scopeOpen}
      <div style="height: {heights[0]}px">
        <SessionGraph />
      </div>
      <!-- resize handle -->
      <div
        class="h-1.5 cursor-row-resize border-b hover:bg-primary/30 touch-none"
        onpointerdown={(e) => onPointerDown(0, e)}
        role="separator"
        aria-orientation="horizontal"
      ></div>
    {/if}
  </div>

  <!-- Plan -->
  <div class="flex shrink-0 flex-col border-b">
    <button
      type="button"
      class="flex items-center gap-1.5 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-wider text-muted-foreground hover:text-foreground"
      onclick={() => (planOpen = !planOpen)}
    >
      {#if planOpen}<ChevronDownIcon class="size-3" />{:else}<ChevronRightIcon class="size-3" />{/if}
      <span>Plan</span>
      {#if !planOpen}
        {#if planTotal > 0}
          <span class="ml-auto font-normal normal-case">Step {planDone}/{planTotal}</span>
        {:else if $currentTask?.goal}
          <span class="ml-auto max-w-[120px] truncate font-normal normal-case">{$currentTask.goal}</span>
        {:else}
          <span class="ml-auto font-normal normal-case text-muted-foreground">No plan yet</span>
        {/if}
      {/if}
    </button>
    {#if planOpen}
      <div style="height: {heights[1]}px" class="flex flex-col overflow-y-auto">
        {#if $currentTask?.goal}
          <div class="flex items-start gap-2 px-3 py-2">
            <MilestoneIcon class="mt-0.5 size-3 shrink-0 text-primary" />
            <span class="text-xs leading-snug text-foreground/90">{$currentTask.goal}</span>
          </div>
        {/if}
        {#if planTotal > 0}
          <div class="px-3 pb-2.5">
            <div class="mb-1.5 flex items-baseline justify-between text-[11px]">
              <span class="font-medium text-foreground">{planDone} of {planTotal} done</span>
              <span class="tabular-nums text-muted-foreground">{planPct}%</span>
            </div>
            <div class="h-1.5 overflow-hidden rounded-full bg-muted">
              <div class="h-full rounded-full bg-primary transition-all duration-500 ease-out" style="width: {planPct}%"></div>
            </div>
          </div>
          <ol class="flex flex-col overflow-y-auto px-2 pb-2 text-[11px]">
            {#each $planSteps as step, i (step.id)}
              {@const isDone = step.status === 'done'}
              {@const isRunning = step.status === 'running'}
              <li class="relative flex items-start gap-2.5 rounded-md px-2 py-1.5 transition-colors {isRunning ? 'bg-primary/5' : ''}">
                {#if i < $planSteps.length - 1}
                  <span class="pointer-events-none absolute bottom-[-2px] left-[13.5px] top-[22px] w-px bg-border" aria-hidden="true"></span>
                {/if}
                <span class="relative z-10 mt-px flex size-3.5 shrink-0 items-center justify-center rounded-full bg-background">
                  {#if isDone}
                    <CircleCheckIcon class="size-3.5 text-primary" />
                  {:else if isRunning}
                    <Spinner class="size-3.5 text-primary" />
                  {:else if step.status === 'failed'}
                    <CircleXIcon class="size-3.5 text-destructive" />
                  {:else if step.status === 'blocked'}
                    <CirclePauseIcon class="size-3.5 text-warning" />
                  {:else if step.status === 'skipped' || step.status === 'replaced'}
                    <CircleSlashIcon class="size-3.5 text-muted-foreground" />
                  {:else}
                    <CircleIcon class="size-3.5 text-muted-foreground/40" />
                  {/if}
                </span>
                <span
                  class="min-w-0 flex-1 leading-snug {isDone
                    ? 'text-muted-foreground line-through decoration-muted-foreground/40'
                    : isRunning
                      ? 'font-medium text-foreground'
                      : 'text-muted-foreground'}"
                >{step.title}</span>
              </li>
            {/each}
          </ol>
        {:else if planPhase === 'drafting'}
          <div class="flex flex-col items-center gap-3 px-3 py-6 text-center">
            <svg viewBox="0 0 140 88" class="h-16 w-auto text-primary" fill="none">
              <g stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
                <circle cx="16" cy="20" r="4.5" fill="currentColor">
                  <animate attributeName="opacity" values="0.35;1;0.35" dur="1.3s" repeatCount="indefinite" />
                </circle>
                <line x1="30" y1="20" x2="124" y2="20" opacity="0.4">
                  <animate attributeName="opacity" values="0.15;0.5;0.15" dur="1.3s" repeatCount="indefinite" />
                </line>
                <circle cx="16" cy="44" r="4.5" fill="currentColor">
                  <animate attributeName="opacity" values="0.35;1;0.35" dur="1.3s" begin="0.25s" repeatCount="indefinite" />
                </circle>
                <line x1="30" y1="44" x2="102" y2="44" opacity="0.4">
                  <animate attributeName="opacity" values="0.15;0.5;0.15" dur="1.3s" begin="0.25s" repeatCount="indefinite" />
                </line>
                <circle cx="16" cy="68" r="4.5" fill="currentColor">
                  <animate attributeName="opacity" values="0.35;1;0.35" dur="1.3s" begin="0.5s" repeatCount="indefinite" />
                </circle>
                <line x1="30" y1="68" x2="80" y2="68" opacity="0.4">
                  <animate attributeName="opacity" values="0.15;0.5;0.15" dur="1.3s" begin="0.5s" repeatCount="indefinite" />
                </line>
              </g>
            </svg>
            <p class="text-xs text-muted-foreground">Drafting a plan…</p>
          </div>
        {:else}
          <div class="flex flex-col items-center gap-3 px-3 py-6 text-center">
            <svg viewBox="0 0 140 88" class="h-16 w-auto text-muted-foreground/40" fill="none">
              <g stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
                <circle cx="16" cy="20" r="4.5" fill="currentColor" opacity="0.7" />
                <line x1="30" y1="20" x2="124" y2="20" opacity="0.35" />
                <circle cx="16" cy="44" r="4.5" fill="currentColor" opacity="0.45" />
                <line x1="30" y1="44" x2="102" y2="44" opacity="0.25" />
                <circle cx="16" cy="68" r="4.5" fill="none" opacity="0.3" />
                <line x1="30" y1="68" x2="80" y2="68" opacity="0.15" stroke-dasharray="2.5 3.5" />
              </g>
            </svg>
            <p class="max-w-[14rem] text-xs leading-relaxed text-muted-foreground">
              {planPhase === 'none' ? 'Handled directly — no plan needed' : 'No plan for this task yet'}
            </p>
          </div>
        {/if}
      </div>
      <!-- resize handle -->
      <div
        class="h-1.5 cursor-row-resize border-b hover:bg-primary/30 touch-none"
        onpointerdown={(e) => onPointerDown(1, e)}
        role="separator"
        aria-orientation="horizontal"
      ></div>
    {/if}
  </div>

  <!-- Activity -->
  <div class="flex min-h-0 flex-1 flex-col">
    <button
      type="button"
      class="flex shrink-0 items-center gap-1.5 px-3 py-2 text-left text-[11px] font-semibold uppercase tracking-wider text-muted-foreground hover:text-foreground"
      onclick={() => (activityOpen = !activityOpen)}
    >
      {#if activityOpen}<ChevronDownIcon class="size-3" />{:else}<ChevronRightIcon class="size-3" />{/if}
      <span>Event log</span>
      {#if !activityOpen}
        {#if $streaming && activityRunning > 0}
          <Spinner class="size-3 text-primary" />
          <span class="font-normal normal-case text-primary">{activityRunning} running</span>
        {:else}
          <span class="ml-auto font-normal normal-case">{activityCount || '—'} action{activityCount === 1 ? '' : 's'}</span>
        {/if}
      {/if}
    </button>
    {#if activityOpen}
      <div class="min-h-0 flex-1 overflow-hidden">
        <ActivityTimeline />
      </div>
    {/if}
  </div>
</div>
