import React, {
  Suspense,
  lazy,
  useCallback,
  useEffect,
  useMemo,
  useReducer,
} from "react";
import { Routes, Route, Outlet, Navigate } from "react-router-dom";
import usersService from "../../services/UsersService";
import Layout from "../Partials/Layout";
import LoadingSpinner from "../Spinners/LoadingSpinner";

const AddFund = lazy(() => import("./AddFund"));
const ConfirmAddFund = lazy(() => import("./ConfirmAddFund"));
const TransferFund = lazy(() => import("./TransferFund"));
const WalletBox = lazy(() => import("./WalletBox"));
const AddRecipient = lazy(() => import("./AddRecipient"));
const ConfirmTransfer = lazy(() => import("./ConfirmTransfer"));

function Wallet() {
  return (
    <Layout>
      <Outlet />
    </Layout>
  );
}

const initialState = {
  loading: true,
  data: [],
  error: false,
};

// Currently learning better about useReducer, so I converted this since it seemed like something complex
const reducer = (state, action) => {
  switch (action.type) {
    case "FETCH_SUCCESS":
      return {
        ...state,
        loading: false,
        data: action.payload,
      };
    case "FETCH_ERROR":
      return {
        ...state,
        loading: false,
        error: true,
      };
    default:
      return state;
  }
};

const WalletRoutes = () => {
  const apiCall = useMemo(() => new usersService(), []);

  const [walletList, dispatchWalletList] = useReducer(reducer, initialState);
  const [paymentHistory, dispatchPaymentHistory] = useReducer(
    reducer,
    initialState
  );

  const getWalletList = useCallback(() => {
    apiCall
      .getUserWallets(null)
      .then((res) => {
        if (res.data.internal_return < 0) {
          dispatchWalletList({ type: "FETCH_SUCCESS", payload: [] });
        } else {
          dispatchWalletList({
            type: "FETCH_SUCCESS",
            payload: res.data.result_list,
          });
        }
      })
      .catch(() => {
        dispatchWalletList({ type: "FETCH_ERROR" });
      });
  }, [apiCall]);

  const getPaymentHistory = useCallback(() => {
    apiCall
      .getPaymentHx()
      .then((res) => {
        if (res.data.internal_return < 0) {
          dispatchPaymentHistory({ type: "FETCH_SUCCESS", payload: [] });
        } else {
          dispatchPaymentHistory({
            type: "FETCH_SUCCESS",
            payload: res.data.result_list,
          });
        }
      })
      .catch(() => {
        dispatchPaymentHistory({ type: "FETCH_ERROR" });
      });
  }, [apiCall]);

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

    if (isMounted) {
      getWalletList();
      getPaymentHistory();
    }

    return () => {
      isMounted = false;
    };
  }, [getWalletList, getPaymentHistory]);

  return (
    <Routes>
      <Route
        element={
          <Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
            <Wallet />
          </Suspense>
        }
      >
        <Route
          path="add-fund"
          element={
            <Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
              <AddFund payment={paymentHistory} />
            </Suspense>
          }
        />
        <Route
          path="add-fund/confirm-add-fund"
          element={
            <Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
              <ConfirmAddFund payment={paymentHistory} />
            </Suspense>
          }
        />
        <Route
          path="transfer-fund"
          element={
            <Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
              <TransferFund payment={paymentHistory} wallet={walletList} />
            </Suspense>
          }
        />
        {/*<Route index element={<Balance wallet={walletList} />} />*/}
        <Route
          index
          element={
            <Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
              <WalletBox wallet={walletList} payment={paymentHistory} />
            </Suspense>
          }
        />
        <Route
          path="transfer-fund/add-recipient"
          element={
            <Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
              <AddRecipient />
            </Suspense>
          }
        />
        <Route
          path="transfer-fund/confirm-transfer"
          element={
            <Suspense fallback={<LoadingSpinner size="16" color="sky-blue" />}>
              <ConfirmTransfer payment={paymentHistory} wallet={walletList} />
            </Suspense>
          }
        />
        <Route path="*" element={<Navigate to="/" />} />
      </Route>
    </Routes>
  );
};

export default WalletRoutes;
