// App.tsx
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { toastConfig } from 'components/CustomAlertModal';
import { navigationRef } from 'components/NavigationRef';
import i18n from 'i18n/i18n';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { I18nextProvider } from 'react-i18next';
import {
  Animated,
  Dimensions,
  LogBox,
  StatusBar,
  StyleSheet,
  View,
} from 'react-native';
import Toast from 'react-native-toast-message';
import SplashScreen from './src/components/SplashScreen';

// Screens
import {
  authEvents,
  getLanguage,
  getToken,
  loadInitialAuthData,
  storage,
} from 'helpers/event';
import Login from 'screens/auth/login/ui';
import Confirm from 'screens/auth/login/ui/Confirm';
import Register from 'screens/auth/registeration/ui';
import SecondStep from 'screens/auth/registeration/ui/SecondStep';
import TermsAndConditions from 'screens/auth/registeration/ui/TermsAndConditions';
import SelectAuth from 'screens/auth/select-auth/SelectAuth';
import Branches from 'screens/home/branches/ui/Branches';
import ListBranches from 'screens/home/branches/ui/ListBranches';
import CargoPrices from 'screens/home/cargoPrices/ui/CargoPrices';
import Home from 'screens/home/home/ui/Home';
import RestrictedProduct from 'screens/home/restrictedProduct/ui/RestrictedProduct';
import CreatePassword from 'screens/passport/createPassport/ui/CreatePassword';
import Passport from 'screens/passport/myPassport/ui/Passport';
import Profile from 'screens/profile/myProfile/ui/Profile';
import AddedLock from 'screens/profile/settings/ui/AddedLock';
import Settings from 'screens/profile/settings/ui/Settings';
import SettingsLock from 'screens/profile/settings/ui/SettingsLock';
import Support from 'screens/profile/support/ui/Support';
import Warehouses from 'screens/profile/warehouses/ui/Warehouses';
import Status from 'screens/status/ui/Status';
import EnterCard from 'screens/wallet/enterCard/ui/EnterCard';
import Wallet from 'screens/wallet/payment/ui/Wallet';
import PaymentMethod from 'screens/wallet/paymentMethod/ui/PaymentMethod';
import PaymentQrCode from 'screens/wallet/successPayment/ui/PaymentQrCode';
import Onboarding from 'screens/welcome/Onboarding';

LogBox.ignoreLogs([
  'ViewPropTypes will be removed',
  // NOTE: I recommend NOT ignoring "Non-serializable values were found in the navigation state"
  // because it hides bugs that can cause crashes. Keep only if you understand the implications.
]);

const Stack = createNativeStackNavigator();
const screenWidth = Dimensions.get('window').width;
const queryClient = new QueryClient();

export default function App() {
  const [initialRoute, setInitialRoute] = useState<string | null>(null);
  const slideAnim = useRef(new Animated.Value(0)).current;
  const [isSplashVisible, setIsSplashVisible] = useState(true);
  const isMounted = useRef(false);
  const currentAnimation = useRef<Animated.CompositeAnimation | null>(null);

  useEffect(() => {
    loadInitialAuthData();
  }, []);

  useEffect(() => {
    const logoutListener = () => {
      if (navigationRef.isReady()) {
        navigationRef.reset({
          index: 0,
          routes: [{ name: 'Login' }],
        });
      }
    };

    authEvents.on('logout', logoutListener);

    return () => {
      authEvents.removeListener('logout', logoutListener);
    };
  }, []);

  useEffect(() => {
    isMounted.current = true;
    return () => {
      isMounted.current = false;
      if (currentAnimation.current) {
        currentAnimation.current.stop();
      }
    };
  }, []);

  useEffect(() => {
    const initializeApp = async () => {
      try {
        const seen = storage.getString('hasSeenOnboarding');
        const token = getToken();
        const lang = getLanguage();

        if (lang) {
          try {
            await i18n.changeLanguage(lang);
          } catch (e) {
            console.warn('i18n.changeLanguage failed:', e);
          }
        }

        const initialRouteName = !seen
          ? 'Onboarding'
          : token
          ? 'Home'
          : 'select-auth';

        if (isMounted.current) {
          setInitialRoute(initialRouteName);
        }
      } catch (error) {
        console.error('App initialization error:', error);
        if (isMounted.current) setInitialRoute('select-auth');
      }
    };

    initializeApp();
  }, []);

  const handleSplashFinish = useMemo(
    () => () => {
      // create animation and keep ref so we can stop it on unmount
      const animation = Animated.timing(slideAnim, {
        toValue: -screenWidth,
        duration: 600,
        useNativeDriver: true,
      });
      currentAnimation.current = animation;
      animation.start(() => {
        // ensure component still mounted before setting state
        if (isMounted.current) {
          setIsSplashVisible(false);
        }
        currentAnimation.current = null;
      });
    },
    [slideAnim],
  );

  const handleOnboardingFinish = useMemo(
    () => async (navigation: any) => {
      try {
        storage.set('hasSeenOnboarding', 'true');
      } catch (e) {
        console.warn('Failed to set hasSeenOnboarding', e);
      }
      navigation.replace('select-auth');
    },
    [],
  );

  if (initialRoute === null) {
    return <View style={{ flex: 1, backgroundColor: '#000' }} />;
  }

  return (
    <QueryClientProvider client={queryClient}>
      <I18nextProvider i18n={i18n}>
        <View style={{ flex: 1 }}>
          <StatusBar barStyle="dark-content" backgroundColor="#fff" />
          <NavigationContainer ref={navigationRef}>
            <Stack.Navigator
              screenOptions={{
                headerShown: false,
                animation: 'none',
                gestureEnabled: false,
              }}
              // initialRouteName set once (we ensure it's available before first render)
              initialRouteName={initialRoute}
            >
              <Stack.Screen name="Onboarding">
                {props => (
                  <Onboarding
                    {...props}
                    onFinish={() => handleOnboardingFinish(props.navigation)}
                  />
                )}
              </Stack.Screen>
              <Stack.Screen name="select-auth" component={SelectAuth} />
              <Stack.Screen name="Login" component={Login} />
              <Stack.Screen name="Login-Confirm" component={Confirm} />
              <Stack.Screen name="Register" component={Register} />
              <Stack.Screen name="Confirm" component={SecondStep} />
              <Stack.Screen name="SettingsLock" component={SettingsLock} />
              <Stack.Screen name="AddLock" component={AddedLock} />
              <Stack.Screen name="Home" component={Home} />
              <Stack.Screen name="Status" component={Status} />
              <Stack.Screen name="Passports" component={Passport} />
              <Stack.Screen name="CargoPrices" component={CargoPrices} />
              <Stack.Screen name="create-password" component={CreatePassword} />
              <Stack.Screen name="Wallet" component={Wallet} />
              <Stack.Screen name="PaymentMethod" component={PaymentMethod} />
              <Stack.Screen name="EnterCard" component={EnterCard} />
              <Stack.Screen name="PaymentQrCode" component={PaymentQrCode} />
              <Stack.Screen name="Profile" component={Profile} />
              <Stack.Screen name="Settings" component={Settings} />
              <Stack.Screen name="Warehouses" component={Warehouses} />
              <Stack.Screen name="Support" component={Support} />
              <Stack.Screen name="ListBranches" component={ListBranches} />
              <Stack.Screen name="Branches" component={Branches} />
              <Stack.Screen
                name="RestrictedProduct"
                component={RestrictedProduct}
              />
              <Stack.Screen
                name="TermsAndConditions"
                component={TermsAndConditions}
              />
            </Stack.Navigator>
          </NavigationContainer>

          {/* Splash transition */}
          {isSplashVisible && (
            <Animated.View
              style={{
                ...StyleSheet.absoluteFillObject,
                transform: [{ translateX: slideAnim }],
                zIndex: 10,
              }}
            >
              <SplashScreen onFinish={handleSplashFinish} />
            </Animated.View>
          )}

          <Toast config={toastConfig} />
        </View>
      </I18nextProvider>
    </QueryClientProvider>
  );
}
