import React, { useEffect, useState } from 'react';
import { Text, View } from 'react-native';
import { Redirect, Stack, usePathname, useRouter } from 'expo-router';
import { useShareIntent } from 'expo-share-intent';
import { StatusBar } from 'expo-status-bar';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { AppProvider, useApp } from '../context/AppContext';
import { CoachMarksProvider } from '../context/CoachMarksContext';
import { CoachMarksOverlay } from '../components/CoachMarksOverlay';
import { useColors } from '../constants/Colors';
import { initDatabase, AppMetaDb } from '../services/database';
import * as SecureStore from 'expo-secure-store';
import * as SplashScreen from 'expo-splash-screen';
import * as ExpoLinking from 'expo-linking';
import { AuthService } from '../services/authService';
import { AnimatedSplashScreen } from '../components/AnimatedSplashScreen';

// Prevent the splash screen from auto-hiding before asset loading is complete.
SplashScreen.preventAutoHideAsync().catch(() => { });

const SECURE_INSTALL_MARKER = 'greenlens_install_v1';
const isShareIntentUrl = (url: string | null | undefined) => Boolean(url?.includes('://dataUrl='));

const toStartupErrorMessage = (error: unknown): string => {
  if (!error) return 'Unknown startup error';
  if (error instanceof Error) return error.message;
  return String(error);
};

const StartupFallback = ({ details }: { details?: string | null }) => (
  <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', padding: 24, backgroundColor: '#111813' }}>
    <Text style={{ color: '#fff', fontSize: 18, fontWeight: '700', marginBottom: 8, textAlign: 'center' }}>
      GreenLens could not start.
    </Text>
    <Text style={{ color: '#D6DED7', fontSize: 14, lineHeight: 20, textAlign: 'center' }}>
      Please send this startup error to support.
    </Text>
    {details ? (
      <Text style={{ color: '#FFB4A8', fontSize: 12, lineHeight: 17, marginTop: 16, textAlign: 'center' }}>
        {details}
      </Text>
    ) : null}
  </View>
);

class RootErrorBoundary extends React.Component<{ children: React.ReactNode }, { hasError: boolean; errorMessage: string | null }> {
  state = { hasError: false, errorMessage: null };

  static getDerivedStateFromError(error: unknown) {
    return { hasError: true, errorMessage: toStartupErrorMessage(error) };
  }

  componentDidCatch(error: unknown) {
    console.error('[RootErrorBoundary]', error);
  }

  render() {
    if (this.state.hasError) {
      return <StartupFallback details={this.state.errorMessage} />;
    }

    return this.props.children;
  }
}

const ensureInstallConsistency = async (): Promise<boolean> => {
  try {
    const sqliteMarker = AppMetaDb.get('install_marker_v2');
    const secureMarker = await SecureStore.getItemAsync(SECURE_INSTALL_MARKER).catch(() => null);

    if (sqliteMarker === '1' && secureMarker === '1') {
      return false; // Alles gut, keine Neuinstallation
    }

    if (sqliteMarker === '1' || secureMarker === '1') {
      // Teilweise vorhanden -> heilen, nicht löschen
      AppMetaDb.set('install_marker_v2', '1');
      await SecureStore.setItemAsync(SECURE_INSTALL_MARKER, '1');
      return false;
    }

    // Fresh Install: Alles zurücksetzen
    await AuthService.logout();
    await AsyncStorage.removeItem('greenlens_show_tour');
    AppMetaDb.set('install_marker_v2', '1');
    await SecureStore.setItemAsync(SECURE_INSTALL_MARKER, '1');
    return true;
  } catch (error) {
    console.error('Failed to initialize install marker', error);
    return false;
  }
};

function RootLayoutInner() {
  const {
    isDarkMode,
    colorPalette,
    signOut,
    session,
    billingSummary,
    isActivatingEntitlement,
    isInitializing,
    isLoadingPlants,
    isLoadingBilling,
  } = useApp();
  const colors = useColors(isDarkMode, colorPalette);
  const pathname = usePathname();
  const router = useRouter();
  const [shareIntentEnabled, setShareIntentEnabled] = useState(false);
  const { hasShareIntent, shareIntent, resetShareIntent } = useShareIntent({ disabled: !shareIntentEnabled });
  const [installCheckDone, setInstallCheckDone] = useState(false);
  const [splashAnimationComplete, setSplashAnimationComplete] = useState(false);

  useEffect(() => {
    let mounted = true;

    ExpoLinking.getInitialURL()
      .then((url) => {
        if (mounted && isShareIntentUrl(url)) {
          setShareIntentEnabled(true);
        }
      })
      .catch(() => {});

    const subscription = ExpoLinking.addEventListener('url', ({ url }) => {
      if (isShareIntentUrl(url)) {
        setShareIntentEnabled(true);
      }
    });

    return () => {
      mounted = false;
      subscription.remove();
    };
  }, []);

  useEffect(() => {
    (async () => {
      const didResetSessionForFreshInstall = await ensureInstallConsistency();
      if (didResetSessionForFreshInstall) {
        await signOut();
      }
      setInstallCheckDone(true);
    })();
  }, [signOut]);

  const isAppReady = installCheckDone && !isInitializing && !isLoadingPlants;

  useEffect(() => {
    if (!hasShareIntent || !isAppReady) return;
    const sharedImage = shareIntent.files?.find((file) => file.mimeType?.startsWith('image/'));
    if (!sharedImage) {
      resetShareIntent();
      return;
    }
    const uri = sharedImage.path;
    if (!uri) {
      resetShareIntent();
      return;
    }
    resetShareIntent();
    router.push({
      pathname: '/scanner',
      params: { sharedImageUri: uri },
    });
  }, [hasShareIntent, shareIntent, resetShareIntent, router, isAppReady]);
  const hasActiveEntitlement = isActivatingEntitlement
    || (billingSummary?.entitlement?.plan === 'pro'
      && billingSummary?.entitlement?.status === 'active');
  const isAllowedWithoutSession = pathname.includes('onboarding')
    || pathname.includes('auth/')
    || pathname.includes('scanner')
    || pathname.includes('profile/billing');
  const isAllowedWithoutEntitlement = pathname.includes('auth/')
    || pathname.includes('onboarding')
    || pathname.includes('scanner')
    || pathname.includes('profile/billing');

  let content = null;

  if (isAppReady) {
    if (!session) {
      // Only redirect if we are not already on an auth-related page or the scanner
      if (!isAllowedWithoutSession) {
        content = <Redirect href="/onboarding" />;
      } else {
        content = (
          <Stack
            screenOptions={{
              headerShown: false,
              contentStyle: { backgroundColor: colors.background },
            }}
          >
            <Stack.Screen name="onboarding" options={{ animation: 'none' }} />
            <Stack.Screen name="onboarding/source" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="onboarding/goal" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="onboarding/experience" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="onboarding/customize" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="auth/login" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="auth/signup" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen
              name="scanner"
              options={{ presentation: 'fullScreenModal', animation: 'slide_from_bottom' }}
            />
            <Stack.Screen
              name="profile/billing"
              options={{ presentation: 'card', animation: 'slide_from_right' }}
            />
          </Stack>
        );
      }
    } else if (!hasActiveEntitlement && !isLoadingBilling && !isAllowedWithoutEntitlement) {
      content = <Redirect href="/onboarding" />;
    } else {
      content = (
        <>
          <Stack
            screenOptions={{
              headerShown: false,
              contentStyle: { backgroundColor: colors.background },
            }}
          >
            <Stack.Screen name="onboarding" options={{ animation: 'none' }} />
            <Stack.Screen name="onboarding/source" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="onboarding/goal" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="onboarding/experience" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="onboarding/customize" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="auth/login" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="auth/signup" options={{ animation: 'slide_from_right' }} />
            <Stack.Screen name="(tabs)" options={{ animation: 'none' }} />
            <Stack.Screen
              name="scanner"
              options={{ presentation: 'fullScreenModal', animation: 'slide_from_bottom' }}
            />
            <Stack.Screen
              name="plant/[id]"
              options={{ presentation: 'card', animation: 'slide_from_right' }}
            />
            <Stack.Screen
              name="lexicon"
              options={{ presentation: 'fullScreenModal', animation: 'slide_from_bottom' }}
            />
            <Stack.Screen
              name="profile/preferences"
              options={{ presentation: 'card', animation: 'slide_from_right' }}
            />
            <Stack.Screen
              name="profile/data"
              options={{ presentation: 'card', animation: 'slide_from_right' }}
            />
            <Stack.Screen
              name="profile/billing"
              options={{ presentation: 'card', animation: 'slide_from_right' }}
            />
          </Stack>
          <CoachMarksOverlay />
        </>
      );
    }
  }

  return (
    <>
      <StatusBar style={isDarkMode ? 'light' : 'dark'} />
      {content}
      {!splashAnimationComplete && (
        <AnimatedSplashScreen
          isAppReady={isAppReady}
          onAnimationComplete={() => setSplashAnimationComplete(true)}
        />
      )}
    </>
  );
}

export default function RootLayout() {
  let dbInitError: string | null = null;
  try {
    initDatabase();
  } catch (e) {
    dbInitError = String(e);
  }

  if (dbInitError) {
    return <StartupFallback details={`Database init failed: ${dbInitError}`} />;
  }

  return (
    <RootErrorBoundary>
      <AppProvider>
        <CoachMarksProvider>
          <RootLayoutInner />
        </CoachMarksProvider>
      </AppProvider>
    </RootErrorBoundary>
  );
}
