<script lang="ts">
  // The desktop shell: full-viewport surface (background + icons + the
  // centered task launcher + the floating window layer) with the taskbar
  // docked below it as a real flex sibling, not an overlay — so a maximized
  // or dragged window can never end up underneath the taskbar. This replaces
  // the old sidebar + hash-routed page shell in App.svelte entirely; apps are
  // desktop icons now (see $lib/apps.ts), not nav items.
  import { APPS } from '$lib/apps'
  import { iconPositions, resetIconLayout } from '$lib/stores/icons'
  import { wm, openAppWindow, toggleShowDesktop } from '$lib/stores/windows'
  import { summary } from '$lib/stores/context'
  import GraphBackground from '../GraphBackground.svelte'
  import DesktopIcon from './DesktopIcon.svelte'
  import TaskLauncher from './TaskLauncher.svelte'
  import WindowLayer from './WindowLayer.svelte'
  import Taskbar from './Taskbar.svelte'
  import LayersIcon from '@lucide/svelte/icons/layers'
  import Rows3Icon from '@lucide/svelte/icons/rows-3'
  import MonitorIcon from '@lucide/svelte/icons/monitor'
  import RotateCcwIcon from '@lucide/svelte/icons/rotate-ccw'
  import Undo2Icon from '@lucide/svelte/icons/undo-2'
  import Redo2Icon from '@lucide/svelte/icons/redo-2'

  // Clicking the bare desktop (not an icon, not a window) blurs the focused
  // window — the familiar "click empty desktop to deselect" affordance.
  function onSurfaceClick(e: MouseEvent) {
    if (e.currentTarget === e.target) wm.blur()
  }

  // Right-click menu, bare desktop only (same currentTarget===target gate as
  // onSurfaceClick above — icons and windows sit on pointer-events-auto
  // layers above the otherwise pointer-events-none surface, so a right-click
  // that lands on either of them never reaches here). canUndo/canRedo are
  // plain wmkit method calls (not stores), so they're snapshotted once at
  // open time rather than read reactively in the template.
  let menuPos = $state<{ x: number; y: number } | null>(null)
  let menuCanUndo = $state(false)
  let menuCanRedo = $state(false)

  function onSurfaceContextMenu(e: MouseEvent) {
    if (e.currentTarget !== e.target) return
    e.preventDefault()
    menuCanUndo = wm.canUndo()
    menuCanRedo = wm.canRedo()
    menuPos = { x: e.clientX, y: e.clientY }
  }

  function closeMenu() {
    menuPos = null
  }

  function runMenuAction(fn: () => void) {
    fn()
    closeMenu()
  }

  // Cmd/Ctrl+Z / Shift+Z for window-arrangement undo/redo (move, resize,
  // close, ...) — wmkit tracks this history but ships no default keybinding.
  // Skipped entirely while an editable element has focus so it never
  // fights the browser's own text-undo inside the task input or a form
  // field.
  function onWindowKeydown(e: KeyboardEvent) {
    if (e.key === 'Escape' && menuPos) {
      closeMenu()
      return
    }
    const target = e.target as HTMLElement | null
    const editable = !!target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable)
    if (editable) return
    if (!(e.metaKey || e.ctrlKey) || e.key.toLowerCase() !== 'z') return
    e.preventDefault()
    if (e.shiftKey) wm.redo()
    else wm.undo()
  }
</script>

<svelte:window onkeydown={onWindowKeydown} onclick={closeMenu} />

<div class="fixed inset-0 flex flex-col">
  <div
    class="relative min-h-0 flex-1 overflow-hidden"
    role="presentation"
    onclick={onSurfaceClick}
    oncontextmenu={onSurfaceContextMenu}
  >
    <GraphBackground />

    <div class="pointer-events-none absolute inset-0 z-0">
      {#each APPS as app (app.id)}
        {@const pos = $iconPositions[app.id] ?? { col: 0, row: 0 }}
        {@const badge = app.badge?.($summary) ?? 0}
        <DesktopIcon {app} {pos} {badge} onOpen={() => openAppWindow(app.id)} />
      {/each}
    </div>

    <div class="pointer-events-none absolute inset-0 z-10 flex items-center justify-center p-6">
      <div class="pointer-events-auto">
        <TaskLauncher />
      </div>
    </div>

    <WindowLayer />
  </div>

  <Taskbar />
</div>

{#if menuPos}
  <div
    class="fixed z-50 min-w-48 rounded-md border bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10"
    style="left: {menuPos.x}px; top: {menuPos.y}px"
    role="menu"
  >
    <button
      type="button"
      class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent hover:text-accent-foreground"
      onclick={() => runMenuAction(() => wm.arrange('cascade'))}
    >
      <LayersIcon class="size-4" /> Cascade windows
    </button>
    <button
      type="button"
      class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent hover:text-accent-foreground"
      onclick={() => runMenuAction(() => wm.arrange('tile'))}
    >
      <Rows3Icon class="size-4" /> Tile windows
    </button>
    <button
      type="button"
      class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent hover:text-accent-foreground"
      onclick={() => runMenuAction(toggleShowDesktop)}
    >
      <MonitorIcon class="size-4" /> Show desktop
    </button>
    <div class="my-1 h-px bg-border"></div>
    <button
      type="button"
      class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent hover:text-accent-foreground"
      onclick={() => runMenuAction(resetIconLayout)}
    >
      <RotateCcwIcon class="size-4" /> Reset icon layout
    </button>
    <div class="my-1 h-px bg-border"></div>
    <button
      type="button"
      disabled={!menuCanUndo}
      class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50"
      onclick={() => runMenuAction(() => wm.undo())}
    >
      <Undo2Icon class="size-4" /> Undo
    </button>
    <button
      type="button"
      disabled={!menuCanRedo}
      class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50"
      onclick={() => runMenuAction(() => wm.redo())}
    >
      <Redo2Icon class="size-4" /> Redo
    </button>
  </div>
{/if}
