import React, {JSX, useEffect, useState} from 'react';
import {
  BackHandler,
  View,
  ActivityIndicator,
  SafeAreaView,
  StatusBar,
} from 'react-native';
import {useQuery} from '@tanstack/react-query';
import {
  SavingsCategoryType,
  SuggestedPlansOptionsType,
  Colors,
  globalStyles,
  ms,
} from '../utils';
import SavingsScreen from '../app/savings';
import SuggestedPlansScreen from '../app/suggestedPlans';
import SavingsFormScreen from '../app/savingsForm';
import ExistingSavingsScreen from '../app/existingSavings';
import HistoryScreen from '../app/history';
import AllPlanScreen from '../app/allPlan';
import PlanScreen from '../app/plan';
import {useSDKConfig} from '../contexts/SDKConfigContext';
import {getTotalAccountTransactionsByCustomerId} from '../services/actions';
import Header from '../components/Header';

export type ScreenName =
  | 'savings'
  | 'suggestedPlans'
  | 'savingsForm'
  | 'existingSavings'
  | 'history'
  | 'allPlan'
  | 'plan';

export type ScreenParams = {
  savings: {preSelectedCategory?: SavingsCategoryType};
  suggestedPlans: {savingsOption: SavingsCategoryType};
  savingsForm: {
    savingsOption: SavingsCategoryType;
    suggestedPlan?: SuggestedPlansOptionsType | null;
    editMode?: boolean;
    existingSavingsData?: any;
  };
  existingSavings: {
    savingsOption?: SavingsCategoryType;
    suggestedPlan?: SuggestedPlansOptionsType | null;
  };
  history: {planId?: string; planName?: string};
  allPlan: {plan?: string; categoryFilter?: any};
  plan: {planId: string; planName: string};
};

export type CommonScreenProps = {
  navigate: <T extends ScreenName>(name: T, params?: ScreenParams[T]) => void;
  replace: <T extends ScreenName>(name: T, params?: ScreenParams[T]) => void;
  goBack: () => void;
  isInitialScreen: boolean;
};

type ScreenStackItem = {
  name: ScreenName;
  params?: any;
};

const AppStackNavigator = (): JSX.Element => {
  const {apiKey, onClose, primaryColor} = useSDKConfig();
  const [screenStack, setScreenStack] = useState<ScreenStackItem[]>([]);

  // Use React Query to check for existing accounts
  const {
    data: accountSummary,
    isLoading,
    isError,
  } = useQuery({
    queryKey: ['customerAccountSummary', apiKey],
    queryFn: () => getTotalAccountTransactionsByCustomerId(apiKey),
    staleTime: 5 * 60 * 1000, // 5 minutes
    retry: 2,
  });

  // Set initial screen based on query results
  useEffect(() => {
    if (!isLoading) {
      // If user has existing accounts (success response), navigate to existingSavings
      // If no accounts (error response), navigate to savings
      if (
        accountSummary &&
        !accountSummary.error &&
        accountSummary.customerId
      ) {
        setScreenStack([{name: 'existingSavings'}]);
      } else {
        setScreenStack([{name: 'savings', params: {}}]);
      }
    }
  }, [isLoading, accountSummary]);

  useEffect(() => {
    const onBackPress = () => {
      if (screenStack.length > 1) {
        goBack();
        return true;
      } else if (onClose) {
        // If it's the initial screen and onClose is provided, call it
        onClose();
        return true;
      }
      return false;
    };

    const subscription = BackHandler.addEventListener(
      'hardwareBackPress',
      onBackPress,
    );

    return () => subscription.remove();
  }, [screenStack, onClose]);

  const navigate = <T extends ScreenName>(
    name: T,
    params?: ScreenParams[T],
  ) => {
    setScreenStack([...screenStack, {name, params}]);
  };

  const replace = <T extends ScreenName>(name: T, params?: ScreenParams[T]) => {
    if (screenStack.length > 0) {
      // Replace the current screen with the new one
      const newStack = [...screenStack];
      newStack[newStack.length - 1] = {name, params};
      setScreenStack(newStack);
    } else {
      // If no screens in stack, just navigate
      setScreenStack([{name, params}]);
    }
  };

  const goBack = () => {
    if (screenStack.length > 1) {
      setScreenStack(screenStack.slice(0, -1));
    } else if (onClose) {
      // If trying to go back from initial screen, call onClose
      onClose();
    }
  };

  // Show loading state during initialization
  if (isLoading || screenStack.length === 0) {
    return (
      <>
        <StatusBar
          backgroundColor={Colors.white}
          barStyle={'dark-content'}
          animated={false}
        />
        <SafeAreaView style={[globalStyles.appContainer]}>
          <Header
            headerText={'Savings'}
            containerStyle={{
              paddingBottom: ms(10),
              paddingTop: ms(4),
              borderBottomWidth: ms(1),
              borderBottomColor: Colors.headerBottomColor,
            }}
            onPressBack={() => {
              goBack();
            }}
            headerChild={<View style={{flex: 0.125}} />}
          />
          <View
            style={{
              flex: 1,
              justifyContent: 'center',
              alignItems: 'center',
            }}>
            <ActivityIndicator size="small" color={primaryColor} />
          </View>
        </SafeAreaView>
      </>
    );
  }

  const {name: currentScreen, params} = screenStack[screenStack.length - 1];
  const isInitialScreen = screenStack.length === 1;

  const screenProps = {
    navigate,
    replace,
    goBack,
    params,
    isInitialScreen,
  };

  switch (currentScreen) {
    case 'savings':
      return <SavingsScreen {...screenProps} />;
    case 'suggestedPlans':
      return <SuggestedPlansScreen {...screenProps} />;
    case 'savingsForm':
      return <SavingsFormScreen {...screenProps} />;
    case 'existingSavings':
      return <ExistingSavingsScreen {...screenProps} />;
    case 'history':
      return <HistoryScreen {...screenProps} />;
    case 'allPlan':
      return <AllPlanScreen {...screenProps} />;
    case 'plan':
      return <PlanScreen {...screenProps} />;
    default:
      return <SavingsScreen {...screenProps} />;
  }
};

export default AppStackNavigator;
