/*
 *  App.tsx
 *  Zyquo Cloud Web
 *
 *  Author: Simon-Pierre Boucher
 *  Mail: contact@spboucher.ai
 *
 *  The app shell: sidebar + chat area (drawer on phones), root empty state,
 *  first-run notice, settings modal, toasts, and global keyboard shortcuts
 *  (⌘N new chat, ⌘K model menu/palette, ⌘F search, ⌘, settings, ⌘. stop,
 *  ⌘⇧E export).
 */

import { useEffect } from 'react'
import ChatView from './components/ChatView'
import CommandPalette from './components/CommandPalette'
import CompareView from './components/CompareView'
import FirstRun from './components/FirstRun'
import ModelMenu from './components/ModelMenu'
import SettingsModal from './components/SettingsModal'
import Sidebar from './components/Sidebar'
import SuggestionGrid from './components/SuggestionGrid'
import Toasts from './components/Toasts'
import StreamTestView from './features/StreamTestView'
import { exportConversationMarkdown } from './features/exporters'
import { useStore } from './state/store'
import './design/components.css'

export default function App() {
  const loaded = useStore((s) => s.loaded)
  const loadAll = useStore((s) => s.loadAll)
  const conversations = useStore((s) => s.conversations)
  const selectedID = useStore((s) => s.selectedID)
  const settings = useStore((s) => s.settings)
  const settingsOpen = useStore((s) => s.settingsOpen)
  const sidebarOpen = useStore((s) => s.sidebarOpen)
  const setSidebarOpen = useStore((s) => s.setSidebarOpen)
  const modelMenuOpen = useStore((s) => s.modelMenuOpen)
  const setModelMenuOpen = useStore((s) => s.setModelMenuOpen)
  const newConversation = useStore((s) => s.newConversation)
  const openSettings = useStore((s) => s.openSettings)
  const stop = useStore((s) => s.stop)
  const send = useStore((s) => s.send)
  const updateSettings = useStore((s) => s.updateSettings)

  const selected = conversations.find((c) => c.id === selectedID) ?? null

  useEffect(() => {
    void loadAll()
  }, [loadAll])

  // Global shortcuts
  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      const mod = e.metaKey || e.ctrlKey
      if (!mod) return
      const state = useStore.getState()
      switch (e.key) {
        case 'n':
          e.preventDefault()
          state.newConversation()
          break
        case 'k':
          e.preventDefault()
          state.setPaletteOpen(!state.paletteOpen)
          break
        case 'f': {
          e.preventDefault()
          const input = document.querySelector<HTMLInputElement>('[data-search-input]')
          input?.focus()
          break
        }
        case ',':
          e.preventDefault()
          state.openSettings()
          break
        case '.':
          e.preventDefault()
          if (state.selectedID) state.stop(state.selectedID)
          break
        case 'E':
          if (e.shiftKey) {
            e.preventDefault()
            const conversation = state.conversations.find((c) => c.id === state.selectedID)
            if (conversation) exportConversationMarkdown(conversation)
          }
          break
      }
    }
    window.addEventListener('keydown', onKeyDown)
    return () => window.removeEventListener('keydown', onKeyDown)
  }, [newConversation, openSettings, stop])

  if (window.location.hash === '#stream-test') return <StreamTestView />

  if (!loaded) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
        <span style={{ color: 'var(--z-text-tertiary)' }}>Loading…</span>
      </div>
    )
  }

  return (
    <div className={`shell${settings.focusMode ? ' focus-mode' : ''}`}>
      <Sidebar />
      {sidebarOpen && <div className="drawer-scrim" onClick={() => setSidebarOpen(false)} />}
      {selected ? (
        <ChatView conversation={selected} />
      ) : (
        <div className="chat-area">
          <SuggestionGrid
            onPick={(prompt) => {
              const conversation = newConversation()
              // Native behavior: self-contained suggestions send immediately;
              // ones expecting pasted input (trailing blank line) seed the draft.
              if (prompt.endsWith('\n\n')) {
                useStore.getState().setDraftSeed(prompt)
              } else {
                void send(conversation.id, prompt, [])
              }
            }}
          />
          {modelMenuOpen && (
            <ModelMenu
              onPick={(model) => {
                updateSettings({ defaultModelID: model.id, defaultProvider: model.provider })
                newConversation({ model })
              }}
              onClose={() => setModelMenuOpen(false)}
            />
          )}
        </div>
      )}
      {settingsOpen && <SettingsModal />}
      <PaletteHost />
      <CompareHost />
      {!settings.firstRunAcknowledged && <FirstRun />}
      <Toasts />
    </div>
  )
}

function PaletteHost() {
  const paletteOpen = useStore((s) => s.paletteOpen)
  const setPaletteOpen = useStore((s) => s.setPaletteOpen)
  if (!paletteOpen) return null
  return <CommandPalette onClose={() => setPaletteOpen(false)} />
}

function CompareHost() {
  const compareOpen = useStore((s) => s.compareOpen)
  const setCompareOpen = useStore((s) => s.setCompareOpen)
  if (!compareOpen) return null
  return <CompareView onClose={() => setCompareOpen(false)} />
}
