/**
 * public/launcher.ts — the home "session chooser" shown when no tab is open.
 *
 * Opening the app no longer auto-creates or auto-restores tabs. Instead this
 * start screen lists the host's running sessions as live preview thumbnails
 * (read-only xterm, same as the manage page) so the user picks which to open —
 * or starts a new one. Sessions persist server-side, so opening one replays its
 * full scrollback. The thumbnail card + preview plumbing is shared with the
 * manage page via public/preview-grid.ts (DRY).
 */

import type { LiveSessionInfo } from '../src/types.js'
import {
  el,
  relTime,
  makePreviewCard,
  updatePreviewCard,
  loadPreviewInto,
  fetchLiveSessions,
  type PreviewCard,
} from './preview-grid.js'

export interface LauncherHooks {
  onOpen: (id: string) => void
  onNew: () => void
}

const THUMB_W = 320
const THUMB_MAX_H = 200
const REFRESH_MS = 5000

export interface Launcher {
  setVisible(v: boolean): void
  refresh(): void
}

export function mountLauncher(host: HTMLElement, hooks: LauncherHooks): Launcher {
  const root = el('div', 'launcher')
  root.style.display = 'none'
  host.appendChild(root)

  const head = el('div', 'launcher-head')
  head.append(el('div', 'launcher-title', 'Your sessions'))
  const sub = el('div', 'launcher-sub', '')
  const actions = el('div', 'launcher-actions')
  const newBtn = el('button', 'launcher-new', '＋ New session')
  newBtn.addEventListener('click', () => hooks.onNew())
  const manage = el('a', 'mg-btn', '🗂 Manage') as HTMLAnchorElement
  manage.href = '/manage.html'
  actions.append(newBtn, manage)
  head.append(sub, actions)
  root.append(head)

  const grid = el('div', 'mg-grid')
  root.append(grid)

  const cards = new Map<string, PreviewCard>()
  let timer: ReturnType<typeof setInterval> | null = null

  function makeCard(s: LiveSessionInfo): PreviewCard {
    return makePreviewCard(s, { onOpen: (id) => hooks.onOpen(id) })
  }

  async function refresh(): Promise<void> {
    const sessions = await fetchLiveSessions()

    sub.textContent = sessions.length
      ? `${sessions.length} running on this host — pick one to open`
      : 'No sessions running yet'

    const seen = new Set<string>()
    for (const s of sessions) {
      seen.add(s.id)
      let card = cards.get(s.id)
      if (!card) {
        card = makeCard(s)
        cards.set(s.id, card)
        grid.append(card.el)
      }
      updatePreviewCard(card, s)
      card.meta.textContent = `${s.cwd ?? 'unknown dir'} · ${s.cols}×${s.rows} · ${relTime(s.createdAt)} old`
      void loadPreviewInto(s.id, card, THUMB_W, THUMB_MAX_H)
    }
    for (const [id, card] of cards) {
      if (!seen.has(id)) {
        card.term.dispose()
        card.el.remove()
        cards.delete(id)
      }
    }

    grid.querySelector('.mg-empty')?.remove()
    if (sessions.length === 0) {
      grid.append(el('div', 'mg-empty', 'No running sessions. Click “New session” to start one.'))
    }
  }

  return {
    setVisible(v: boolean): void {
      root.style.display = v ? 'block' : 'none'
      if (v) {
        void refresh()
        if (timer === null) {
          timer = setInterval(() => {
            if (root.style.display !== 'none') void refresh()
          }, REFRESH_MS)
        }
      } else {
        if (timer !== null) {
          clearInterval(timer)
          timer = null
        }
        for (const card of cards.values()) card.term.dispose()
        cards.clear()
        grid.replaceChildren()
      }
    },
    refresh(): void {
      void refresh()
    },
  }
}
