import { render as renderApp } from 'hono/jsx/dom'
import { Dashboard } from './components'
import { initRouter, navigate } from './router'
import { apps, dashboardTab, getSelectedTab, selectedApp, setApps, setIsNarrow } from './state'
import { initToolIframes, updateToolIframes } from './tool-iframes'
import { initUpdate } from './update'

const render = () => {
  renderApp(<Dashboard render={render} />, document.getElementById('app')!)
  // Update tool iframes after DOM settles
  requestAnimationFrame(() => {
    if (selectedApp) {
      const tools = apps.filter(a => a.tool && a.apps !== false)
      updateToolIframes(getSelectedTab(selectedApp), tools, selectedApp)
    } else {
      const tools = apps.filter(a => a.tool && a.dashboard)
      updateToolIframes(dashboardTab, tools, null)
    }
  })
}

// Initialize render functions
initUpdate(render)
initToolIframes()

// Set theme based on localStorage preference or system preference
export const setTheme = () => {
  const stored = localStorage.getItem('theme')
  if (stored === 'light' || stored === 'dark') {
    document.documentElement.setAttribute('data-theme', stored)
    return
  }
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
  document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light')
}

// Listen for system theme changes (only applies when using system theme)
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
  setTheme()
  render()
})

// Set initial theme
setTheme()

// Listen for narrow screen changes
const narrowQuery = window.matchMedia('(max-width: 768px)')
narrowQuery.addEventListener('change', e => {
  setIsNarrow(e.matches)
  render()
})

// Initialize router (sets initial state from URL and renders)
initRouter(render)

// SSE connection with reconnection handling
let renderQueued = false

const queueRender = () => {
  if (renderQueued) return
  renderQueued = true
  requestAnimationFrame(() => {
    renderQueued = false
    render()
  })
}

function connectSSE() {
  const events = new EventSource('/api/apps/stream')

  events.onmessage = e => {
    setApps(JSON.parse(e.data))

    if (selectedApp && !apps.some(a => a.name === selectedApp)) {
      navigate('/')
    }

    queueRender()
  }

  events.onerror = () => {
    // EventSource auto-reconnects, but close and retry if it enters CLOSED state
    if (events.readyState === EventSource.CLOSED) {
      events.close()
      setTimeout(connectSSE, 2000)
    }
  }
}

connectSSE()
