import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import { useI18n } from '@/hooks/useI18n'
import React from 'react'
import { nostrAuthService } from '@/lib/nostrAuth'
import { relaySessionManager } from '@/lib/relaySessionManager'
import { publishWorker } from '@/lib/publishWorker'
import { swSyncHandler } from '@/lib/swSyncHandler'
import { swClient } from '@/lib/swClient'

function I18nProvider({ children }: { children: React.ReactNode }): React.ReactElement {
  // Get saved locale from localStorage or default to French
  const getInitialLocale = (): 'fr' | 'en' => {
    if (typeof window === 'undefined') {
      return 'fr'
    }
    try {
      const savedLocale = window.localStorage.getItem('zapwall-locale') as 'fr' | 'en' | null
      if (savedLocale === 'fr' || savedLocale === 'en') {
        return savedLocale
      }
    } catch {
      // Fallback to browser locale detection
    }
    // Try to detect browser locale
    const browserLocale = navigator.language.split('-')[0]
    return browserLocale === 'en' ? 'en' : 'fr'
  }

  const [initialLocale, setInitialLocale] = React.useState<'fr' | 'en'>('fr')
  const [localeLoaded, setLocaleLoaded] = React.useState(false)

  React.useEffect(() => {
    const locale = getInitialLocale()
    setInitialLocale(locale)
    setLocaleLoaded(true)
  }, [])

  const { loaded } = useI18n(initialLocale)

  if (!localeLoaded || !loaded) {
    return <div className="min-h-screen bg-cyber-darker flex items-center justify-center text-neon-cyan">Loading...</div>
  }

  return children as React.ReactElement
}

export default function App({ Component, pageProps }: AppProps): React.ReactElement {
  // Initialize relay session manager on app mount (reset all relays to active)
  React.useEffect(() => {
    void relaySessionManager.initialize()
  }, [])

  // Initialize Service Worker and sync handler
  React.useEffect(() => {
    if (typeof window !== 'undefined') {
      void swSyncHandler.initialize()
    }
  }, [])

  // Start publish worker on app mount to republish unpublished objects
  React.useEffect(() => {
    void publishWorker.start()
    return () => {
      void publishWorker.stop()
    }
  }, [])

  // Start platform sync on app mount via Service Worker only
  React.useEffect(() => {
    const startPlatformSync = async (): Promise<void> => {
      try {
        const isReady = await swClient.isReady()
        if (isReady) {
          await swClient.startPlatformSync()
        }
      } catch (error) {
        console.warn('[App] Service Worker not available for platform sync:', error)
      }
    }

    void startPlatformSync()

    // Trigger sync on each page navigation
    const handleRouteChange = (): void => {
      void startPlatformSync()
    }

    // Listen to route changes
    const router = require('next/router').default
    router.events?.on('routeChangeComplete', handleRouteChange)

    return () => {
      router.events?.off('routeChangeComplete', handleRouteChange)
      void swClient.stopPlatformSync()
    }
  }, [])

  // Start user content sync on app mount via Service Worker only
  React.useEffect(() => {
    const startUserSync = async (): Promise<void> => {
      const state = nostrAuthService.getState()
      if (!state.connected || !state.pubkey) {
        return
      }

      try {
        const isReady = await swClient.isReady()
        if (isReady) {
          await swClient.startUserSync(state.pubkey)
        }
      } catch (error) {
        console.warn('[App] Service Worker not available for user content sync:', error)
      }
    }

    // Try to start sync immediately
    void startUserSync()

    // Also listen to connection changes and route changes to sync when user connects or navigates
    const router = require('next/router').default
    const handleRouteChange = (): void => {
      void startUserSync()
    }

    router.events?.on('routeChangeComplete', handleRouteChange)

    const unsubscribe = nostrAuthService.subscribe((state) => {
      if (state.connected && state.pubkey) {
        void startUserSync()
      }
    })

    return () => {
      router.events?.off('routeChangeComplete', handleRouteChange)
      unsubscribe()
    }
  }, [])

  return (
    <I18nProvider>
      <Component {...pageProps} />
    </I18nProvider>
  )
}

