import Sidebar from '@/components/Sidebar'
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import logger from '@/lib/logger'
import { ChevronLeft } from 'lucide-react'
import { NavigationService } from '@/services/navigation.service'
import NoteListPage from '@/pages/primary/NoteListPage'
import SecondaryNoteListPage from '@/pages/secondary/NoteListPage'
// Page imports needed for primary note view
import SettingsPage from '@/pages/secondary/SettingsPage'
import RelaySettingsPage from '@/pages/secondary/RelaySettingsPage'
import WalletPage from '@/pages/secondary/WalletPage'
import PostSettingsPage from '@/pages/secondary/PostSettingsPage'
import GeneralSettingsPage from '@/pages/secondary/GeneralSettingsPage'
import TranslationPage from '@/pages/secondary/TranslationPage'
import RssFeedSettingsPage from '@/pages/secondary/RssFeedSettingsPage'
import NoteDrawer from '@/components/NoteDrawer'
import SecondaryProfilePage from '@/pages/secondary/ProfilePage'
import storage from '@/services/local-storage.service'
import { Sheet, SheetContent } from '@/components/ui/sheet'
import FollowingListPage from '@/pages/secondary/FollowingListPage'
import MuteListPage from '@/pages/secondary/MuteListPage'
import OthersRelaySettingsPage from '@/pages/secondary/OthersRelaySettingsPage'
import SecondaryRelayPage from '@/pages/secondary/RelayPage'
import { CurrentRelaysProvider } from '@/providers/CurrentRelaysProvider'
import { NotificationProvider } from '@/providers/NotificationProvider'
// DEPRECATED: useUserPreferences removed - double-panel functionality disabled
import { TPageRef } from '@/types'
import {
  cloneElement,
  createContext,
  createRef,
  ReactNode,
  RefObject,
  useCallback,
  useContext,
  useEffect,
  useRef,
  useState
} from 'react'
import BottomNavigationBar from './components/BottomNavigationBar'
import TooManyRelaysAlertDialog from './components/TooManyRelaysAlertDialog'
import { normalizeUrl } from './lib/url'
import ExplorePage from './pages/primary/ExplorePage'
import MePage from './pages/primary/MePage'
import NotificationListPage from './pages/primary/NotificationListPage'
import ProfilePage from './pages/primary/ProfilePage'
import RelayPage from './pages/primary/RelayPage'
import SearchPage from './pages/primary/SearchPage'
import DiscussionsPage from './pages/primary/DiscussionsPage'
import { useScreenSize } from './providers/ScreenSizeProvider'
import { routes } from './routes'
import modalManager from './services/modal-manager.service'
import CreateWalletGuideToast from './components/CreateWalletGuideToast'


type TPrimaryPageContext = {
  navigate: (page: TPrimaryPageName, props?: object) => void
  current: TPrimaryPageName | null
  display: boolean
}

type TSecondaryPageContext = {
  push: (url: string) => void
  pop: () => void
  currentIndex: number
  navigateToPrimaryPage: (page: TPrimaryPageName, props?: object) => void
}

type TStackItem = {
  index: number
  url: string
  component: React.ReactElement | null
  ref: RefObject<TPageRef> | null
}

const PRIMARY_PAGE_REF_MAP = {
  home: createRef<TPageRef>(),
  explore: createRef<TPageRef>(),
  notifications: createRef<TPageRef>(),
  me: createRef<TPageRef>(),
  profile: createRef<TPageRef>(),
  relay: createRef<TPageRef>(),
  search: createRef<TPageRef>(),
  discussions: createRef<TPageRef>()
}

// Lazy function to create PRIMARY_PAGE_MAP to avoid circular dependency
// This is only evaluated when called, not at module load time
const getPrimaryPageMap = () => ({
  home: <NoteListPage ref={PRIMARY_PAGE_REF_MAP.home} />,
  explore: <ExplorePage ref={PRIMARY_PAGE_REF_MAP.explore} />,
  notifications: <NotificationListPage ref={PRIMARY_PAGE_REF_MAP.notifications} />,
  me: <MePage ref={PRIMARY_PAGE_REF_MAP.me} />,
  profile: <ProfilePage ref={PRIMARY_PAGE_REF_MAP.profile} />,
  relay: <RelayPage ref={PRIMARY_PAGE_REF_MAP.relay} />,
  search: <SearchPage ref={PRIMARY_PAGE_REF_MAP.search} />,
  discussions: <DiscussionsPage ref={PRIMARY_PAGE_REF_MAP.discussions} />
})

// Type for primary page names - use the return type of getPrimaryPageMap
export type TPrimaryPageName = keyof ReturnType<typeof getPrimaryPageMap>

export const PrimaryPageContext = createContext<TPrimaryPageContext | undefined>(undefined)

const SecondaryPageContext = createContext<TSecondaryPageContext | undefined>(undefined)

const PrimaryNoteViewContext = createContext<{
  setPrimaryNoteView: (view: ReactNode | null, type?: 'note' | 'settings' | 'settings-sub' | 'profile' | 'hashtag' | 'relay' | 'following' | 'mute' | 'others-relay-settings') => void
  primaryViewType: 'note' | 'settings' | 'settings-sub' | 'profile' | 'hashtag' | 'relay' | 'following' | 'mute' | 'others-relay-settings' | null
  getNavigationCounter: () => number
} | undefined>(undefined)

const NoteDrawerContext = createContext<{
  openDrawer: (noteId: string) => void
  closeDrawer: () => void
  isDrawerOpen: boolean
  drawerNoteId: string | null
} | undefined>(undefined)

export function usePrimaryPage() {
  const context = useContext(PrimaryPageContext)
  if (!context) {
    throw new Error('usePrimaryPage must be used within a PrimaryPageContext.Provider')
  }
  return context
}

export function useSecondaryPage() {
  const context = useContext(SecondaryPageContext)
  if (!context) {
    throw new Error('useSecondaryPage must be used within a SecondaryPageContext.Provider')
  }
  return context
}

export function usePrimaryNoteView() {
  const context = useContext(PrimaryNoteViewContext)
  if (!context) {
    throw new Error('usePrimaryNoteView must be used within a PrimaryNoteViewContext.Provider')
  }
  return context
}

export function useNoteDrawer() {
  const context = useContext(NoteDrawerContext)
  if (!context) {
    throw new Error('useNoteDrawer must be used within a NoteDrawerContext.Provider')
  }
  return context
}

// Helper function to build contextual note URL
function buildNoteUrl(noteId: string, currentPage: TPrimaryPageName | null): string {
  // Pages that should preserve context in the URL
  const contextualPages: TPrimaryPageName[] = ['discussions', 'search', 'profile', 'explore', 'notifications']
  
  if (currentPage && contextualPages.includes(currentPage) && currentPage !== 'home') {
    return `/${currentPage}/notes/${noteId}`
  }
  
  return `/notes/${noteId}`
}

// Helper function to build contextual relay URL
function buildRelayUrl(relayUrl: string, currentPage: TPrimaryPageName | null): string {
  const encodedRelayUrl = encodeURIComponent(relayUrl)
  
  // Only preserve context for explore page (where you discover relays)
  if (currentPage === 'explore') {
    return `/explore/relays/${encodedRelayUrl}`
  }
  
  return `/relays/${encodedRelayUrl}`
}

// Helper function to extract noteId and context from URL
function parseNoteUrl(url: string): { noteId: string; context?: string } {
  // Match patterns like /discussions/notes/{noteId} or /notes/{noteId}
  const contextualMatch = url.match(/\/(discussions|search|profile|explore|notifications)\/notes\/(.+)$/)
  if (contextualMatch) {
    return { noteId: contextualMatch[2], context: contextualMatch[1] }
  }
  
  // Match standard pattern /notes/{noteId}
  const standardMatch = url.match(/\/notes\/(.+)$/)
  if (standardMatch) {
    return { noteId: standardMatch[1] }
  }
  
  // Fallback: extract from any /notes/ pattern
  const fallbackMatch = url.replace(/.*\/notes\//, '')
  return { noteId: fallbackMatch || url }
}

// Fixed: Note navigation uses drawer on mobile/single-pane, secondary panel on double-pane desktop
export function useSmartNoteNavigation() {
  const { push: pushSecondaryPage } = useSecondaryPage()
  const { openDrawer, isDrawerOpen } = useNoteDrawer()
  const { isSmallScreen } = useScreenSize()
  const { current: currentPrimaryPage } = usePrimaryPage()
  
  const navigateToNote = (url: string) => {
    // Extract noteId from URL (handles both /notes/{id} and /{context}/notes/{id})
    const { noteId } = parseNoteUrl(url)
    
    // Build contextual URL based on current page
    const contextualUrl = buildNoteUrl(noteId, currentPrimaryPage)
    
    if (isSmallScreen) {
      // Mobile: always push to secondary stack AND update drawer
      // This ensures back button works when clicking embedded events
      pushSecondaryPage(contextualUrl)
      openDrawer(noteId)
    } else {
      // Desktop: check panel mode
      const currentPanelMode = storage.getPanelMode()
      if (currentPanelMode === 'single') {
        // Single-pane: if drawer is already open, push to stack AND update drawer
        // Otherwise, just open drawer
        if (isDrawerOpen) {
          // Navigating from within drawer - push to stack for back button support
          pushSecondaryPage(contextualUrl)
          openDrawer(noteId)
        } else {
          // Opening drawer for first time
          window.history.pushState(null, '', contextualUrl)
          openDrawer(noteId)
        }
      } else {
        // Double-pane: use secondary panel
        pushSecondaryPage(contextualUrl)
      }
    }
  }
  
  return { navigateToNote }
}

// Fixed: Relay navigation now uses primary note view on mobile, secondary routing (drawer in single-pane, side panel in double-pane) on desktop
export function useSmartRelayNavigation() {
  const { setPrimaryNoteView } = usePrimaryNoteView()
  const { push: pushSecondaryPage } = useSecondaryPage()
  const { isSmallScreen } = useScreenSize()
  const { current: currentPrimaryPage } = usePrimaryPage()
  
  const navigateToRelay = (url: string) => {
    // Extract relay URL from path (handles both /relays/{url} and /{context}/relays/{url})
    const relayUrlMatch = url.match(/\/(discussions|search|profile|explore|notifications)\/relays\/(.+)$/) || 
                          url.match(/\/relays\/(.+)$/)
    const relayUrl = relayUrlMatch ? decodeURIComponent(relayUrlMatch[relayUrlMatch.length - 1]) : decodeURIComponent(url.replace(/.*\/relays\//, ''))
    
    // Build contextual URL based on current page
    const contextualUrl = buildRelayUrl(relayUrl, currentPrimaryPage)
    
    if (isSmallScreen) {
      // Use primary note view on mobile
      window.history.pushState(null, '', contextualUrl)
      setPrimaryNoteView(<SecondaryRelayPage url={relayUrl} index={0} hideTitlebar={true} />, 'relay')
    } else {
      // Desktop: always use secondary routing (will be rendered in drawer in single-pane, side panel in double-pane)
      pushSecondaryPage(contextualUrl)
    }
  }
  
  return { navigateToRelay }
}

// Fixed: Profile navigation now uses primary note view on mobile, secondary routing on desktop
export function useSmartProfileNavigation() {
  const { setPrimaryNoteView } = usePrimaryNoteView()
  const { push: pushSecondaryPage } = useSecondaryPage()
  const { isSmallScreen } = useScreenSize()
  const { closeDrawer, isDrawerOpen } = useNoteDrawer()
  
  const navigateToProfile = (url: string) => {
    // Close drawer if open (profiles aren't shown in drawers)
    // Navigate after drawer closes to avoid URL being restored by drawer's onOpenChange
    if (isDrawerOpen) {
      closeDrawer()
      // Wait for drawer to close (350ms animation) before navigating
      setTimeout(() => {
        if (isSmallScreen) {
          // Use primary note view on mobile
          const profileId = url.replace('/users/', '')
          window.history.pushState(null, '', url)
          setPrimaryNoteView(<SecondaryProfilePage id={profileId} index={0} hideTitlebar={true} />, 'profile')
        } else {
          // Use secondary routing on desktop
          pushSecondaryPage(url)
        }
      }, 400) // Slightly longer than drawer close animation (350ms)
    } else {
      // No drawer open, navigate immediately
      if (isSmallScreen) {
        // Use primary note view on mobile
        const profileId = url.replace('/users/', '')
        window.history.pushState(null, '', url)
        setPrimaryNoteView(<SecondaryProfilePage id={profileId} index={0} hideTitlebar={true} />, 'profile')
      } else {
        // Use secondary routing on desktop
        pushSecondaryPage(url)
      }
    }
  }
  
  return { navigateToProfile }
}

// Fixed: Hashtag navigation now uses primary note view since secondary panel is disabled
export function useSmartHashtagNavigation() {
  const { setPrimaryNoteView, getNavigationCounter } = usePrimaryNoteView()
  
  const navigateToHashtag = (url: string) => {
    // Use primary note view to show hashtag feed since secondary panel is disabled
    // Update URL first - do this synchronously before setting the view
    const parsedUrl = url.startsWith('/') ? url : `/${url}`
    window.history.pushState(null, '', parsedUrl)
    
    // Extract hashtag from URL for the key to ensure unique keys for different hashtags
    const searchParams = new URLSearchParams(parsedUrl.includes('?') ? parsedUrl.split('?')[1] : '')
    const hashtag = searchParams.get('t') || ''
    // Get the current navigation counter and use next value for the key
    // This ensures unique keys that force remounting - setPrimaryNoteView will increment it
    const counter = getNavigationCounter()
    const key = `hashtag-${hashtag}-${counter + 1}`
    
    // Use a key based on the hashtag and navigation counter to force remounting when hashtag changes
    // This ensures the component reads the new URL parameters when it mounts
    // setPrimaryNoteView will increment the counter, so we use counter + 1 for the key
    setPrimaryNoteView(<SecondaryNoteListPage key={key} hideTitlebar={true} />, 'hashtag')
    // Dispatch custom event as a fallback for components that might be reused
    window.dispatchEvent(new CustomEvent('hashtag-navigation', { detail: { url: parsedUrl } }))
  }
  
  return { navigateToHashtag }
}

// Fixed: Following list navigation now uses primary note view on mobile, secondary routing on desktop
export function useSmartFollowingListNavigation() {
  const { setPrimaryNoteView } = usePrimaryNoteView()
  const { push: pushSecondaryPage } = useSecondaryPage()
  const { isSmallScreen } = useScreenSize()
  
  const navigateToFollowingList = (url: string) => {
    if (isSmallScreen) {
      // Use primary note view on mobile
      const profileId = url.replace('/users/', '').replace('/following', '')
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<FollowingListPage id={profileId} index={0} hideTitlebar={true} />, 'following')
    } else {
      // Use secondary routing on desktop
      pushSecondaryPage(url)
    }
  }
  
  return { navigateToFollowingList }
}

// Fixed: Mute list navigation now uses primary note view on mobile, secondary routing on desktop
export function useSmartMuteListNavigation() {
  const { setPrimaryNoteView } = usePrimaryNoteView()
  const { push: pushSecondaryPage } = useSecondaryPage()
  const { isSmallScreen } = useScreenSize()
  
  const navigateToMuteList = (url: string) => {
    if (isSmallScreen) {
      // Use primary note view on mobile
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<MuteListPage index={0} hideTitlebar={true} />, 'mute')
    } else {
      // Use secondary routing on desktop
      pushSecondaryPage(url)
    }
  }
  
  return { navigateToMuteList }
}

// Fixed: Others relay settings navigation now uses primary note view on mobile, secondary routing on desktop
export function useSmartOthersRelaySettingsNavigation() {
  const { setPrimaryNoteView } = usePrimaryNoteView()
  const { push: pushSecondaryPage } = useSecondaryPage()
  const { isSmallScreen } = useScreenSize()
  
  const navigateToOthersRelaySettings = (url: string) => {
    if (isSmallScreen) {
      // Use primary note view on mobile
      const profileId = url.replace('/users/', '').replace('/relays', '')
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<OthersRelaySettingsPage id={profileId} index={0} hideTitlebar={true} />, 'others-relay-settings')
    } else {
      // Use secondary routing on desktop
      pushSecondaryPage(url)
    }
  }
  
  return { navigateToOthersRelaySettings }
}

// Fixed: Settings navigation now uses primary note view since secondary panel is disabled
export function useSmartSettingsNavigation() {
  const { setPrimaryNoteView } = usePrimaryNoteView()
  
  const navigateToSettings = (url: string) => {
    // Use primary note view to show settings since secondary panel is disabled
    if (url === '/settings') {
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<SettingsPage key="settings" index={0} hideTitlebar={true} />, 'settings')
    } else if (url.startsWith('/settings/relays')) {
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<RelaySettingsPage key="relay-settings" index={0} hideTitlebar={true} />, 'settings-sub')
    } else if (url === '/settings/wallet') {
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<WalletPage key="wallet" index={0} hideTitlebar={true} />, 'settings-sub')
    } else if (url === '/settings/posts') {
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<PostSettingsPage key="post-settings" index={0} hideTitlebar={true} />, 'settings-sub')
    } else if (url === '/settings/general') {
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<GeneralSettingsPage key="general-settings" index={0} hideTitlebar={true} />, 'settings-sub')
    } else if (url === '/settings/translation') {
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<TranslationPage key="translation" index={0} hideTitlebar={true} />, 'settings-sub')
    } else if (url === '/settings/rss-feeds') {
      window.history.pushState(null, '', url)
      setPrimaryNoteView(<RssFeedSettingsPage key="rss-feed-settings" index={0} hideTitlebar={true} />, 'settings-sub')
    }
  }
  
  return { navigateToSettings }
}

// DEPRECATED: ConditionalHomePage removed - double-panel functionality disabled

// Helper function to get page title based on view type and URL
function getPageTitle(viewType: 'note' | 'settings' | 'settings-sub' | 'profile' | 'hashtag' | 'relay' | 'following' | 'mute' | 'others-relay-settings' | null, pathname: string): string {
  // Create a temporary navigation service instance to use the getPageTitle method
  const tempService = new NavigationService({ setPrimaryNoteView: () => {} })
  return tempService.getPageTitle(viewType, pathname)
}

// DEPRECATED: Double-panel functionality removed - simplified to single column layout
function MainContentArea({ 
  primaryPages, 
  currentPrimaryPage, 
  primaryNoteView,
  primaryViewType,
  goBack
}: {
  primaryPages: { name: TPrimaryPageName; element: ReactNode; props?: any }[]
  currentPrimaryPage: TPrimaryPageName
  primaryNoteView: ReactNode | null
  primaryViewType: 'note' | 'settings' | 'settings-sub' | 'profile' | 'hashtag' | 'relay' | 'following' | 'mute' | 'others-relay-settings' | null
  goBack: () => void
}) {
  const [, forceUpdate] = useState(0)
  
  // Listen for note page title updates
  useEffect(() => {
    const handleTitleUpdate = () => {
      forceUpdate(n => n + 1)
    }
    window.addEventListener('notePageTitleUpdated', handleTitleUpdate)
    return () => {
      window.removeEventListener('notePageTitleUpdated', handleTitleUpdate)
    }
  }, [])
  
  logger.debug('MainContentArea rendering:', { 
    currentPrimaryPage, 
    primaryPages: primaryPages.map(p => p.name), 
    primaryNoteView: !!primaryNoteView
  })
  
  // Always use single column layout since double-panel is disabled
  return (
    <div className="grid grid-cols-1 gap-2 w-full pr-2 py-2">
      <div className="rounded-lg shadow-lg bg-background overflow-hidden">
        {primaryNoteView ? (
          // Show note view with back button
          <div className="flex flex-col h-full w-full">
            <div className="flex justify-center py-1 border-b">
              <span className="text-green-600 dark:text-green-500 font-semibold text-sm">
                Imwald
              </span>
            </div>
            <div className="flex gap-1 p-1 items-center justify-between font-semibold border-b">
              <div className="flex items-center flex-1 w-0">
                <Button
                  className="flex gap-1 items-center w-fit max-w-full justify-start pl-2 pr-3"
                  variant="ghost"
                  size="titlebar-icon"
                  title="Back"
                  onClick={goBack}
                >
                  <ChevronLeft />
                  <div className="truncate text-lg font-semibold">
                    Back
                  </div>
                </Button>
              </div>
              <div className="flex-1 flex justify-center">
                <div className="text-lg font-semibold">
                  {getPageTitle(primaryViewType, window.location.pathname)}
                </div>
              </div>
              <div className="flex-1 w-0"></div>
            </div>
            <div className="flex-1 overflow-auto">
              {primaryNoteView}
            </div>
          </div>
        ) : (
          // Show normal primary pages
          primaryPages.map(({ name, element, props }) => {
            const isCurrentPage = currentPrimaryPage === name
            logger.debug(`Primary page ${name}:`, { isCurrentPage, currentPrimaryPage })
            return (
              <div
                key={name}
                className="flex flex-col h-full w-full"
                style={{
                  display: isCurrentPage ? 'block' : 'none'
                }}
              >
                {(() => {
                  try {
                    logger.debug(`Rendering ${name} component`)
                    return props ? cloneElement(element as React.ReactElement, props) : element
                  } catch (error) {
                    logger.error(`Error rendering ${name} component:`, error)
                    return <div>Error rendering {name}: {error instanceof Error ? error.message : String(error)}</div>
                  }
                })()}
              </div>
            )
          })
        )}
      </div>
      {/* DEPRECATED: Secondary panel removed - double-panel functionality disabled */}
    </div>
  )
}

export function PageManager({ maxStackSize = 5 }: { maxStackSize?: number }) {
  const { isSmallScreen } = useScreenSize()
  // DEPRECATED: showRecommendedRelaysPanel removed - double-panel functionality disabled
  const [currentPrimaryPage, setCurrentPrimaryPage] = useState<TPrimaryPageName>('home')
  const [primaryPages, setPrimaryPages] = useState<
    { name: TPrimaryPageName; element: ReactNode; props?: any }[]
  >([
    {
      name: 'home',
      element: getPrimaryPageMap().home
    }
  ])
  const [secondaryStack, setSecondaryStack] = useState<TStackItem[]>([])
  const [primaryNoteView, setPrimaryNoteViewState] = useState<ReactNode | null>(null)
  const [primaryViewType, setPrimaryViewType] = useState<'note' | 'settings' | 'settings-sub' | 'profile' | 'hashtag' | 'relay' | 'following' | 'mute' | 'others-relay-settings' | null>(null)
  const [savedPrimaryPage, setSavedPrimaryPage] = useState<TPrimaryPageName | null>(null)
  const [drawerOpen, setDrawerOpen] = useState(false)
  const [drawerNoteId, setDrawerNoteId] = useState<string | null>(null)
  const [panelMode, setPanelMode] = useState<'single' | 'double'>(() => storage.getPanelMode())
  const navigationCounterRef = useRef(0)
  const savedFeedStateRef = useRef<Map<TPrimaryPageName, { 
    tab?: string,
    discussionsState?: { selectedTopic: string, timeSpan: '30days' | '90days' | 'all' },
    trendingTab?: 'nostr' | 'relays' | 'hashtags'
  }>>(new Map())
  const currentTabStateRef = useRef<Map<TPrimaryPageName, string>>(new Map()) // Track current tab state for each page
  
  const setPrimaryNoteView = (view: ReactNode | null, type?: 'note' | 'settings' | 'settings-sub' | 'profile' | 'hashtag' | 'relay' | 'following' | 'mute' | 'others-relay-settings') => {
    if (view && !primaryNoteView) {
      // Saving current primary page before showing overlay
      setSavedPrimaryPage(currentPrimaryPage)
      
      // Get current tab state from ref (updated by components via events)
      const currentTab = currentTabStateRef.current.get(currentPrimaryPage)
      
      // Get Discussions state if on discussions page
      let discussionsState: { selectedTopic: string, timeSpan: '30days' | '90days' | 'all' } | undefined = undefined
      if (currentPrimaryPage === 'discussions') {
        // Request discussions state from component
        const stateEvent = new CustomEvent('requestDiscussionsState')
        let receivedState: { selectedTopic: string, timeSpan: '30days' | '90days' | 'all' } | null = null
        const handler = ((e: CustomEvent) => {
          receivedState = e.detail
        }) as EventListener
        window.addEventListener('discussionsStateResponse', handler)
        window.dispatchEvent(stateEvent)
        setTimeout(() => {
          window.removeEventListener('discussionsStateResponse', handler)
          if (receivedState) {
            discussionsState = receivedState
          }
        }, 10)
      }
      
      // Get trending tab if on search page
      const trendingTab = currentTabStateRef.current.get('search') as 'nostr' | 'relays' | 'hashtags' | undefined
      
      // Save state (tab, discussions, trending) if any exists
      if (currentTab || discussionsState || trendingTab) {
        logger.info('PageManager: Saving page state', { 
          page: currentPrimaryPage, 
          tab: currentTab,
          discussionsState,
          trendingTab
        })
        savedFeedStateRef.current.set(currentPrimaryPage, { 
          tab: currentTab,
          discussionsState,
          trendingTab
        })
      }
    }
    
    // Increment navigation counter when setting a new view to ensure unique keys
    // This forces React to remount components even when navigating between items of the same type
    if (view) {
      navigationCounterRef.current += 1
    }
    
    // Always update the view state - even if the type is the same, the component might be different
    // This ensures that navigation works even when navigating between items of the same type (e.g., different hashtags)
    setPrimaryNoteViewState(view)
    setPrimaryViewType(type || null)
    
    // If clearing the view, restore to the saved primary page
    if (!view && savedPrimaryPage) {
      const newUrl = savedPrimaryPage === 'home' ? '/' : `/${savedPrimaryPage}`
      window.history.replaceState(null, '', newUrl)
      
      const savedFeedState = savedFeedStateRef.current.get(savedPrimaryPage)
      
      // Restore tab state first
      if (savedFeedState?.tab) {
        logger.info('PageManager: Restoring tab state', { page: savedPrimaryPage, tab: savedFeedState.tab })
        window.dispatchEvent(new CustomEvent('restorePageTab', { 
          detail: { page: savedPrimaryPage, tab: savedFeedState.tab } 
        }))
        currentTabStateRef.current.set(savedPrimaryPage, savedFeedState.tab)
      }
      
      // Restore Discussions state
      if (savedFeedState?.discussionsState && savedPrimaryPage === 'discussions') {
        logger.info('PageManager: Restoring Discussions state', { 
          page: savedPrimaryPage, 
          discussionsState: savedFeedState.discussionsState 
        })
        window.dispatchEvent(new CustomEvent('restoreDiscussionsState', { 
          detail: { page: savedPrimaryPage, discussionsState: savedFeedState.discussionsState } 
        }))
      }
      
      // Restore trending tab for search page
      if (savedFeedState?.trendingTab && savedPrimaryPage === 'search') {
        logger.info('PageManager: Restoring trending tab', { 
          page: savedPrimaryPage, 
          trendingTab: savedFeedState.trendingTab 
        })
        window.dispatchEvent(new CustomEvent('restorePageTab', { 
          detail: { page: 'search', tab: savedFeedState.trendingTab } 
        }))
        currentTabStateRef.current.set('search', savedFeedState.trendingTab)
      }
    }
  }

  const goBack = () => {
    // Special handling for settings sub-pages - go back to main settings page
    if (primaryViewType === 'settings-sub') {
      window.history.pushState(null, '', '/settings')
      setPrimaryNoteView(<SettingsPage index={0} hideTitlebar={true} />, 'settings')
    } else if (primaryViewType === 'following' || primaryViewType === 'mute' || primaryViewType === 'others-relay-settings') {
      // Special handling for profile sub-pages - go back to main profile page
      const currentPath = window.location.pathname
      const profileId = currentPath.replace('/users/', '').replace('/following', '').replace('/muted', '').replace('/relays', '')
      const profileUrl = `/users/${profileId}`
      window.history.pushState(null, '', profileUrl)
      setPrimaryNoteView(<SecondaryProfilePage id={profileId} index={0} hideTitlebar={true} />, 'profile')
    } else {
      // Use browser's back functionality for other pages
      window.history.back()
    }
  }

  // Drawer handlers
  const openDrawer = useCallback((noteId: string) => {
    setDrawerNoteId(noteId)
    setDrawerOpen(true)
  }, [])

  const closeDrawer = useCallback(() => {
    if (!drawerOpen) return // Already closed
    setDrawerOpen(false)
    // Don't clear noteId here - let onOpenChange handle it when animation completes
  }, [drawerOpen])
  const ignorePopStateRef = useRef(false)

  // Handle browser back button for primary note view
  useEffect(() => {
    const handlePopState = () => {
      if (ignorePopStateRef.current) {
        ignorePopStateRef.current = false
        return
      }
      
      // If we have a primary note view open (and drawer is not open), close it
      if (primaryNoteView && !drawerOpen) {
        setPrimaryNoteView(null)
      }
    }

    window.addEventListener('popstate', handlePopState)
    return () => window.removeEventListener('popstate', handlePopState)
  }, [primaryNoteView, drawerOpen])

  useEffect(() => {
    if (['/npub1', '/nprofile1'].some((prefix) => window.location.pathname.startsWith(prefix))) {
      window.history.replaceState(
        null,
        '',
        '/users' + window.location.pathname + window.location.search + window.location.hash
      )
    } else if (
      ['/note1', '/nevent1', '/naddr1'].some((prefix) =>
        window.location.pathname.startsWith(prefix)
      )
    ) {
      window.history.replaceState(
        null,
        '',
        '/notes' + window.location.pathname + window.location.search + window.location.hash
      )
    }
    window.history.pushState(null, '', window.location.href)
    if (window.location.pathname !== '/') {
      const url = window.location.pathname + window.location.search + window.location.hash
      const pathname = window.location.pathname
      
      // Check if this is a note URL - handle both /notes/{id} and /{context}/notes/{id}
      const contextualNoteMatch = pathname.match(/\/(discussions|search|profile|explore|notifications)\/notes\/(.+)$/)
      const standardNoteMatch = pathname.match(/\/notes\/(.+)$/)
      const noteUrlMatch = contextualNoteMatch || standardNoteMatch
      
      if (noteUrlMatch) {
        const noteId = noteUrlMatch[noteUrlMatch.length - 1].split('?')[0].split('#')[0]
        if (noteId) {
          // If this is a contextual note URL, set the primary page first
          if (contextualNoteMatch) {
            const pageContext = contextualNoteMatch[1] as TPrimaryPageName
            if (pageContext in getPrimaryPageMap()) {
              // Open drawer immediately, then load background page asynchronously
              // This prevents the background page loading from blocking the drawer
              if (isSmallScreen || panelMode === 'single') {
                // Single-pane mode or mobile: open drawer first
                openDrawer(noteId)
                
                // Load background page asynchronously after drawer opens
                setTimeout(() => {
                  setCurrentPrimaryPage(pageContext)
                  setPrimaryPages((prev) => {
                    const exists = prev.find((p) => p.name === pageContext)
                    if (!exists) {
                      return [...prev, { name: pageContext, element: getPrimaryPageMap()[pageContext] }]
                    }
                    return prev
                  })
                  setSavedPrimaryPage(pageContext)
                }, 0)
                return
              } else {
                // Double-pane mode: set page immediately (no drawer)
                setCurrentPrimaryPage(pageContext)
                setPrimaryPages((prev) => {
                  const exists = prev.find((p) => p.name === pageContext)
                    if (!exists) {
                      return [...prev, { name: pageContext, element: getPrimaryPageMap()[pageContext] }]
                    }
                  return prev
                })
                setSavedPrimaryPage(pageContext)
              }
            }
          }
          
              // Build contextual URL based on current page (for both single and double-pane)
          const contextualUrl = buildNoteUrl(noteId, currentPrimaryPage)
          
          // Check pane mode to determine how to open the note
          if (isSmallScreen || panelMode === 'single') {
            // Single-pane mode or mobile: open in drawer
            openDrawer(noteId)
            // Update URL to contextual URL if different
            if (url !== contextualUrl) {
              window.history.replaceState(null, '', contextualUrl)
            }
            return
          } else {
            // Double-pane mode: push to secondary stack with contextual URL
            setSecondaryStack((prevStack) => {
              if (isCurrentPage(prevStack, contextualUrl)) return prevStack

              const { newStack, newItem } = pushNewPageToStack(
                prevStack,
                contextualUrl,
                maxStackSize,
                window.history.state?.index
              )
              if (newItem) {
                window.history.replaceState({ index: newItem.index, url: contextualUrl }, '', contextualUrl)
              }
              return newStack
            })
            return
          }
        }
      }
      
      // Check if this is a primary page URL - don't push primary pages to secondary stack
      const pathnameOnly = pathname.split('?')[0].split('#')[0]
      const isPrimaryPageUrl = pathnameOnly === '/' || pathnameOnly === '/home' || 
                                (pathnameOnly.startsWith('/') && pathnameOnly.slice(1).split('/')[0] in getPrimaryPageMap() && 
                                 !pathnameOnly.match(/^\/(notes|users|relays|settings|profile-editor|mutes|follow-packs)/))
      
      if (isPrimaryPageUrl) {
        // This is a primary page - just navigate to it, don't push to secondary stack
        const pageName = pathnameOnly === '/' || pathnameOnly === '/home' ? 'home' : pathnameOnly.slice(1).split('/')[0] as TPrimaryPageName
        if (pageName in getPrimaryPageMap()) {
          navigatePrimaryPage(pageName)
        }
        return
      }
      
      // For relay URLs and other non-note URLs, push to secondary stack
      // (will be rendered in drawer in single-pane mode, side panel in double-pane mode)
      setSecondaryStack((prevStack) => {
        if (isCurrentPage(prevStack, url)) return prevStack

        const { newStack, newItem } = pushNewPageToStack(
          prevStack,
          url,
          maxStackSize,
          window.history.state?.index
        )
        if (newItem) {
          window.history.replaceState({ index: newItem.index, url }, '', url)
        }
        return newStack
      })
    } else {
      // Check for relay URL in query params (legacy support)
      const searchParams = new URLSearchParams(window.location.search)
      const r = searchParams.get('r')
      
      if (r) {
        const url = normalizeUrl(r)
        if (url) {
          navigatePrimaryPage('relay', { url })
          return
        }
      }
      
      // Parse pathname to determine primary page
      const pathname: string = window.location.pathname
      
      // Handle dedicated paths for primary pages
      if (pathname === '/' || pathname === '/home') {
        navigatePrimaryPage('home')
      } else {
        // Check if pathname matches a primary page name
        // First, check if it's a contextual note URL (e.g., /discussions/notes/...)
        const contextualNoteMatch = pathname.match(/^\/(discussions|search|profile|explore|notifications)\/notes\//)
        if (contextualNoteMatch) {
          // Extract the page context from the URL
          const pageContext = contextualNoteMatch[1] as TPrimaryPageName
          if (pageContext in getPrimaryPageMap()) {
            navigatePrimaryPage(pageContext)
            // The note URL will be handled by the note URL parsing above
          }
          return
        }
        
        // Check if it's a standard primary page path
        const pageName: string = pathname.slice(1).split('/')[0] // Get first segment after slash
        if (pageName && pageName in getPrimaryPageMap()) {
          // For relay page, check if there's a URL prop
          if (pageName === 'relay') {
            // Relay URLs are handled via secondary routing, not primary pages
            // This should be caught earlier in the URL parsing
          } else {
            navigatePrimaryPage(pageName as TPrimaryPageName)
          }
        }
        // If pathname doesn't match a primary page, it might be a secondary route
        // which is handled elsewhere
      }
    }

    const onPopState = (e: PopStateEvent) => {
      if (ignorePopStateRef.current) {
        ignorePopStateRef.current = false
        return
      }

      const closeModal = modalManager.pop()
      if (closeModal) {
        ignorePopStateRef.current = true
        window.history.forward()
        return
      }

      let state = e.state as { index: number; url: string } | null
      
      // Use state.url if available, otherwise fall back to current pathname
      const urlToCheck = state?.url || window.location.pathname
      
      // Check if it's a note URL (we'll update drawer after stack is synced)
      const noteUrlMatch = urlToCheck.match(/\/(discussions|search|profile|explore|notifications)\/notes\/(.+)$/) || 
                          urlToCheck.match(/\/notes\/(.+)$/)
      const noteIdToShow = noteUrlMatch ? noteUrlMatch[noteUrlMatch.length - 1].split('?')[0].split('#')[0] : null
      
      // If not a note URL and drawer is open - close the drawer immediately
      // Only in single-pane mode or mobile
      if (!noteIdToShow && drawerOpen && (isSmallScreen || panelMode === 'single')) {
        setDrawerOpen(false)
        setTimeout(() => {
          setDrawerNoteId(null)
          // Restore URL to current primary page
          const pageUrl = currentPrimaryPage === 'home' ? '/' : `/${currentPrimaryPage}`
          window.history.replaceState(null, '', pageUrl)
        }, 350)
      }

      setSecondaryStack((pre) => {
        const currentItem = pre[pre.length - 1] as TStackItem | undefined
        const currentIndex = currentItem?.index
        if (!state) {
          if (window.location.pathname + window.location.search + window.location.hash !== '/') {
            // Just change the URL
            return pre
          } else {
            // Back to root
            state = { index: -1, url: '/' }
          }
        }

        // Go forward
        if (currentIndex === undefined || state.index > currentIndex) {
          const { newStack } = pushNewPageToStack(pre, state.url, maxStackSize)
          return newStack
        }

        if (state.index === currentIndex) {
          return pre
        }

        // Go back
        const newStack = pre.filter((item) => item.index <= state!.index)
        const topItem = newStack[newStack.length - 1] as TStackItem | undefined
        
        if (!topItem) {
          // Stack is empty - check if this is a primary page URL or a secondary route
          const pathname = state.url.split('?')[0].split('#')[0]
          const isPrimaryPage = pathname === '/' || pathname === '/home' || 
                                (pathname.startsWith('/') && pathname.slice(1).split('/')[0] in getPrimaryPageMap() && 
                                 !pathname.match(/^\/(notes|users|relays|settings|profile-editor|mutes|follow-packs)/))
          
          // If it's a primary page URL, return empty stack (right panel will close)
          if (isPrimaryPage) {
            // On mobile or single-pane: if drawer is open, close it
            if (drawerOpen && (isSmallScreen || panelMode === 'single')) {
              setDrawerOpen(false)
              setTimeout(() => {
                setDrawerNoteId(null)
                // Ensure URL matches the primary page
                const pageUrl = pathname === '/' || pathname === '/home' ? '/' : pathname
                window.history.replaceState(null, '', pageUrl)
              }, 350)
            }
            return []
          }
          
          // Check if navigating to a note URL (supports both /notes/{id} and /{context}/notes/{id})
          const noteUrlMatch = state.url.match(/\/(discussions|search|profile|explore|notifications)\/notes\/(.+)$/) || 
                              state.url.match(/\/notes\/(.+)$/)
          if (noteUrlMatch) {
            const noteId = noteUrlMatch[noteUrlMatch.length - 1].split('?')[0].split('#')[0]
            if (noteId) {
              if (isSmallScreen || panelMode === 'single') {
                // Single-pane mode or mobile: open in drawer
                openDrawer(noteId)
                return pre
              }
              // Double-pane mode: continue with stack creation
            }
          }
          // Create a new stack item if it's a secondary route (e.g., /follow-packs, /mutes)
          const { component, ref } = findAndCreateComponent(state.url, state.index)
          if (component) {
            newStack.push({
              index: state.index,
              url: state.url,
              component,
              ref
            })
          } else {
            // No component found - likely a primary page, return empty stack
            // On mobile or single-pane: if drawer is open, close it
            if (drawerOpen && (isSmallScreen || panelMode === 'single')) {
              closeDrawer()
            }
            return []
          }
        } else if (!topItem.component) {
          // Load the component if it's not cached
          const { component, ref } = findAndCreateComponent(topItem.url, state.index)
          if (component) {
            topItem.component = component
            topItem.ref = ref
          }
        }
        if (newStack.length === 0) {
          // On mobile or single-pane: if drawer is open, close it
          if (drawerOpen && (isSmallScreen || panelMode === 'single')) {
            closeDrawer()
          }
          // DO NOT update URL when closing panel - closing should NEVER affect the main page
        } else if (newStack.length > 0) {
          // Stack still has items - update drawer to show the top item's note (for mobile/single-pane)
          // Only update drawer if drawer is currently open (not in the process of closing)
          if ((isSmallScreen || panelMode === 'single') && drawerOpen && drawerNoteId) {
            // Extract noteId from top item's URL or from state.url
            const topItemUrl = newStack[newStack.length - 1]?.url || state?.url
            if (topItemUrl) {
              const topNoteUrlMatch = topItemUrl.match(/\/(discussions|search|profile|explore|notifications)\/notes\/(.+)$/) || 
                                     topItemUrl.match(/\/notes\/(.+)$/)
              if (topNoteUrlMatch) {
                const topNoteId = topNoteUrlMatch[topNoteUrlMatch.length - 1].split('?')[0].split('#')[0]
                if (topNoteId && topNoteId !== drawerNoteId) {
                  // Use setTimeout to ensure drawer update happens after stack state is committed
                  setTimeout(() => {
                    // Double-check drawer is still open before updating
                    if (drawerOpen) {
                      openDrawer(topNoteId)
                    }
                  }, 0)
                }
              }
            }
          }
        }
        // If newStack.length === 0, we're closing - don't reopen the drawer
        return newStack
      })
    }

    window.addEventListener('popstate', onPopState)

    return () => {
      window.removeEventListener('popstate', onPopState)
    }
  }, [isSmallScreen, openDrawer, closeDrawer, panelMode, drawerOpen])

  // Listen for tab state changes from components
  useEffect(() => {
    const handleTabChange = (e: CustomEvent<{ page: TPrimaryPageName, tab: string }>) => {
      currentTabStateRef.current.set(e.detail.page, e.detail.tab)
      logger.debug('PageManager: Tab state updated', { page: e.detail.page, tab: e.detail.tab })
    }
    
    window.addEventListener('pageTabChanged', handleTabChange as EventListener)
    return () => {
      window.removeEventListener('pageTabChanged', handleTabChange as EventListener)
    }
  }, [])

  // Listen for panel mode changes from toggle
  useEffect(() => {
    const handlePanelModeChange = (e: CustomEvent<{ mode: 'single' | 'double' }>) => {
      setPanelMode(e.detail.mode)
      logger.debug('PageManager: Panel mode changed', { mode: e.detail.mode })
    }
    
    window.addEventListener('panelModeChanged', handlePanelModeChange as EventListener)
    return () => {
      window.removeEventListener('panelModeChanged', handlePanelModeChange as EventListener)
    }
  }, [])
  
  // Restore tab state when returning to primary page from browser back button
  useEffect(() => {
    if (secondaryStack.length === 0 && currentPrimaryPage) {
      const savedFeedState = savedFeedStateRef.current.get(currentPrimaryPage)
      
      // Restore tab state first
      if (savedFeedState?.tab) {
        logger.info('PageManager: Browser back - Restoring tab state', { page: currentPrimaryPage, tab: savedFeedState.tab })
        window.dispatchEvent(new CustomEvent('restorePageTab', { 
          detail: { page: currentPrimaryPage, tab: savedFeedState.tab } 
        }))
        // Update ref immediately
        currentTabStateRef.current.set(currentPrimaryPage, savedFeedState.tab)
      }
      
      // Restore Discussions state
      if (savedFeedState?.discussionsState && currentPrimaryPage === 'discussions') {
        logger.info('PageManager: Browser back - Restoring Discussions state', { 
          page: currentPrimaryPage, 
          discussionsState: savedFeedState.discussionsState 
        })
        window.dispatchEvent(new CustomEvent('restoreDiscussionsState', { 
          detail: { page: currentPrimaryPage, discussionsState: savedFeedState.discussionsState } 
        }))
      }
      
      // Restore trending tab for search page
      if (savedFeedState?.trendingTab && currentPrimaryPage === 'search') {
        logger.info('PageManager: Browser back - Restoring trending tab', { 
          page: currentPrimaryPage, 
          trendingTab: savedFeedState.trendingTab 
        })
        window.dispatchEvent(new CustomEvent('restorePageTab', { 
          detail: { page: 'search', tab: savedFeedState.trendingTab } 
        }))
        currentTabStateRef.current.set('search', savedFeedState.trendingTab)
      }
    }
  }, [secondaryStack.length, currentPrimaryPage])


  const navigatePrimaryPage = (page: TPrimaryPageName, props?: any) => {
    // Clear any primary note view when navigating to a new primary page
    // This ensures menu clicks always take you to the primary page, not stuck on overlays
    setPrimaryNoteView(null)
    
    // Always clear secondary pages when navigating to a primary page via menu
    // This ensures clicking menu items always takes you to that page, not stuck on profile/note pages
    clearSecondaryPages()
    
    // Update primary pages and current page
    setPrimaryPages((prev) => {
      const exists = prev.find((p) => p.name === page)
      if (exists && props) {
        exists.props = props
        return [...prev]
      } else if (!exists) {
        return [...prev, { name: page, element: getPrimaryPageMap()[page], props }]
      }
      return prev
    })
    setCurrentPrimaryPage(page)
    
    // Update URL for primary pages - use dedicated paths
    // Home can be either / or /home, but we'll use / for home
    const newUrl = page === 'home' ? '/' : `/${page}`
    window.history.pushState(null, '', newUrl)
    
    // NEVER scroll to top - feed should maintain scroll position at all times
  }


  const pushSecondaryPage = (url: string, index?: number) => {
    logger.component('PageManager', 'pushSecondaryPage called', { url })
    
    // Save tab state before navigating
    const currentTab = currentTabStateRef.current.get(currentPrimaryPage)
    const trendingTab = currentTabStateRef.current.get('search') as 'nostr' | 'relays' | 'hashtags' | undefined
    
    if (currentPrimaryPage && (currentTab || trendingTab)) {
      logger.info('PageManager: Desktop - Saving page state', { 
        page: currentPrimaryPage, 
        tab: currentTab,
        trendingTab
      })
      savedFeedStateRef.current.set(currentPrimaryPage, { tab: currentTab, trendingTab })
    }
    
    setSecondaryStack((prevStack) => {
      logger.component('PageManager', 'Current secondary stack length', { length: prevStack.length })
      
      // For relay pages, clear the stack and start fresh to avoid confusion
      if (url.startsWith('/relays/')) {
        logger.component('PageManager', 'Clearing stack for relay navigation')
        const { newStack, newItem } = pushNewPageToStack([], url, maxStackSize, 0)
        logger.component('PageManager', 'New stack created', { 
          newStackLength: newStack.length, 
          hasNewItem: !!newItem 
        })
        if (newItem) {
          window.history.pushState({ index: newItem.index, url }, '', url)
        }
        return newStack
      }
      
      if (isCurrentPage(prevStack, url)) {
        logger.component('PageManager', 'Page already exists, not scrolling')
        // NEVER scroll to top - maintain scroll position
        return prevStack
      }

      logger.component('PageManager', 'Creating new page for URL', { url, prevStackLength: prevStack.length })
      const { newStack, newItem } = pushNewPageToStack(prevStack, url, maxStackSize, index)
      logger.component('PageManager', 'New page created', { 
        newStackLength: newStack.length, 
        prevStackLength: prevStack.length,
        hasNewItem: !!newItem,
        newItemUrl: newItem?.url,
        newItemIndex: newItem?.index
      })
      if (newItem) {
        window.history.pushState({ index: newItem.index, url }, '', url)
      } else {
        logger.error('PageManager', 'Failed to create component for URL - component will not be displayed', { url, path: url.split('?')[0].split('#')[0] })
      }
      return newStack
    })
  }

  const popSecondaryPage = () => {
    // In double-pane mode, never open drawer - just pop from stack
    if (panelMode === 'double' && !isSmallScreen) {
      if (secondaryStack.length === 1) {
        // Just close the panel - DO NOT change the main page or URL
        // Closing panel should NEVER affect the main page
        setSecondaryStack([])
        
        const savedFeedState = savedFeedStateRef.current.get(currentPrimaryPage)
        
        // Restore tab state first
        if (savedFeedState?.tab) {
          logger.info('PageManager: Desktop - Restoring tab state', { page: currentPrimaryPage, tab: savedFeedState.tab })
          window.dispatchEvent(new CustomEvent('restorePageTab', { 
            detail: { page: currentPrimaryPage, tab: savedFeedState.tab } 
          }))
          currentTabStateRef.current.set(currentPrimaryPage, savedFeedState.tab)
        }
        
        // Restore Discussions state
        if (savedFeedState?.discussionsState && currentPrimaryPage === 'discussions') {
          logger.info('PageManager: Desktop - Restoring Discussions state', { 
            page: currentPrimaryPage, 
            discussionsState: savedFeedState.discussionsState 
          })
          window.dispatchEvent(new CustomEvent('restoreDiscussionsState', { 
            detail: { page: currentPrimaryPage, discussionsState: savedFeedState.discussionsState } 
          }))
        }
        
        // Restore trending tab for search page
        if (savedFeedState?.trendingTab && currentPrimaryPage === 'search') {
          logger.info('PageManager: Desktop - Restoring trending tab', { 
            page: currentPrimaryPage, 
            trendingTab: savedFeedState.trendingTab 
          })
          window.dispatchEvent(new CustomEvent('restorePageTab', { 
            detail: { page: 'search', tab: savedFeedState.trendingTab } 
          }))
          currentTabStateRef.current.set('search', savedFeedState.trendingTab)
        }
      } else if (secondaryStack.length > 1) {
        // Pop from stack directly instead of using history.go(-1)
        // This ensures the stack is updated immediately
        setSecondaryStack((prevStack) => {
          const newStack = prevStack.slice(0, -1)
          const topItem = newStack[newStack.length - 1]
          if (topItem) {
            // Update URL to match the top item
            window.history.replaceState({ index: topItem.index, url: topItem.url }, '', topItem.url)
          }
          return newStack
        })
      } else {
        // Just go back in history - popstate will handle stack update
        window.history.go(-1)
      }
      return
    }
    
    // Single-pane mode or mobile: check if drawer is open and stack is empty - close drawer instead
    if (drawerOpen && secondaryStack.length === 0) {
      // Close drawer and reveal the background page
      setDrawerOpen(false)
      setTimeout(() => setDrawerNoteId(null), 350)
      return
    }
    
    // On mobile or single-pane: if stack has 1 item and drawer is open, close drawer and clear stack
    if ((isSmallScreen || panelMode === 'single') && secondaryStack.length === 1 && drawerOpen) {
      // Close drawer (this will restore the URL to the correct primary page)
      setDrawerOpen(false)
      setTimeout(() => setDrawerNoteId(null), 350)
      // Clear stack
      setSecondaryStack([])
      
      const savedFeedState = savedFeedStateRef.current.get(currentPrimaryPage)
      
      // Restore tab state first
      if (savedFeedState?.tab) {
        logger.info('PageManager: Mobile/Single-pane - Restoring tab state', { page: currentPrimaryPage, tab: savedFeedState.tab })
        window.dispatchEvent(new CustomEvent('restorePageTab', { 
          detail: { page: currentPrimaryPage, tab: savedFeedState.tab } 
        }))
        currentTabStateRef.current.set(currentPrimaryPage, savedFeedState.tab)
      }
      
      // Restore Discussions state
      if (savedFeedState?.discussionsState && currentPrimaryPage === 'discussions') {
        logger.info('PageManager: Mobile/Single-pane - Restoring Discussions state', { 
          page: currentPrimaryPage, 
          discussionsState: savedFeedState.discussionsState 
        })
        window.dispatchEvent(new CustomEvent('restoreDiscussionsState', { 
          detail: { page: currentPrimaryPage, discussionsState: savedFeedState.discussionsState } 
        }))
      }
      
      // Restore trending tab for search page
      if (savedFeedState?.trendingTab && currentPrimaryPage === 'search') {
        logger.info('PageManager: Mobile/Single-pane - Restoring trending tab', { 
          page: currentPrimaryPage, 
          trendingTab: savedFeedState.trendingTab 
        })
        window.dispatchEvent(new CustomEvent('restorePageTab', { 
          detail: { page: 'search', tab: savedFeedState.trendingTab } 
        }))
        currentTabStateRef.current.set('search', savedFeedState.trendingTab)
      }
      return
    }
    
    if (secondaryStack.length === 1) {
      // Just close the panel - DO NOT change the main page or URL
      // Closing panel should NEVER affect the main page
      setSecondaryStack([])
      
      const savedFeedState = savedFeedStateRef.current.get(currentPrimaryPage)
      
      // Restore tab state first
      if (savedFeedState?.tab) {
        logger.info('PageManager: Desktop - Restoring tab state', { page: currentPrimaryPage, tab: savedFeedState.tab })
        window.dispatchEvent(new CustomEvent('restorePageTab', { 
          detail: { page: currentPrimaryPage, tab: savedFeedState.tab } 
        }))
        currentTabStateRef.current.set(currentPrimaryPage, savedFeedState.tab)
      }
      
      // Restore Discussions state
      if (savedFeedState?.discussionsState && currentPrimaryPage === 'discussions') {
        logger.info('PageManager: Desktop - Restoring Discussions state', { 
          page: currentPrimaryPage, 
          discussionsState: savedFeedState.discussionsState 
        })
        window.dispatchEvent(new CustomEvent('restoreDiscussionsState', { 
          detail: { page: currentPrimaryPage, discussionsState: savedFeedState.discussionsState } 
        }))
      }
      
      // Restore trending tab for search page
      if (savedFeedState?.trendingTab && currentPrimaryPage === 'search') {
        logger.info('PageManager: Desktop - Restoring trending tab', { 
          page: currentPrimaryPage, 
          trendingTab: savedFeedState.trendingTab 
        })
        window.dispatchEvent(new CustomEvent('restorePageTab', { 
          detail: { page: 'search', tab: savedFeedState.trendingTab } 
        }))
        currentTabStateRef.current.set('search', savedFeedState.trendingTab)
      }
    } else {
      window.history.go(-1)
    }
  }

  const clearSecondaryPages = () => {
    if (secondaryStack.length === 0) return
    // Capture the length before clearing
    const stackLength = secondaryStack.length
    // Clear the state immediately for instant navigation
    setSecondaryStack([])
    // Also update browser history to keep it in sync
    window.history.go(-stackLength)
  }

  if (isSmallScreen) {
    return (
      <PrimaryPageContext.Provider
        value={{
          navigate: navigatePrimaryPage,
          current: currentPrimaryPage,
          display: secondaryStack.length === 0
        }}
      >
        <SecondaryPageContext.Provider
          value={{
            push: pushSecondaryPage,
            pop: popSecondaryPage,
            currentIndex: secondaryStack.length
              ? secondaryStack[secondaryStack.length - 1].index
              : 0,
            navigateToPrimaryPage: navigatePrimaryPage
          }}
        >
        <CurrentRelaysProvider>
          <NotificationProvider>
            <PrimaryNoteViewContext.Provider value={{ setPrimaryNoteView, primaryViewType, getNavigationCounter: () => navigationCounterRef.current }}>
            <NoteDrawerContext.Provider value={{ openDrawer, closeDrawer, isDrawerOpen: drawerOpen, drawerNoteId }}>
            {primaryNoteView ? (
              // Show primary note view with back button on mobile
              <div className="flex flex-col h-full w-full">
                <div className="flex justify-center py-1 border-b">
                  <span className="text-green-600 dark:text-green-500 font-semibold text-sm">
                    Imwald
                  </span>
                </div>
                <div className="flex gap-1 p-1 items-center justify-between font-semibold border-b">
                  <div className="flex items-center flex-1 w-0">
                    <Button
                      className="flex gap-1 items-center w-fit max-w-full justify-start pl-2 pr-3"
                      variant="ghost"
                      size="titlebar-icon"
                      title="Back to feed"
                      onClick={() => setPrimaryNoteView(null)}
                    >
                      <ChevronLeft />
                      <div className="truncate text-lg font-semibold">
                        {primaryViewType === 'settings' ? 'Settings' : 
                         primaryViewType === 'settings-sub' ? 'Settings' : 
                         primaryViewType === 'profile' ? 'Back' : 
                         primaryViewType === 'hashtag' ? 'Hashtag' : 
                         primaryViewType === 'note' ? getPageTitle(primaryViewType, window.location.pathname) : 'Note'}
                      </div>
                    </Button>
                  </div>
                </div>
                <div className="flex-1 overflow-auto">
                  {primaryNoteView}
                </div>
              </div>
            ) : (
              <>
                {!!secondaryStack.length &&
                  secondaryStack.map((item, index) => {
                    const isLast = index === secondaryStack.length - 1
                    logger.component('PageManager', 'Rendering secondary stack item', { 
                      index, 
                      isLast, 
                      url: item.url, 
                      hasComponent: !!item.component,
                      display: isLast ? 'block' : 'none'
                    })
                    return (
                      <div
                        key={item.index}
                        style={{
                          display: isLast ? 'block' : 'none'
                        }}
                      >
                        {item.component}
                      </div>
                    )
                  })}
                {primaryPages.map(({ name, element, props }) => (
                  <div
                    key={name}
                    style={{
                      display:
                        secondaryStack.length === 0 && currentPrimaryPage === name ? 'block' : 'none'
                    }}
                  >
                    {props ? cloneElement(element as React.ReactElement, props) : element}
                  </div>
                ))}
              </>
            )}
            {drawerNoteId && (
              <NoteDrawer 
                open={drawerOpen} 
                onOpenChange={(open) => {
                  setDrawerOpen(open)
                  // Only clear noteId when Sheet is fully closed (after animation completes)
                  // Use 350ms to ensure animation is fully done (animation is 300ms)
                  if (!open) {
                    // Restore URL to current primary page
                    const pageUrl = currentPrimaryPage === 'home' ? '/' : `/${currentPrimaryPage}`
                    window.history.replaceState(null, '', pageUrl)
                    setTimeout(() => setDrawerNoteId(null), 350)
                  }
                }} 
                noteId={drawerNoteId} 
              />
            )}
            <BottomNavigationBar />
            <TooManyRelaysAlertDialog />
            <CreateWalletGuideToast />
            </NoteDrawerContext.Provider>
            </PrimaryNoteViewContext.Provider>
          </NotificationProvider>
        </CurrentRelaysProvider>
        </SecondaryPageContext.Provider>
      </PrimaryPageContext.Provider>
    )
  }

  return (
    <PrimaryPageContext.Provider
      value={{
        navigate: navigatePrimaryPage,
        current: currentPrimaryPage,
        display: true
      }}
    >
      <SecondaryPageContext.Provider
        value={{
          push: pushSecondaryPage,
          pop: popSecondaryPage,
          currentIndex: secondaryStack.length ? secondaryStack[secondaryStack.length - 1].index : 0,
          navigateToPrimaryPage: navigatePrimaryPage
        }}
      >
        <CurrentRelaysProvider>
          <NotificationProvider>
            <PrimaryNoteViewContext.Provider value={{ setPrimaryNoteView, primaryViewType, getNavigationCounter: () => navigationCounterRef.current }}>
            <NoteDrawerContext.Provider value={{ openDrawer, closeDrawer, isDrawerOpen: drawerOpen, drawerNoteId }}>
            <div className="flex flex-col items-center bg-surface-background">
              <div
                className="flex h-[var(--vh)] w-full bg-surface-background"
                style={{
                  maxWidth: '1920px'
                }}
              >
                <Sidebar />
                {(() => {
                  if (panelMode === 'double') {
                    // Double-pane mode: show feed on left (flexible, maintains width), secondary stack on right (1042px, same as drawer)
                    return (
                      <div className="flex-1 flex overflow-hidden">
                        {/* Left panel: Feed (flexible, takes remaining space after 1042px) */}
                        <div className="flex-1 min-w-0 overflow-auto border-r">
                          <MainContentArea 
                            primaryPages={primaryPages}
                            currentPrimaryPage={currentPrimaryPage}
                            primaryNoteView={primaryNoteView}
                            primaryViewType={primaryViewType}
                            goBack={goBack}
                          />
                        </div>
                        {/* Right panel: Secondary stack (1042px fixed width, same as drawer) */}
                        <div className="w-[1042px] shrink-0 overflow-auto">
                          {secondaryStack.length > 0 ? (
                            secondaryStack.map((item, index) => {
                              const isLast = index === secondaryStack.length - 1
                              return (
                                <div
                                  key={item.index}
                                  style={{
                                    display: isLast ? 'block' : 'none'
                                  }}
                                >
                                  {item.component}
                                </div>
                              )
                            })
                          ) : (
                            <div className="h-full flex items-center justify-center text-muted-foreground">
                              {/* Empty state - no secondary content */}
                            </div>
                          )}
                        </div>
                      </div>
                    )
                  } else {
                    // Single-pane mode: show feed only, drawer overlay for notes
                    return (
                      <MainContentArea 
                        primaryPages={primaryPages}
                        currentPrimaryPage={currentPrimaryPage}
                        primaryNoteView={primaryNoteView}
                        primaryViewType={primaryViewType}
                        goBack={goBack}
                      />
                    )
                  }
                })()}
              </div>
            </div>
            {drawerNoteId && (
              <NoteDrawer 
                open={drawerOpen} 
                onOpenChange={(open) => {
                  setDrawerOpen(open)
                  // Only clear noteId when Sheet is fully closed (after animation completes)
                  // Use 350ms to ensure animation is fully done (animation is 300ms)
                  if (!open) {
                    // Restore URL to current primary page
                    const pageUrl = currentPrimaryPage === 'home' ? '/' : `/${currentPrimaryPage}`
                    window.history.replaceState(null, '', pageUrl)
                    setTimeout(() => setDrawerNoteId(null), 350)
                  }
                }} 
                noteId={drawerNoteId} 
              />
            )}
            {/* Generic drawer for secondary stack in single-pane mode (for relay pages, etc.) */}
            {panelMode === 'single' && !isSmallScreen && secondaryStack.length > 0 && !drawerOpen && (
              <Sheet 
                open={true} 
                onOpenChange={(open) => {
                  if (!open) {
                    // Close drawer and go back
                    popSecondaryPage()
                  }
                }}
              >
                <SheetContent side="right" className="w-full sm:max-w-[1042px] overflow-y-auto p-0">
                  <div className="h-full">
                    {secondaryStack.map((item, index) => {
                      const isLast = index === secondaryStack.length - 1
                      if (!isLast) return null
                      return (
                        <div key={item.index}>
                          {item.component}
                        </div>
                      )
                    })}
                  </div>
                </SheetContent>
              </Sheet>
            )}
            <TooManyRelaysAlertDialog />
            <CreateWalletGuideToast />
            </NoteDrawerContext.Provider>
            </PrimaryNoteViewContext.Provider>
          </NotificationProvider>
        </CurrentRelaysProvider>
      </SecondaryPageContext.Provider>
    </PrimaryPageContext.Provider>
  )
}

export function SecondaryPageLink({
  to,
  children,
  className,
  onClick
}: {
  to: string
  children: React.ReactNode
  className?: string
  onClick?: (e: React.MouseEvent) => void
}) {
  const { push } = useSecondaryPage()

  return (
    <span
      className={cn('cursor-pointer', className)}
      onClick={(e) => {
        if (onClick) {
          onClick(e)
        }
        push(to)
      }}
    >
      {children}
    </span>
  )
}

function isCurrentPage(stack: TStackItem[], url: string) {
  const currentPage = stack[stack.length - 1]
  if (!currentPage) return false

  logger.component('PageManager', 'isCurrentPage check', { currentUrl: currentPage.url, newUrl: url, match: currentPage.url === url })
  return currentPage.url === url
}

function findAndCreateComponent(url: string, index: number) {
  const path = url.split('?')[0].split('#')[0]
  logger.component('PageManager', 'findAndCreateComponent called', { url, path, routes: routes.length })
  
  for (const { matcher, element } of routes) {
    const match = matcher(path)
    logger.component('PageManager', 'Trying route matcher', { path, matchResult: !!match, matchParams: match ? (match as any).params : null })
    if (!match) continue

    if (!element) {
      logger.component('PageManager', 'No element for this route', { path })
      return {}
    }
    const ref = createRef<TPageRef>()
    
    // Decode URL parameters for relay pages
    const params = { ...(match as any).params }
    if (params.url && typeof params.url === 'string') {
      params.url = decodeURIComponent(params.url)
      logger.component('PageManager', 'Decoded URL parameter', { url: params.url })
    }
    
    logger.component('PageManager', 'Creating component with params', { params, index })
    try {
      const component = cloneElement(element, { ...params, index, ref } as any)
      logger.component('PageManager', 'Component created successfully', { hasComponent: !!component })
      return { component, ref }
    } catch (error) {
      logger.error('PageManager', 'Error creating component', { error, params })
      return {}
    }
  }
  logger.component('PageManager', 'No matching route found', { path, url })
  return {}
}

function pushNewPageToStack(
  stack: TStackItem[],
  url: string,
  maxStackSize = 5,
  specificIndex?: number
) {
  const currentItem = stack[stack.length - 1]
  const currentIndex = specificIndex ?? (currentItem ? currentItem.index + 1 : 0)

  const { component, ref } = findAndCreateComponent(url, currentIndex)
  if (!component) {
    logger.error('PageManager', 'pushNewPageToStack: No component created', { url, currentIndex, path: url.split('?')[0].split('#')[0] })
    return { newStack: stack, newItem: null }
  }

  const newItem = { component, ref, url, index: currentIndex }
  const newStack = [...stack, newItem]
  const lastCachedIndex = newStack.findIndex((stack) => stack.component)
  // Clear the oldest cached component if there are too many cached components
  if (newStack.length - lastCachedIndex > maxStackSize) {
    newStack[lastCachedIndex].component = null
  }
  logger.component('PageManager', 'pushNewPageToStack: Success', { url, newStackLength: newStack.length, newItemIndex: currentIndex })
  return { newStack, newItem }
}
