import UploadProgress from "@/components/upload-progress/upload-progress";
import { checkUserSession } from "@/redux/user/user.actions";
import { selectBodyshop, selectCurrentUser } from "@/redux/user/user.selectors";
import { ApolloProvider } from "@apollo/client";
import { loadDevMessages, loadErrorMessages } from "@apollo/client/dev";
import MaterialIcons from "@expo/vector-icons/MaterialIcons";

import {
  DarkTheme,
  DefaultTheme,
  ThemeProvider,
} from "@react-navigation/native";
import * as Sentry from "@sentry/react-native";
import * as Notifications from "expo-notifications";
import { Stack } from "expo-router";
import {
  Icon,
  Label,
  NativeTabs,
  VectorIcon,
} from "expo-router/unstable-native-tabs";
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { Platform, View } from "react-native";
import {
  ActivityIndicator,
  Provider as PaperProvider,
} from "react-native-paper";
import { connect, Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { createStructuredSelector } from "reselect";
import { client } from "../graphql/client";
import { useTheme as usePaperTheme } from "../hooks/useTheme";
import { persistor, store } from "../redux/store";
import "../translations/i18n";
import { registerForPushNotificationsAsync } from "../util/notificationHandler";

loadDevMessages();
loadErrorMessages();

Sentry.init({
  dsn: "https://8d6c3de1940a4e4f8b81cf4d2150bdea@o492140.ingest.us.sentry.io/5558869",
  // Adds more context data to events (IP address, cookies, user, etc.)
  // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
  sendDefaultPii: true,
  // Enable Logs
  enableLogs: true,
  // Configure Session Replay
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1,
  integrations: [
    Sentry.mobileReplayIntegration(),
    Sentry.feedbackIntegration(),
  ],
  ignoreErrors: [/.*Network Error.*/i],
});

function AuthenticatedLayout() {
  const { t } = useTranslation();
  const paperTheme = usePaperTheme();

  return (
    <ThemeProvider
      value={paperTheme.theme === "dark" ? DarkTheme : DefaultTheme}
    >
      <NativeTabs
        minimizeBehavior="onScrollDown"
        disableTransparentOnScrollEdge
        {...(paperTheme.theme === "dark"
          ? {
              backgroundColor: DarkTheme.colors.background,
              tintColor: DarkTheme.colors.text,
              indicatorColor: DarkTheme.colors.border,
            }
          : {})}
      >
        <NativeTabs.Trigger name="jobs">
          <Label>{t("joblist.labels.activejobs")}</Label>

          {Platform.select({
            ios: <Icon sf="checklist" drawable="custom_android_drawable" />,
            android: (
              <Icon
                src={<VectorIcon family={MaterialIcons} name="checklist" />}
              />
            ),
          })}
        </NativeTabs.Trigger>
        {/* <NativeTabs.Trigger name="production">
          {Platform.select({
            ios: <Icon sf="gear" drawable="custom_android_drawable" />,
            android: (
              <Icon src={<VectorIcon family={MaterialIcons} name="start" />} />
            ),
          })}
          <Label>{t("production.titles.production")}</Label>
        </NativeTabs.Trigger> */}
        <NativeTabs.Trigger name="settings">
          {Platform.select({
            ios: <Icon sf="gear" drawable="custom_android_drawable" />,
            android: (
              <Icon
                src={<VectorIcon family={MaterialIcons} name="settings" />}
              />
            ),
          })}
          <Label>{t("settings.titles.settings")}</Label>
        </NativeTabs.Trigger>
        <NativeTabs.Trigger name="search" role="search">
          {Platform.select({
            //ios: <Icon sf="checklist" drawable="custom_android_drawable" />,
            android: (
              <Icon src={<VectorIcon family={MaterialIcons} name="search" />} />
            ),
          })}
          <Label>Search</Label>
        </NativeTabs.Trigger>
      </NativeTabs>
    </ThemeProvider>
  );
}

function UnauthenticatedLayout() {
  const paperTheme = usePaperTheme();

  return (
    <ThemeProvider
      value={paperTheme.theme === "dark" ? DarkTheme : DefaultTheme}
    >
      <Stack>
        <Stack.Screen name="sign-in" options={{ headerShown: false }} />
      </Stack>
    </ThemeProvider>
  );
}

function LoadingLayout() {
  return (
    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
      <ActivityIndicator size="large" />
    </View>
  );
}

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop,
  currentUser: selectCurrentUser,
});
const mapDispatchToProps = (dispatch: any) => ({
  checkUserSession: () => dispatch(checkUserSession()),
});
function AppContent({ currentUser, checkUserSession, bodyshop }: any) {
  useEffect(() => {
    checkUserSession();
  }, [checkUserSession]);

  useEffect(() => {
    registerForPushNotificationsAsync()
      .then((token) => console.log("Expo Push Token:", token))
      .catch((error: any) =>
        console.log("Error getting Expo Push Token:", error)
      );

    const notificationListener = Notifications.addNotificationReceivedListener(
      async (notification) => {
        console.log("Notification received:", notification);
        Notifications.setBadgeCountAsync(
          (await Notifications.getBadgeCountAsync()) + 1
        );
      }
    );

    const responseListener =
      Notifications.addNotificationResponseReceivedListener((response) => {
        console.log("Notification response received:", response);
      });

    //Clear the badges.
    Notifications.setBadgeCountAsync(0);

    return () => {
      notificationListener.remove();
      responseListener.remove();
    };
  }, []);

  if (currentUser.authorized === null) {
    return (
      <ThemedLayout>
        <LoadingLayout />
      </ThemedLayout>
    );
  }
  if (currentUser.authorized) {
    return (
      <ThemedLayout>
        <UploadProgress />
        <AuthenticatedLayout />
      </ThemedLayout>
    );
  }
  return (
    <ThemedLayout>
      <UnauthenticatedLayout />
    </ThemedLayout>
  );
}

function ThemedLayout({ children }: { children: React.ReactNode }) {
  const themeToApply = usePaperTheme();
  return <PaperProvider theme={themeToApply}>{children}</PaperProvider>;
}
const ConnectedAppContent = connect(
  mapStateToProps,
  mapDispatchToProps
)(AppContent);

function AppLayout() {
  return (
    <Provider store={store}>
      <PersistGate persistor={persistor}>
        <ApolloProvider client={client}>
          <ConnectedAppContent />
        </ApolloProvider>
      </PersistGate>
    </Provider>
  );
}

export default Sentry.wrap(AppLayout);
