import { useEffect, useState } from 'react'
import {
  hydrateLocalSaveFromServer,
  loadSession,
  localCloudSave,
  logoutAccount,
  pushCloudSave,
  type AuthSession,
} from './actionApi'
import type { ActionMechanicConfig } from './actionBoss/actionEncounterConfig'
import { ActionModeScreen } from './components/ActionModeScreen'
import { AuthScreen } from './components/AuthScreen'

export function App() {
  const [session, setSession] = useState<AuthSession | null>(null)
  const [loading, setLoading] = useState(true)
  const [message, setMessage] = useState('')
  const [screenKey, setScreenKey] = useState(0)

  useEffect(() => {
    let cancelled = false
    async function start() {
      try {
        const nextSession = await loadSession()
        if (!nextSession.account) {
          if (!cancelled) setSession(nextSession)
          return
        }
        const syncStatus = await hydrateLocalSaveFromServer()
        if (!cancelled) {
          setSession(nextSession)
          setScreenKey((current) => current + 1)
          setMessage(syncStatus === 'loaded' ? 'Server save loaded.' : '')
        }
      } catch {
        if (!cancelled) setMessage('Server unavailable. Sign in when it comes back online.')
      } finally {
        if (!cancelled) setLoading(false)
      }
    }
    start()
    return () => {
      cancelled = true
    }
  }, [])

  async function handleAuthenticated(nextSession: AuthSession) {
    if (nextSession.account) {
      const syncStatus = await hydrateLocalSaveFromServer()
      setMessage(syncStatus === 'loaded' ? 'Server save loaded.' : 'Local save uploaded.')
      setScreenKey((current) => current + 1)
    }
    setSession(nextSession)
  }

  function handlePlayOffline() {
    setSession({ account: null, offline: true })
    setMessage('')
    setScreenKey((current) => current + 1)
  }

  async function handleLogout() {
    if (!session?.offline) await logoutAccount()
    setSession({ account: null })
    setMessage(session?.offline ? 'Offline mode ended.' : 'Signed out.')
  }

  function syncCharacter() {
    if (!session?.account) return
    pushCloudSave(localCloudSave()).catch(() => null)
  }

  function syncMechanics(mechanics: ActionMechanicConfig) {
    if (!session?.account) return
    pushCloudSave({ ...localCloudSave(), mechanics }).catch(() => null)
  }

  if (loading) {
    return (
      <main className="auth-shell">
        <section className="auth-panel single">
          <div className="auth-card">
            <p className="eyebrow">Loading</p>
            <h1>Connecting</h1>
            <p className="auth-message">Checking server session.</p>
          </div>
        </section>
      </main>
    )
  }

  if (!session?.account && !session?.offline) {
    return (
      <AuthScreen
        onAuthenticated={handleAuthenticated}
        onPlayOffline={handlePlayOffline}
        serverMessage={message}
      />
    )
  }

  return (
    <ActionModeScreen
      key={screenKey}
      account={session.account ?? undefined}
      authActionLabel={session.offline ? 'Sign In' : 'Logout'}
      onCharacterSaved={syncCharacter}
      onLogout={handleLogout}
      onMechanicsSaved={syncMechanics}
    />
  )
}
