import { useState, useEffect } from 'react'
import { generateToken, loadState, saveState } from './api.js'
import { createState } from './gameState.js'
import { BACKGROUNDS } from './constants.js'
import Shell from './components/Shell.jsx'
import Actor from './screens/Actor.jsx'
import Forum from './screens/Forum.jsx'
import Map from './screens/Map.jsx'
import './App.css'

import contextsJson from './config/contexts.json'

const TOKEN_KEY = 'otivm_token'

export default function App() {
  const [state, setState]     = useState(null)
  const [token, setToken]     = useState(null)
  const [loading, setLoading] = useState(true)
  const [context, setContext] = useState('actor')

  useEffect(() => {
    async function bootstrap() {
      let tok = localStorage.getItem(TOKEN_KEY)
      if (!tok) {
        tok = generateToken()
        localStorage.setItem(TOKEN_KEY, tok)
      }
      setToken(tok)
      const saved = await loadState(tok)
      if (saved) {
        setState(saved)
        setContext(saved.background_id && saved.background_id !== 'unknown' ? 'forum' : 'actor')
      } else {
        const fresh = createState(tok)
        setState(fresh)
        await saveState(tok, fresh)
        setContext('actor')
      }
      setLoading(false)
    }
    bootstrap()
  }, [])

  async function onStateChange(newState) {
    setState(newState)
    await saveState(token, newState)
  }

  async function onSelectBackground(backgroundId) {
    const bg = BACKGROUNDS.find(b => b.id === backgroundId)
    if (!bg) return
    const updated = { ...state, background_id: backgroundId, den: bg.starting_den }
    setState(updated)
    await saveState(token, updated)
    setContext('forum')
  }

  async function onNewGame() {
    if (state && token) {
      const abandoned = {
        ...state,
        events: [
          ...(state.events || []),
          { type: 'session_abandoned', route_id: null, timestamp_utc: new Date().toISOString() },
        ],
      }
      await saveState(token, abandoned)
    }
    const newTok = generateToken()
    localStorage.setItem(TOKEN_KEY, newTok)
    setToken(newTok)
    const fresh = createState(newTok)
    setState(fresh)
    await saveState(newTok, fresh)
    setContext('actor')
  }

  if (loading) {
    return <div className="otivm-loading"><span>Consulting the ledger...</span></div>
  }

  const activeCtx = contextsJson.find(c => c.id === context) || contextsJson[0]
  const layout    = activeCtx.layout
  const subitems  = activeCtx.subitems || []

  return (
    <Shell
      contexts={contextsJson}
      activeId={context}
      onContext={setContext}
      subitems={subitems}
      layout={layout}
      token={token}
      onNewGame={onNewGame}
      ctxName={activeCtx.name}
      ctxSubtitle={activeCtx.subtitle}
    >
      {/* ACTOR */}
      {context === 'actor' && (
        <Actor
          state={state}
          onSelectBackground={onSelectBackground}
          layout={layout}
        />
      )}

      {/* FORUM */}
      {context === 'forum' && (
        <Forum
          state={state}
          onStateChange={onStateChange}
          onNewGame={onNewGame}
          layout={layout}
        />
      )}

      {/* MAP */}
      {context === 'map' && (
        <Map state={state} layout={layout} />
      )}
    </Shell>
  )
}
