import { useEffect, useState } from 'react'
import { BrowserRouter, Routes, Route, Navigate, Outlet, useNavigate } from 'react-router-dom'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import useAuthStore from './store/authStore'
import useShiftStore from './store/shiftStore'
import useThemeStore from './store/themeStore'
import useTableColourStore from './store/tableColourStore'
import useConnectionStore from './store/connectionStore'
import useWaiterFavoritesStore from './store/waiterFavoritesStore'
import client from './api/client'
import LoginPage from './pages/LoginPage'
import TableListPage from './pages/TableListPage'
import TableDetailPage from './pages/TableDetailPage'
import AddItemsPage from './pages/AddItemsPage'
import OfflinePage from './pages/OfflinePage'
import SettingsPage from './pages/SettingsPage'
import FavoritesSetupPage from './pages/FavoritesSetupPage'
import ChatListPage from './pages/ChatListPage'
import ChatThreadPage from './pages/ChatThreadPage'
import ShiftOverviewPage from './pages/ShiftOverviewPage'
import OrderLogPage from './pages/OrderLogPage'
import { NotificationProvider } from './context/NotificationContext'
import { SSEProvider } from './context/SSEContext'
import ConnectivityBar from './components/ConnectivityBar'
import AppShell from './components/AppShell'
import UpdatePrompt from './components/UpdatePrompt'

// ─── Utility ─────────────────────────────────────────────────────────────────

function Spinner() {
  return (
    <div className="page page--centered" style={{ gap: 12 }}>
      <div style={{
        width: 36, height: 36,
        border: '3px solid var(--border)',
        borderTopColor: 'var(--accent)',
        borderRadius: '50%',
        animation: 'gate-spin 0.7s linear infinite',
      }} />
      <span style={{ color: 'var(--muted)', fontSize: 14 }}>Φόρτωση…</span>
    </div>
  )
}

// ─── Gate Screens ─────────────────────────────────────────────────────────────

function GateCard({ emoji, title, subtitle, children }) {
  return (
    <div className="page page--centered" style={{ gap: 24, padding: 32 }}>
      <div style={{ textAlign: 'center' }}>
        <div style={{ fontSize: 52, marginBottom: 12 }}>{emoji}</div>
        <p style={{ fontSize: 20, fontWeight: 700, color: 'var(--text)', marginBottom: 6 }}>{title}</p>
        {subtitle && <p style={{ fontSize: 14, color: 'var(--muted)', lineHeight: 1.5 }}>{subtitle}</p>}
      </div>
      {children}
    </div>
  )
}

function GateBtn({ onClick, disabled, variant = 'primary', children }) {
  const base = {
    height: 44, padding: '0 24px', borderRadius: 12, border: 'none',
    fontSize: 15, fontWeight: 600, cursor: disabled ? 'not-allowed' : 'pointer',
    opacity: disabled ? 0.6 : 1, transition: 'opacity 120ms',
  }
  const styles = {
    primary:   { background: 'var(--accent)', color: '#0f172a' },
    secondary: { background: 'var(--bg3)', color: 'var(--text)' },
    danger:    { background: 'var(--danger)', color: '#fff' },
  }
  return <button style={{ ...base, ...styles[variant] }} onClick={onClick} disabled={disabled}>{children}</button>
}

function ClosedScreen({ onRefresh, onLogout }) {
  return (
    <GateCard emoji="🔒" title="Εστιατόριο κλειστό"
      subtitle={'Δεν υπάρχει ενεργή ημέρα λειτουργίας.\nΖητήστε από τον διαχειριστή να ανοίξει την ημέρα.'}>
      <div style={{ display: 'flex', gap: 12 }}>
        <GateBtn variant="secondary" onClick={onRefresh}>Ανανέωση</GateBtn>
        <GateBtn variant="danger" onClick={onLogout}>Αποσύνδεση</GateBtn>
      </div>
    </GateCard>
  )
}

function WaitingManagerScreen({ onRefresh, onLogout }) {
  return (
    <GateCard emoji="⏳" title="Αναμονή για έναρξη βάρδιας"
      subtitle="Ζητήστε από τον διαχειριστή να ξεκινήσει τη βάρδια σας.">
      <div style={{ display: 'flex', gap: 12 }}>
        <GateBtn variant="secondary" onClick={onRefresh}>Ανανέωση</GateBtn>
        <GateBtn variant="danger" onClick={onLogout}>Αποσύνδεση</GateBtn>
      </div>
    </GateCard>
  )
}

function StartShiftScreen({ username, onStart, onLogout }) {
  const [startingCash, setStartingCash] = useState('')
  const [starting, setStarting] = useState(false)
  const [error, setError] = useState(null)

  async function handleStart() {
    setStarting(true)
    setError(null)
    try {
      await onStart(startingCash ? parseFloat(startingCash) : null)
    } catch (e) {
      setError(e.response?.data?.detail || 'Σφάλμα εκκίνησης βάρδιας')
      setStarting(false)
    }
  }

  return (
    <GateCard emoji="👋" title={`Καλώς ήρθες, ${username}!`}
      subtitle="Θέλεις να ξεκινήσεις τη βάρδια σου;">
      <div style={{
        width: '100%', maxWidth: 320,
        background: 'var(--bg2)', border: '1px solid var(--border)',
        borderRadius: 16, padding: 20,
        display: 'flex', flexDirection: 'column', gap: 16,
      }}>
        <div>
          <label style={{ fontSize: 13, fontWeight: 600, color: 'var(--muted)', display: 'block', marginBottom: 6 }}>
            Αρχικά μετρητά (προαιρετικό)
          </label>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ color: 'var(--muted)', fontWeight: 700 }}>€</span>
            <input
              type="number" step="0.01" min="0" placeholder="0.00"
              value={startingCash}
              onChange={e => setStartingCash(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && handleStart()}
              style={{
                flex: 1, background: 'var(--bg3)', border: '1px solid var(--border)',
                borderRadius: 10, padding: '10px 12px',
                color: 'var(--text)', fontSize: 16, outline: 'none',
              }}
            />
          </div>
        </div>

        {error && (
          <p style={{
            fontSize: 13, color: 'var(--danger)',
            background: 'var(--danger-dim)', borderRadius: 8, padding: '8px 12px',
          }}>{error}</p>
        )}

        <GateBtn onClick={handleStart} disabled={starting}>
          {starting ? 'Εκκίνηση…' : '▶ Έναρξη Βάρδιας'}
        </GateBtn>
      </div>

      <button
        style={{ fontSize: 13, color: 'var(--muted)', background: 'none', border: 'none', cursor: 'pointer' }}
        onClick={onLogout}
      >
        Αποσύνδεση
      </button>
    </GateCard>
  )
}

// ─── Protected Layout with Shift Gate ────────────────────────────────────────

function AppLayout() {
  const { token, user, logout } = useAuthStore()
  const navigate = useNavigate()
  const {
    shift, businessDay,
    setShift, setBusinessDay,
    setSelfStartAllowed, setSelfEndAllowed,
    gateStatus, setGateStatus,
  } = useShiftStore()

  if (!token) return <Navigate to="/login" replace />

  const isManager = user?.role && user.role !== 'waiter'

  async function checkGate() {
    if (!user) return
    if (isManager) { setGateStatus('ready'); return }

    setGateStatus('loading')
    try {
      const dayRes = await client.get('/api/business-day/current')
      const day = dayRes.data
      setBusinessDay(day)
      if (!day) { setGateStatus('closed'); return }

      const shiftRes = await client.get('/api/shifts/my')
      if (shiftRes.data) {
        setShift(shiftRes.data)
        setGateStatus('ready')
        return
      }

      // No active shift — check self-start setting
      try {
        const settingsRes = await client.get('/api/settings/')
        const canStart = settingsRes.data?.['shifts.waiter_self_start']?.value !== 'false'
        const canEnd   = settingsRes.data?.['shifts.waiter_self_end']?.value   !== 'false'
        setSelfStartAllowed(canStart)
        setSelfEndAllowed(canEnd)
        setGateStatus(canStart ? 'needs_start' : 'waiting_manager')
      } catch {
        setSelfStartAllowed(true)
        setSelfEndAllowed(true)
        setGateStatus('needs_start')
      }
    } catch {
      setBusinessDay(null)
      setGateStatus('closed')
    }
  }

  useEffect(() => {
    if (user) checkGate()
  }, [user?.id])

  // Poll every 15s to detect shift-end or business-day-close triggered by manager
  useEffect(() => {
    if (!user || isManager || gateStatus !== 'ready') return
    const id = setInterval(async () => {
      try {
        const dayRes = await client.get('/api/business-day/current')
        if (!dayRes.data) { setGateStatus('closed'); return }
        const shiftRes = await client.get('/api/shifts/my')
        if (!shiftRes.data) {
          // Shift was ended by manager — rerun full gate check
          checkGate()
        }
      } catch {
        // network error — ignore, don't lock
      }
    }, 15_000)
    return () => clearInterval(id)
  }, [user, isManager, gateStatus])

  async function handleStartShift(startingCash) {
    const res = await client.post('/api/shifts/start', { starting_cash: startingCash })
    setShift(res.data)
    setGateStatus('ready')
  }

  function handleLogout() {
    logout()
    navigate('/login')
  }

  if (!user || gateStatus === 'loading') return <Spinner />

  if (gateStatus === 'closed') return <ClosedScreen onRefresh={checkGate} onLogout={handleLogout} />
  if (gateStatus === 'waiting_manager') return <WaitingManagerScreen onRefresh={checkGate} onLogout={handleLogout} />
  if (gateStatus === 'needs_start') {
    return (
      <StartShiftScreen
        username={user.username}
        onStart={handleStartShift}
        onLogout={handleLogout}
      />
    )
  }

  return <Outlet />
}

// ─── Global helpers ───────────────────────────────────────────────────────────

function AuthRehydrator() {
  const { token, user, login, logout } = useAuthStore()
  useEffect(() => {
    if (token && !user) {
      client.get('/api/auth/me')
        .then(r => login(r.data, token))
        .catch(() => logout())
    }
  }, [])
  return null
}

function OfflineListener() {
  const navigate = useNavigate()
  const { token } = useAuthStore()
  const { status } = useConnectionStore()
  useEffect(() => {
    function handler() {
      // If user is logged in, ConnectivityBar handles it — don't redirect to /offline
      if (token && status !== 'online') return
      // Not logged in and server is down → redirect to offline page
      if (!token) navigate('/offline')
    }
    window.addEventListener('backend-offline', handler)
    return () => window.removeEventListener('backend-offline', handler)
  }, [navigate, token, status])
  return null
}

function ThemeApplier() {
  const dark = useThemeStore(s => s.dark)
  useEffect(() => {
    document.documentElement.setAttribute('data-theme', dark ? 'dark' : 'light')
  }, [dark])
  return null
}

// Prevents the Android back gesture/button from exiting the PWA.
//
// Strategy: whenever the browser lands on /tables (the root screen), immediately
// push a sentinel entry so there is always one history entry behind it. If the
// user backs into the sentinel we push it again — they can never back past /tables.
//
// Only active when running as an installed PWA (standalone display mode).
function AndroidBackGuard() {
  useEffect(() => {
    const isStandalone = window.matchMedia('(display-mode: standalone)').matches
      || window.navigator.standalone === true
    if (!isStandalone) return

    function pushSentinel() {
      history.pushState({ pwaGuard: true }, '')
    }

    // If we're already on the root screen at mount time, push the sentinel now.
    if (window.location.pathname === '/tables' || window.location.pathname === '/') {
      pushSentinel()
    }

    function onPopState(e) {
      if (e.state?.pwaGuard) {
        // User backed into the sentinel — push it again so there's always one more.
        pushSentinel()
        return
      }
      // User backed to /tables (the real root screen) — push the sentinel behind it.
      if (window.location.pathname === '/tables' || window.location.pathname === '/') {
        pushSentinel()
      }
    }

    window.addEventListener('popstate', onPopState)
    return () => window.removeEventListener('popstate', onPopState)
  }, [])
  return null
}

function ColourLoader() {
  const loadFromBackend = useTableColourStore(s => s.loadFromBackend)
  useEffect(() => {
    client.get('/api/settings/')
      .then(r => {
        const raw = r.data?.['ui.table_colours']?.value
        if (raw) loadFromBackend(raw)
      })
      .catch(() => {})
  }, [])
  return null
}

function FavoritesLoader() {
  const { token } = useAuthStore()
  const loadFromServer = useWaiterFavoritesStore(s => s.loadFromServer)
  useEffect(() => {
    if (token) loadFromServer()
  }, [token])
  return null
}

// ─── Login guard — redirect to /tables if already authenticated ───────────────

function LoginGuard({ children }) {
  const { token } = useAuthStore()
  if (token) return <Navigate to="/tables" replace />
  return children
}

// ─── ChatListPage wrapper — owns showNewChat state so pencil can live in AppShell ──

function ChatListRoute() {
  return (
    <AppShell>
      <ChatListPage />
    </AppShell>
  )
}

// ─── TableListPage wrapper ────────────────────────────────────────────────────

function TableListRoute() {
  return (
    <AppShell>
      <TableListPage />
    </AppShell>
  )
}

// ─── App ──────────────────────────────────────────────────────────────────────

const queryClient = new QueryClient()

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
    <BrowserRouter>
      <ThemeApplier />
      <AndroidBackGuard />
      <ColourLoader />
      <FavoritesLoader />
      <AuthRehydrator />
      <OfflineListener />
      <SSEProvider>
        <NotificationProvider>
          <ConnectivityBar />
          <UpdatePrompt />
          <Routes>
            <Route path="/login" element={<LoginGuard><LoginPage /></LoginGuard>} />
            <Route path="/offline" element={<OfflinePage />} />
            <Route element={<AppLayout />}>
              <Route index element={<Navigate to="/tables?tab=tables" replace />} />
              <Route path="/tables" element={<TableListRoute />} />
              <Route path="/tables/:tableId" element={<TableDetailPage />} />
              <Route path="/tables/:tableId/add" element={<AddItemsPage />} />
              <Route path="/standalone/:orderType/add" element={<AddItemsPage />} />
              <Route path="/orders/:orderId" element={<TableDetailPage />} />
              <Route path="/settings" element={<SettingsPage />} />
              <Route path="/settings/favorites" element={<FavoritesSetupPage />} />
              <Route path="/shift-overview" element={<ShiftOverviewPage />} />
              <Route path="/order-log" element={<OrderLogPage />} />
              <Route path="/messages" element={<ChatListRoute />} />
              <Route path="/messages/:conversationId" element={<ChatThreadPage />} />
            </Route>
            <Route path="*" element={<Navigate to="/tables?tab=tables" replace />} />
          </Routes>
        </NotificationProvider>
      </SSEProvider>
    </BrowserRouter>
    </QueryClientProvider>
  )
}
