import React, {useMemo, useState} from 'react';
import {View, SectionList, ActivityIndicator} from 'react-native';
import dayjs from 'dayjs';
import {useInfiniteQuery} from '@tanstack/react-query';
import {
  Colors,
  fontSz,
  formatDate,
  groupArray,
  ms,
  wp,
} from '../../utils';
import {Text} from '../Text';
import TransactionCard from '../Common/transactionCard';
import ThreePaneToggleTabs from '../ToggleTab/threePane';
import {WalletTransactionDto} from '../../services/types';
import {getSavingsTransactionsList, getSavingsTransactionHistory} from '../../services/actions';
import {useSDKConfig} from '../../contexts/SDKConfigContext';

type TransactionsListProps = {
  savingsId?: string;
  recordsPerPage?: number;
  limit?: number;
  showScrollIndicator?: boolean;
  contentContainerStyle?: any;
  scrollEnabled?: boolean;
  showTabs?: boolean;
  useHistoryEndpoint?: boolean;
};

const TransactionsList = ({
  savingsId,
  recordsPerPage = 10,
  limit,
  showScrollIndicator = false,
  contentContainerStyle,
  scrollEnabled = true,
  showTabs = true,
  useHistoryEndpoint = false,
}: TransactionsListProps) => {
  const {apiKey, primaryColor} = useSDKConfig();
  const [tabRoute, setTabRoute] = useState<0 | 1 | 2>(0);

  // Convert tab route to transaction type for API
  const transactionType = useMemo(() => {
    if (tabRoute === 1) {return 'Credit';}
    if (tabRoute === 2) {return 'Debit';}
    return undefined; // undefined means 'All' - don't pass transactionType parameter
  }, [tabRoute]);

  // Query key should be different for history vs savings transactions
  const queryKey = useHistoryEndpoint 
    ? ['savingsTransactionHistory', apiKey, transactionType]
    : ['savingsTransactions', savingsId, apiKey, transactionType];

  // Query for transactions with infinite loading
  const {
    data: transactionsData,
    isLoading,
    isError,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isFetching,
  } = useInfiniteQuery({
    queryKey,
    queryFn: async ({ pageParam }) => {
      try {
        const params: any = {
          recordsPerPage,
          nextPageToken: pageParam,
        };

        // Only add transactionType if it's not 'All'
        if (transactionType) {
          params.transactionType = transactionType;
        }

        let result;
        if (useHistoryEndpoint) {
          // Use history endpoint - doesn't need savingsId
          result = await getSavingsTransactionHistory(apiKey, params);
          console.log(result, 'result');
        } else {
          // Use existing endpoint - needs savingsId
          if (!savingsId) {
            throw new Error('savingsId is required when not using history endpoint');
          }
          params.savingsId = savingsId;
          result = await getSavingsTransactionsList(apiKey, params);
        }

        // Ensure we always return a valid structure
        return {
          transactionsList: Array.isArray(result?.transactionsList) ? result.transactionsList : [],
          nextPageToken: result?.nextPageToken || undefined,
        };
      } catch (error) {
        console.error('Error fetching transactions:', error);
        // Return empty structure on error
        return {
          transactionsList: [],
          nextPageToken: undefined,
        };
      }
    },
    getNextPageParam: (lastPage) => {
      if (!lastPage || typeof lastPage !== 'object') {
        return undefined;
      }
      return lastPage.nextPageToken || undefined;
    },
    initialPageParam: undefined as string | undefined,
    retry: 2,
    enabled: useHistoryEndpoint || !!savingsId, // Enable if using history endpoint OR if savingsId exists
    // Add default data structure to prevent undefined errors
    initialData: {
      pages: [],
      pageParams: [],
    },
  });

  // Safely flatten all pages into a single transactions array
  const allTransactions = useMemo(() => {
    try {
      if (!transactionsData?.pages || !Array.isArray(transactionsData.pages)) {
        return [];
      }

      const flattened = transactionsData.pages
        .filter(page => page && typeof page === 'object')
        .flatMap(page => {
          if (!Array.isArray(page.transactionsList)) {
            return [];
          }

          return page.transactionsList.filter((transaction: WalletTransactionDto) =>
            transaction &&
            typeof transaction === 'object' &&
            transaction.transactionId
          );
        });

      return flattened;
    } catch (error) {
      console.error('Error processing transactions:', error);
      return [];
    }
  }, [transactionsData]);

  // Apply limit if specified (no need for transaction type filtering since it's done server-side)
  const filteredTransactions = useMemo(() => {
    if (!Array.isArray(allTransactions)) {
      return [];
    }

    // Apply limit if specified
    if (limit) {
      return allTransactions.slice(0, limit);
    }

    return allTransactions;
  }, [allTransactions, limit]);

  // Group transactions by day
  const getDayWiseTransactions = () => {
    if (!Array.isArray(filteredTransactions) || filteredTransactions.length === 0) {
      return [];
    }

    const transactionsWithDay = filteredTransactions
      .filter((el: WalletTransactionDto) => el && el.createdDate)
      .map(function (el: WalletTransactionDto) {
        const formattedDay = formatDate(el.createdDate, 'MMM D, YYYY');
        const todayDate = formatDate(new Date(), 'MMM D, YYYY');
        const dayDifference = dayjs(todayDate).diff(formattedDay, 'day');
        return {
          ...el,
          dayName:
            dayDifference === 0
              ? 'Today'
              : dayDifference === 1
              ? 'Yesterday'
              : formattedDay,
        };
      });

    const dayGroupTransactions = groupArray(transactionsWithDay, 'dayName');
    return Object.entries(dayGroupTransactions).map(([key, value]) => ({
      title: key,
      data: value,
    }));
  };

  const dayWiseTransactions = useMemo(
    () => getDayWiseTransactions(),
    [filteredTransactions],
  );

  // Render content area (loader, error, empty state, or transactions)
  const renderContent = () => {
    // Show loader for initial load or refetching
    if (isLoading || (isFetching && !isLoading)) {
      return (
        <View style={{
          flex: 1,
          justifyContent: 'center',
          alignItems: 'center',
          paddingTop: ms(50),
        }}>
          <ActivityIndicator size="small" color={primaryColor} />
        </View>
      );
    }

    // Show error state
    if (isError) {
      return (
        <View style={{
          flex: 1,
          justifyContent: 'center',
          alignItems: 'center',
          paddingTop: ms(50),
        }}>
          <Text
            color={Colors.neutral90}
            fontWeight="400"
            fontFamily={'Gordita-Regular'}
            fontSize={14}
            text="Failed to load transactions"
          />
        </View>
      );
    }

    // Show empty state
    if (filteredTransactions.length === 0) {
      return (
        <View style={{alignItems: 'center', paddingTop: ms(20)}}>
          <Text
            color={Colors.neutral90}
            fontWeight="400"
            fontFamily={'Gordita-Regular'}
            fontSize={fontSz(14)}
            text="No transactions found"
          />
        </View>
      );
    }

    // Show transactions list
    return (
      <SectionList
        scrollEnabled={scrollEnabled}
        showsVerticalScrollIndicator={showScrollIndicator}
        sections={dayWiseTransactions}
        contentContainerStyle={contentContainerStyle}
        style={{marginTop: showTabs ? ms(4) : 0}}
        onEndReached={() => {
          if (hasNextPage && !isFetchingNextPage && !limit) {
            fetchNextPage();
          }
        }}
        onEndReachedThreshold={0.3}
        ListFooterComponent={
          isFetchingNextPage && !limit ? (
            <View style={{ padding: ms(20), alignItems: 'center' }}>
              <ActivityIndicator size="small" color={primaryColor} />
            </View>
          ) : null
        }
        renderItem={({item, index}) => {
          return (
            <TransactionCard
              key={index}
              status={item?.transactionType as 'Debit' | 'Credit'}
              title={item?.description || item?.narration}
              transactionType={item?.transactionType}
              amount={item?.amount}
              createdDate={item?.createdDate}
              showTransactionType={true}
              onPress={() => {}}
            />
          );
        }}
        renderSectionHeader={({section}) => (
          <View style={{
            backgroundColor: Colors.white,
            paddingTop: ms(10),
            paddingBottom: ms(5),
          }}>
            <Text
              color={'#515A65'}
              fontWeight="500"
              fontFamily={'Gordita-Medium'}
              fontSize={fontSz(12)}
              lineHeight={fontSz(18)}
              text={section.title}
            />
          </View>
        )}
        keyExtractor={(item, index) => `${item.transactionId}-${index}`}
      />
    );
  };

  return (
    <View style={{flex: 1}}>
      {showTabs && (
        <ThreePaneToggleTabs
          selectedTab={(e: React.SetStateAction<0 | 1 | 2>) => {
            setTabRoute(e);
          }}
          currentTab={tabRoute}
          firstLabel={'All'}
          secondLabel={'Credit'}
          thirdLabel={'Debit'}
        />
      )}

      {renderContent()}
    </View>
  );
};

export default TransactionsList;
