import { Box, Flex } from '@chakra-ui/react'
import { useEffect, useState } from 'react'
import { navigationItems, type PageId } from '../config/navigation'
import { Outlet, useLocation, useNavigate } from 'react-router-dom'
import { useCompetitions } from '../features/competitions/useCompetitions'
import { fetchCompetitionsWithBets } from '../features/bets/betApi'
import type { AppOutletContext, AuthSession } from '../types/auth'
import { ShellHeader } from './ShellHeader'
import { ShellSidebar } from './ShellSidebar'

type AppShellProps = {
  session: AuthSession
  onLogout: () => void
}

export function AppShell({ session, onLogout }: AppShellProps) {
  const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
  const [avatarMenuOpen, setAvatarMenuOpen] = useState(false)
  const [selectedCompetitionId, setSelectedCompetitionId] = useState<string | null>(null)
  const { competitions, loading: competitionsLoading, refetch: refetchCompetitions } = useCompetitions(session.token)
  const [competitionIdsWithBets, setCompetitionIdsWithBets] = useState<number[]>([])
  const [betsLoaded, setBetsLoaded] = useState(false)

  useEffect(() => {
    fetchCompetitionsWithBets(session.token)
      .then((ids) => { setCompetitionIdsWithBets(ids); setBetsLoaded(true) })
      .catch(() => setBetsLoaded(true))
  }, [session.token])

  // Auto-select a competition after data loads (never overrides a manual selection)
  useEffect(() => {
    if (competitionsLoading || !betsLoaded || selectedCompetitionId !== null) return
    if (competitions.length === 0) return

    const now = new Date()
    const betSet = new Set(competitionIdsWithBets)
    const isActive = (c: { startDate: string; endDate: string }) =>
      now >= new Date(c.startDate) && now <= new Date(c.endDate)

    // 1. Active competition with bets
    const activeWithBets = competitions.find((c) => isActive(c) && betSet.has(c.id))
    if (activeWithBets) { setSelectedCompetitionId(String(activeWithBets.id)); return }

    // 2. Any competition with bets — pick the one whose end date is closest to now
    const withBets = competitions
      .filter((c) => betSet.has(c.id))
      .sort((a, b) => Math.abs(+new Date(a.endDate) - +now) - Math.abs(+new Date(b.endDate) - +now))
    if (withBets.length > 0) { setSelectedCompetitionId(String(withBets[0].id)); return }

    // 3. Active competition (no bets placed yet)
    const active = competitions.find((c) => isActive(c))
    if (active) { setSelectedCompetitionId(String(active.id)); return }

    // 4. Next upcoming competition
    const upcoming = competitions
      .filter((c) => new Date(c.startDate) > now)
      .sort((a, b) => +new Date(a.startDate) - +new Date(b.startDate))
    if (upcoming.length > 0) { setSelectedCompetitionId(String(upcoming[0].id)); return }

    // 5. Fallback: most recent past competition
    const fallback = competitions
      .slice()
      .sort((a, b) => +new Date(b.endDate) - +new Date(a.endDate))
    setSelectedCompetitionId(String(fallback[0].id))
  }, [competitionsLoading, betsLoaded, competitions, competitionIdsWithBets])
  const location = useLocation()
  const navigate = useNavigate()

  const currentPage =
    navigationItems.find((item) =>
      item.path === '/'
        ? location.pathname === '/'
        : location.pathname.startsWith(item.path),
    ) ?? navigationItems[0]

  const activePage: PageId = currentPage.id

  return (
    <Flex minH="100vh" bg="page">
      <ShellSidebar
        activePage={activePage}
        collapsed={sidebarCollapsed}
        isAdmin={session.isAdmin}
        onNavigate={(path) => {
          navigate(path)
          setAvatarMenuOpen(false)
        }}
      />

      <Flex direction="column" flex="1" minW="0">
        <ShellHeader
          currentPage={currentPage}
          session={session}
          sidebarCollapsed={sidebarCollapsed}
          avatarMenuOpen={avatarMenuOpen}
          onSidebarToggle={() => setSidebarCollapsed((value) => !value)}
          onAvatarMenuToggle={() => setAvatarMenuOpen((value) => !value)}
          onLogout={onLogout}
          selectedCompetitionId={selectedCompetitionId}
          onCompetitionChange={setSelectedCompetitionId}
          competitions={competitions}
          competitionsLoading={competitionsLoading}
          competitionIdsWithBets={competitionIdsWithBets}
        />

        <Box
          as="main"
          flex="1"
          px={{ base: '5', md: '8' }}
          py={{ base: '6', md: '8' }}
          maxW="5xl"
          w="full"
          mx="auto"
        >
          <Outlet context={{ session, selectedCompetitionId, refetchCompetitions } satisfies AppOutletContext} />
        </Box>
      </Flex>
    </Flex>
  )
}
