<script setup lang="ts">
// Waffle app launcher. Strict port of project/platform-app.jsx `AppLauncher`
// (lines 303-377). Right-aligned drop-in (margin 64px 20px 0 0, width 440),
// 3-col grid of centered tiles. The app you're currently inside is rendered
// with a signal-yellow icon container and a "HERE" pill.

import type { IconName } from './UiIcon.vue'

const launcher = useAppLauncher()
const route = useRoute()
const partnerMode = usePartnerMode()
const { isTenantAdmin } = useMe()

interface Tile {
  key: string
  name: string
  icon: IconName
  // Real per-service subdomain behind Traefik (e.g. 'files' for OCIS). Combined
  // with the live base domain at click time to build the app URL. Omitted for
  // internal tiles (Personal / Admin / Partner) which navigate in-app instead.
  host?: string
  current?: boolean
}

// Section context drives which extras (Admin / Partner) appear in the grid,
// and which tile is marked `current` ("HERE" pill).
const section = computed<'partner' | 'admin' | 'user'>(() => {
  if (partnerMode.isActive.value) return 'admin'
  if (route.path.startsWith('/partner')) return 'partner'
  if (route.path.startsWith('/admin')) return 'admin'
  return 'user'
})

const tiles = computed<Tile[]>(() => {
  const isAdmin = section.value === 'admin'
  const isPartner = section.value === 'partner'
  const base: Tile[] = [
    { key: 'mail',     name: 'Mail',      icon: 'mail',     host: 'mail' },
    // Drev = OCIS files, served at files.<domain> (not a vanity 'drev' host).
    { key: 'drev',     name: 'Drev',      icon: 'folder',   host: 'files' },
    { key: 'moder',    name: 'Møder',     icon: 'video',    host: 'meet' },
    { key: 'chat',     name: 'Chat',      icon: 'chat',     host: 'chat' },
    { key: 'cal',      name: 'Kalender',  icon: 'calendar', host: 'cal' },
    { key: 'contacts', name: 'Kontakter', icon: 'users',    host: 'contacts' },
  ]
  // Admin tile is the entry point to the workspace-admin surface. Show it to any
  // tenant admin/owner (so they can get TO /admin from the personal shell), not
  // only when already on the admin section. Marked "HERE" when on /admin. Pair it
  // with a Personal tile so the launcher is a clean two-way toggle between the
  // admin and personal surfaces — clicking either crosses over, "HERE" shows
  // which side you're on.
  if (isAdmin || isTenantAdmin.value) {
    base.push({ key: 'home', name: 'Personal', icon: 'home', current: section.value === 'user' })
    base.push({ key: 'admin', name: 'Admin', icon: 'shield', current: isAdmin && !isPartner })
  }
  if (isPartner) {
    base.push({ key: 'partner', name: 'Partner', icon: 'briefcase', current: true })
  }
  base.push({ key: 'docs', name: 'Docs', icon: 'file', host: 'docs' })
  return base
})

// The base domain the portal itself is served on, so app links resolve in every
// environment: app.dezky.local → dezky.local, app.dezky.com → dezky.com. Falls
// back to the dev domain during SSR (open() only runs client-side on click).
function appBaseDomain(): string {
  if (import.meta.client) {
    const parts = window.location.hostname.split('.')
    return parts.length > 2 ? parts.slice(1).join('.') : window.location.hostname
  }
  return 'dezky.local'
}

const toast = useToast()
function open(t: Tile) {
  launcher.hide()
  if (t.key === 'home') return navigateTo('/')
  if (t.key === 'admin') return navigateTo('/admin')
  if (t.key === 'partner') return navigateTo('/partner')
  if (t.host) {
    const url = `https://${t.host}.${appBaseDomain()}`
    window.open(url, '_blank', 'noopener')
    toast.info(`Opening ${t.name}…`, url.replace(/^https:\/\//, ''))
    return
  }
  toast.info(`Opening ${t.name}…`)
}

onMounted(() => {
  const onKey = (e: KeyboardEvent) => {
    if (e.key === 'Escape' && launcher.open.value) launcher.hide()
  }
  document.addEventListener('keydown', onKey)
  onBeforeUnmount(() => document.removeEventListener('keydown', onKey))
})
</script>

<template>
  <Teleport to="body">
    <Transition name="launcher">
      <div v-if="launcher.open.value" class="scrim" @click="launcher.hide">
        <div class="panel" @click.stop>
          <header>
            <div class="head-meta">
              <Eyebrow>Apps</Eyebrow>
              <div class="head-title">Jump to</div>
            </div>
            <button class="x" @click="launcher.hide" aria-label="Close">
              <UiIcon name="x" :size="16" />
            </button>
          </header>
          <div class="grid">
            <a
              v-for="t in tiles"
              :key="t.key"
              href="#"
              class="tile"
              @click.prevent="open(t)"
            >
              <span class="tile-icon" :class="{ current: t.current }">
                <UiIcon :name="t.icon" :size="20" />
              </span>
              <span class="tile-name">{{ t.name }}</span>
              <span v-if="t.current" class="here">HERE</span>
            </a>
          </div>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<style scoped>
.scrim {
  position: fixed;
  inset: 0;
  background: rgba(10, 10, 10, 0.36);
  z-index: 75;
  display: flex;
  justify-content: flex-end;
}

.panel {
  margin: 64px 20px 0 0;
  width: 440px;
  height: max-content;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.25);
  overflow: hidden;
}

header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.head-meta { display: flex; flex-direction: column; gap: 2px; }
.head-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16px;
  letter-spacing: -0.015em;
  margin-top: 2px;
}

.x {
  background: transparent;
  border: 0;
  padding: 6px;
  border-radius: 4px;
  color: var(--text-mute);
  cursor: pointer;
}
.x:hover { background: var(--surface); color: var(--text); }

.grid {
  padding: 12px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}

.tile {
  position: relative;
  padding: 14px 8px;
  border-radius: 6px;
  text-decoration: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  color: var(--text);
  transition: background 0.12s;
}
.tile:hover { background: var(--row-hover); }

.tile-icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--text);
  color: var(--bg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tile-icon.current {
  background: var(--accent);
  color: var(--accent-fg);
}

.tile-name {
  font-size: 12px;
  font-weight: 500;
  text-align: center;
}

.here {
  position: absolute;
  top: 8px;
  right: 8px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  color: var(--accent-fg);
  background: var(--accent);
  padding: 1px 4px;
  border-radius: 2px;
  letter-spacing: 0.04em;
}

.launcher-enter-active, .launcher-leave-active { transition: opacity 0.14s; }
.launcher-enter-from, .launcher-leave-to { opacity: 0; }
.launcher-enter-active .panel { animation: launcherIn 0.18s ease-out; }

@keyframes launcherIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}
</style>
