<script setup lang="ts">
/**
 * App root.
 *
 * Three mutually-exclusive render states:
 * 1. **Loading** — branded splash while workspace initializes
 * 2. **Welcome** — no workspace configured or saved path is stale
 * 3. **Ready** — workspace loaded, normal layout renders
 *
 * The native File menu is always available once the app is ready,
 * even during the welcome screen. Its actions transition state
 * from welcome → ready via hasWorkspace.
 */
import { invoke } from "@tauri-apps/api/core"
import { Menu, MenuItem, Submenu } from "@tauri-apps/api/menu"
import { watch } from "vue"
import WelcomeScreen from "~/components/WelcomeScreen.vue"
import { useFileSystem } from "~/composables/useFileSystem"
import type { InitResult } from "~/stores/workspace"
import { useWorkspaceStore } from "~/stores/workspace"

const workspace = useWorkspaceStore()
const fs = useFileSystem()

const ready = ref(false)
const hasWorkspace = ref(false)
const stalePath = ref<string | null>(null)

async function handleMenuNewWorkspace() {
  const path = await workspace.pickWorkspace()
  if (!path) return
  await workspace.setWorkspace(path)
  hasWorkspace.value = true
}

async function handleMenuOpenWorkspace() {
  const path = await workspace.pickWorkspace()
  if (!path) return
  await workspace.switchWorkspace(path)
  hasWorkspace.value = true
}

async function handleMenuOpenRecent(path: string) {
  await workspace.switchWorkspace(path)
  hasWorkspace.value = true
}

async function handleCloseWorkspace() {
  await workspace.closeWorkspace()
  stalePath.value = null
  hasWorkspace.value = false
}

async function handleReindex() {
  const toast = useToast()
  const { id } = toast.add({
    title: "Rebuilding index…",
    duration: 0,
    close: false,
    color: "neutral",
  })
  try {
    await workspace.reindex()
    toast.update(id, {
      title: "Index rebuilt",
      color: "success",
      duration: 3000,
      close: true,
    })
  } catch {
    toast.update(id, {
      title: "Indexing failed",
      color: "error",
      duration: 5000,
      close: true,
    })
  }
}

async function handleQuit() {
  await invoke("exit_app")
}

async function buildMenu() {
  const fileItems: (MenuItem | Submenu | { item: "Separator" })[] = [
    await MenuItem.new({
      id: "new-workspace",
      text: "New",
      accelerator: "CmdOrCtrl+Shift+N",
      action: handleMenuNewWorkspace,
    }),
    await MenuItem.new({
      id: "open-workspace",
      text: "Open",
      accelerator: "CmdOrCtrl+O",
      action: handleMenuOpenWorkspace,
    }),
    { item: "Separator" },
  ]

  // Recent workspaces as a submenu
  const recent = workspace.recentWorkspaces
  const validItems: MenuItem[] = []
  for (const p of recent) {
    if (await fs.pathExists(p)) {
      validItems.push(
        await MenuItem.new({
          id: `recent:${p}`,
          text: p.split("/").pop() ?? p,
          action: () => handleMenuOpenRecent(p),
        }),
      )
    }
  }
  if (validItems.length > 0) {
    const recentSubmenu = await Submenu.new({
      text: "Recent",
      items: validItems,
    })
    fileItems.push(recentSubmenu)
  }

  fileItems.push(
    { item: "Separator" },
    await MenuItem.new({
      id: "close-workspace",
      text: "Close",
      accelerator: "CmdOrCtrl+W",
      action: handleCloseWorkspace,
    }),
    { item: "Separator" },
    await MenuItem.new({
      id: "reindex-library",
      text: "Reindex Library",
      accelerator: "CmdOrCtrl+Shift+R",
      action: handleReindex,
    }),
    { item: "Separator" },
    await MenuItem.new({
      id: "quit",
      text: "Quit Enesis",
      accelerator: "CmdOrCtrl+Q",
      action: handleQuit,
    }),
  )

  const fileSubmenu = await Submenu.new({
    text: "File",
    items: fileItems,
  })

  const menu = await Menu.new({ items: [fileSubmenu] })
  await menu.setAsAppMenu()
}

onMounted(async () => {
  const result: InitResult = await workspace.initialize()
  if (result.status === "ok") {
    hasWorkspace.value = true
  } else if (result.status === "stale") {
    stalePath.value = result.path
  }
  await workspace.loadRecentWorkspaces()
  ready.value = true
})

// Build the menu once the app is ready — always visible
watch(
  ready,
  async (r) => {
    if (r) await buildMenu()
  },
  { once: true },
)

// Rebuild menu when recent workspaces change
watch(
  () => workspace.recentWorkspaces,
  async () => {
    if (ready.value) await buildMenu()
  },
  { deep: true },
)
</script>

<template>
  <UApp>
    <!-- 1. Loading — branded splash while workspace initializes -->
    <!-- Uses inline styles, not CSS variables — Nuxt UI theme isn't ready yet -->
    <div
      v-if="!ready"
      class="flex h-screen items-center justify-center select-none"
      style="background-color: #121212"
    >
      <div class="text-center" style="display: flex; flex-direction: column; gap: 1.5rem; align-items: center">
        <svg
          width="64" height="56" viewBox="0 0 160 140"
          aria-hidden="true"
        >
          <polygon points="80,10 140,30 80,50 20,30"   fill="#c25f34" opacity="0.85" />
          <polygon points="20,30 80,50 80,80 20,60"   fill="#c25f34" opacity="0.65" />
          <polygon points="80,50 140,30 140,60 80,80"   fill="#c25f34" opacity="0.55" />
          <polygon points="20,60 80,80 80,110 20,90"   fill="#c25f34" opacity="0.45" />
          <polygon points="80,80 140,60 140,90 80,110"   fill="#c25f34" opacity="0.35" />
          <polygon points="20,90 80,110 80,140 20,120"   fill="#c25f34" opacity="0.25" />
          <polygon points="80,110 140,90 140,120 80,140"   fill="#c25f34" opacity="0.15" />
        </svg>

        <div>
          <p style="margin: 0; font-size: 1.5rem; font-family: serif; color: #e4e4e7; letter-spacing: -0.025em">
            Enesis
          </p>
          <p style="margin: 0.75rem 0 0; font-size: 0.875rem; color: #a1a1aa">
            Your thinking space
          </p>
        </div>
      </div>
    </div>

    <!-- 2. Needs onboarding — no workspace or stale path -->
    <WelcomeScreen
      v-else-if="!hasWorkspace"
      :stale-path="stalePath"
      :recent-paths="workspace.recentWorkspaces"
      @complete="hasWorkspace = true"
    />

    <!-- 3. Ready — normal app chrome -->
    <NuxtLayout v-else>
      <NuxtPage :key="workspace.workspacePath" />
    </NuxtLayout>
  </UApp>
</template>
