/**
 * TabataFit Root Layout
 * Expo Router v3 — SF Pro system font (no custom font loading)
 * Waits for store hydration before rendering
 */

import '@/src/shared/i18n'
import '@/src/shared/i18n/types'

import { useState, useEffect, useCallback, Component } from 'react'
import { Stack } from 'expo-router'
import { StatusBar } from 'expo-status-bar'
import { View, Text, Pressable, StyleSheet } from 'react-native'
import * as SplashScreen from 'expo-splash-screen'
import * as Notifications from 'expo-notifications'

import { PostHogProvider } from 'posthog-react-native'

import { ThemeProvider, useThemeColors } from '@/src/shared/theme'
import { TEXT, NAVY, GREEN } from '@/src/shared/constants/colors'
import { useUserStore } from '@/src/shared/stores'
import { useNotifications } from '@/src/shared/hooks'
import { OfflineBanner } from '@/src/shared/components/OfflineBanner'
import { initializePurchases } from '@/src/shared/services/purchases'
import { initializeAnalytics, getPostHogClient, trackScreen } from '@/src/shared/services/analytics'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: false,
    shouldPlaySound: false,
    shouldSetBadge: false,
    shouldShowBanner: false,
    shouldShowList: false,
  }),
})

SplashScreen.preventAutoHideAsync()

// ─── Error Boundary (F-108) ────────────────────────────────────────────────
interface ErrorBoundaryState {
  hasError: boolean
  error: Error | null
}

class ErrorBoundary extends Component<{ children: React.ReactNode }, ErrorBoundaryState> {
  state: ErrorBoundaryState = { hasError: false, error: null }

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    return { hasError: true, error }
  }

  componentDidCatch(error: Error, info: React.ErrorInfo) {
    console.error('ErrorBoundary caught:', error, info.componentStack)
  }

  private handleRetry = () => {
    this.setState({ hasError: false, error: null })
  }

  render() {
    if (this.state.hasError) {
      return (
        <View style={errorStyles.container}>
          <Text style={errorStyles.emoji}>⚠️</Text>
          <Text style={errorStyles.title}>Something went wrong</Text>
          <Text style={errorStyles.message}>
            {this.state.error?.message ?? 'An unexpected error occurred.'}
          </Text>
          <Pressable style={errorStyles.button} onPress={this.handleRetry}>
            <Text style={errorStyles.buttonText}>Try again</Text>
          </Pressable>
        </View>
      )
    }
    return this.props.children
  }
}

const errorStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: NAVY[900],
    alignItems: 'center',
    justifyContent: 'center',
    padding: 32,
  },
  emoji: { fontSize: 48, marginBottom: 16 },
  title: {
    fontSize: 22,
    fontWeight: '700',
    color: TEXT.PRIMARY,
    marginBottom: 8,
  },
  message: {
    fontSize: 15,
    fontWeight: '400',
    color: TEXT.SECONDARY,
    textAlign: 'center',
    marginBottom: 24,
    lineHeight: 20,
  },
  button: {
    backgroundColor: '#00C896',
    paddingHorizontal: 32,
    paddingVertical: 14,
    borderRadius: 12,
    borderCurve: 'continuous',
    minHeight: 44,
  },
  buttonText: {
    fontSize: 17,
    fontWeight: '600',
    color: NAVY[900],
  },
})

// Create React Query Client
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 1000 * 60 * 5, // 5 minutes
      gcTime: 1000 * 60 * 60 * 24, // 24 hours
      retry: 2,
      refetchOnWindowFocus: false,
    },
  },
})

function RootLayoutInner() {
  const colors = useThemeColors()

  useNotifications()

  // Wait for persisted store to hydrate from AsyncStorage
  const [hydrated, setHydrated] = useState(useUserStore.persist.hasHydrated())

  useEffect(() => {
    const unsub = useUserStore.persist.onFinishHydration(() => setHydrated(true))
    return unsub
  }, [])

  // Initialize RevenueCat + PostHog after hydration
  useEffect(() => {
    if (hydrated) {
      initializePurchases().catch((err) => {
        console.error('Failed to initialize RevenueCat:', err)
      })
      initializeAnalytics().catch((err) => {
        console.error('Failed to initialize PostHog:', err)
      })
    }
  }, [hydrated])

  const onLayoutRootView = useCallback(async () => {
    if (hydrated) {
      await SplashScreen.hideAsync()
    }
  }, [hydrated])

  if (!hydrated) {
    return null
  }

  const content = (
    <QueryClientProvider client={queryClient}>
      <View style={{ flex: 1, backgroundColor: colors.bg.base }} onLayout={onLayoutRootView}>
        <StatusBar style={colors.statusBarStyle} />
        <OfflineBanner />
        <Stack
            screenOptions={{
              headerShown: false,
              contentStyle: { backgroundColor: colors.bg.base },
              animation: 'default',
              headerBackButtonDisplayMode: 'minimal',
              headerTintColor: GREEN[500],
              headerStyle: { backgroundColor: colors.bg.base },
              headerShadowVisible: false,
              headerTitleStyle: { fontWeight: '600', fontSize: 17, color: colors.text.primary },
            }}
          >
            <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
            <Stack.Screen
              name="onboarding"
              options={{ animation: 'fade' }}
            />
            <Stack.Screen
              name="zone/[bodyZone]"
              options={{ headerShown: true, headerTitle: '' }}
            />
            <Stack.Screen
              name="program/[id]"
              options={{ headerShown: true, headerTitle: '' }}
            />
            <Stack.Screen
              name="player/[id]"
              options={{ presentation: 'fullScreenModal', animation: 'fade' }}
            />
            <Stack.Screen
              name="complete/[id]"
              options={{ animation: 'fade' }}
            />
            <Stack.Screen
              name="settings"
              options={{
                presentation: 'formSheet',
                sheetGrabberVisible: true,
                sheetAllowedDetents: [0.75, 1.0],
              }}
            />
            <Stack.Screen
              name="terms"
              options={{ headerShown: true, headerTitle: '' }}
            />
            <Stack.Screen
              name="privacy"
              options={{ headerShown: true, headerTitle: '' }}
            />
            <Stack.Screen
              name="paywall"
              options={{
                presentation: 'formSheet',
                sheetGrabberVisible: true,
                sheetAllowedDetents: [0.85, 1.0],
              }}
            />
          </Stack>
      </View>
    </QueryClientProvider>
  )

  const posthogClient = getPostHogClient()

  // Only wrap with PostHogProvider if client is initialized
  if (!posthogClient) {
    return content
  }

  return (
    <PostHogProvider
      client={posthogClient}
      autocapture={{
        captureScreens: true,
        captureTouches: true,
      }}
    >
      {content}
    </PostHogProvider>
  )
}

export default function RootLayout() {
  return (
    <ErrorBoundary>
      <ThemeProvider>
        <RootLayoutInner />
      </ThemeProvider>
    </ErrorBoundary>
  )
}
