import "react-native-gesture-handler";
import { StatusBar } from "expo-status-bar";
import { Text, View } from "react-native";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { DefaultTheme, NavigationContainer } from "@react-navigation/native";
import SideBar from "./src/Components/SideBar";
import {
  AppContext,
  AppProvider,
  AppStyles,
  Constants,
  GetDataFromList,
  GetMultipleData,
  IsPlatformIos,
} from "./src/utils";
import { Suspense, lazy, useContext, useEffect } from "react";
import { SafeAreaView } from "react-native-safe-area-context";
import "./i18n";
import DeviceScreen from "./src/Screens/Device";
import { createStackNavigator } from "@react-navigation/stack";
import { TouchableOpacity } from "react-native";
import MyIcon from "./src/Components/Icon";
import { useTranslation } from "react-i18next";
import ChooseSceneModalContent from "./src/Screens/Device/modals/ChooseScene";
import CreateSceneModalContent from "./src/Screens/Device/modals/ChooseScene/CreateScene";
import AddSceneActionModalContent from "./src/Screens/Device/modals/AddSceneAction";
import LayerSelectionModalContent from "./src/Screens/Device/modals/AddSceneAction/LayerSelection";
import {
  SettingsAppColorSchemeModalContent,
  SettingsAppLanguageModalContent,
} from "./src/Screens/Settings";
import UpdateSceneNameModalContent from "./src/Screens/Device/modals/UpdateSceneName";
import SettingsChangeDeviceDisplayNameModalContent from "./src/Screens/Device/modals/SettingsChangeDeviceDisplayName";
import LightsEditActionModalContent, {
  LightsEditActionColorModeSelectionModalContent,
} from "./src/Screens/Device/modals/EditActions/Lights";
import { EditActionAnimationSelectionModalContent } from "./src/Screens/Device/modals/EditActions";
import MotorEditActionModalContent, {
  MotorEditActionMotorModeSelectionModalContent,
} from "./src/Screens/Device/modals/EditActions/Motor";
import WaitXSecondsEditActionModalContent from "./src/Screens/Device/modals/EditActions/Wait";
import StopEditActionModalContent from "./src/Screens/Device/modals/EditActions/Stop";
import SearchForNewDevicesModalContent from "./src/Screens/SearchForNewDevices";
import HelpCenterModalContent from "./src/Screens/Help/modals/HelpCenter";
import { FeedbackStepsModalContent } from "./src/Screens/Help/modals/Feedback/steps";
import GiveFeedbackModalContent from "./src/Screens/Help/modals/Feedback";
import FeedbackFinishedModalContent from "./src/Screens/Help/modals/Feedback/finished";

const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();

const SettingsScreen = lazy(() => import("./src/Screens/Settings"));
const HelpScreen = lazy(() => import("./src/Screens/Help"));
const NoDevicesConnectedScreen = lazy(() =>
  import("./src/Screens/NoDevicesConnected")
);

export function MyApp() {
  const appContext = useContext(AppContext);
  const { t } = useTranslation();

  useEffect(() => {
    const loadData = async () => {
      const data = await GetMultipleData([
        "appLanguage",
        "appColorScheme",
        "userExpertMode",
        "userDeveloperMode",
        "userColorSwatchesFavorites",
      ]);

      const appLanguage = GetDataFromList(data, "appLanguage");
      const appColorScheme = GetDataFromList(data, "appColorScheme");
      const userExpertMode = GetDataFromList(data, "userExpertMode");
      const userDeveloperMode = GetDataFromList(data, "userDeveloperMode");
      const userColorSwatchesFavorites = GetDataFromList(
        data,
        "userColorSwatchesFavorites"
      );

      appContext.setAppLanguage(
        appLanguage === null ? Constants.defaultLanguage : appLanguage
      );
      appContext.setAppColorScheme(
        appColorScheme === null ? "auto" : appColorScheme
      );

      appContext.setIsUserExpertModeEnabled(
        userExpertMode == null ? false : userExpertMode
      );

      appContext.setUserIsDeveloperModeEnabled(
        userDeveloperMode == null ? false : userDeveloperMode
      );

      appContext.setUserColorSwatchesFavorites(
        userColorSwatchesFavorites === null
          ? Constants.defaultColorSwatchesFavorites
          : userColorSwatchesFavorites
      );
    };

    loadData();
  }, []);

  const options = ({ navigation, pageTitle }) => {
    return getScreenStackOptions(
      navigation,
      pageTitle,
      appContext.appTheme.text,
      appContext.appTheme.backgroundColor,
      true
    );
  };

  const navigatonTheme = {
    ...DefaultTheme,
    colors: {
      ...DefaultTheme.colors,
      background: appContext.appTheme.backgroundColor,
      border: "transparent",
    },
  };

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <NavigationContainer theme={navigatonTheme}>
        <Stack.Navigator screenOptions={{ headerTitleAlign: "center" }}>
          <Stack.Screen
            name="drawer"
            component={MyDrawer}
            options={{ headerShown: false }}
          />

          <Stack.Screen
            name="modalChooseScene"
            component={ChooseSceneModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.modalChooseScene.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalCreateScene"
            component={CreateSceneModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.modalCreateScene.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalAddSceneAction"
            component={AddSceneActionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.modalAddSceneAction.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalLayerSelection"
            component={LayerSelectionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.modalLayerSelection.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalLightsEditAction"
            component={LightsEditActionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
              })
            }
          />

          <Stack.Screen
            name="modalLightsEditActionColorModeSelection"
            component={LightsEditActionColorModeSelectionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.editActions.modalLightsEditActionColorModeSelection.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalEditActionAnimationInOrOutSelection"
            component={EditActionAnimationSelectionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
              })
            }
          />

          <Stack.Screen
            name="modalMotorEditAction"
            component={MotorEditActionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.editActions.modalMotorEditAction.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalMotorEditActionMotorModeSelection"
            component={MotorEditActionMotorModeSelectionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.editActions.modalMotorEditActionMotorModeSelection.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalWaitEditAction"
            component={WaitXSecondsEditActionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.editActions.modalWaitEditAction.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalStopEditAction"
            component={StopEditActionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.editActions.modalStopEditAction.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalUpdateSceneName"
            component={UpdateSceneNameModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.modalUpdateSceneName.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalHelpCenter"
            component={HelpCenterModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t("screens.help.modalHelpCenter.pageTitle"),
              })
            }
          />

          <Stack.Screen
            name="modalGiveFeedback"
            component={GiveFeedbackModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t("screens.help.modalGiveFeedback.pageTitle"),
              })
            }
          />

          <Stack.Screen
            name="modalFeedbackSteps"
            component={FeedbackStepsModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t("screens.help.modalFeedbackSteps.pageTitle"),
              })
            }
          />

          <Stack.Screen
            name="modalFeedbackFinished"
            component={FeedbackFinishedModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t("screens.help.modalFeedbackFinished.pageTitle"),
              })
            }
          />

          <Stack.Screen
            name="modalSettingsAppColorScheme"
            component={SettingsAppColorSchemeModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t("screens.settings.appColorSchemeModalTitle"),
              })
            }
          />

          <Stack.Screen
            name="modalSettingsAppLanguage"
            component={SettingsAppLanguageModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t("screens.settings.languageModalTitle"),
              })
            }
          />

          <Stack.Screen
            name="modalSettingsChangeDeviceDisplayName"
            component={SettingsChangeDeviceDisplayNameModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.settings.modalSettingsChangeDeviceDisplayName.pageTitle"
                ),
              })
            }
          />

          <Stack.Screen
            name="modalSearchForNewDevices"
            component={SearchForNewDevicesModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t("screens.modalSearchForNewDevices.pageTitle"),
              })
            }
          />
        </Stack.Navigator>
      </NavigationContainer>

      <StatusBar
        backgroundColor={appContext.appTheme.backgroundColor}
        style={appContext.appTheme._id === "dark" ? "light" : "dark"}
      />
    </SafeAreaView>
  );
}

// This is for the left sidebar navigation
function MyDrawer() {
  const appContext = useContext(AppContext);

  return (
    <Drawer.Navigator
      screenOptions={{
        headerShown: false,
        //headerStyle: {
        //  backgroundColor: appContext.appTheme.backgroundColor,
        //},
        //headerTintColor: appContext.appTheme.text,
        drawerStyle: {
          backgroundColor: appContext.appTheme.drawer.backgroundColor,
        },
      }}
      drawerContent={(props) => <SideBar {...props} />}
    >
      {appContext.devices.map((device) => (
        <Drawer.Screen
          key={device.id}
          name={device.displayName}
          component={DeviceScreenStack}
          initialParams={{ deviceDisplayName: device.displayName }}
        />
      ))}

      <Drawer.Screen name="Help" component={HelpScreenStack} />
      <Drawer.Screen name="Settings" component={SettingsScreenStack} />

      <Drawer.Screen
        name="_noDevicesConnected"
        component={NoDevicesConnectedStack}
      />
    </Drawer.Navigator>
  );
}

const DeviceScreenStack = (props) => {
  return (
    <MyScreenStack
      name="device"
      pageTitle={props.route.params.deviceDisplayName}
      component={DeviceScreen}
      navigation={props.navigation}
      params={props.route.params}
    />
  );
};

const NoDevicesConnectedStack = (props) => {
  const { t } = useTranslation();

  return (
    <MyScreenStack
      name="noDevicesConnected"
      pageTitle={t("screens.noDevicesConnected.pageTitle")}
      component={NoDevicesConnectedScreen}
      navigation={props.navigation}
    />
  );
};

const HelpScreenStack = (props) => {
  const { t } = useTranslation();

  return (
    <MyScreenStack
      name="help"
      pageTitle={t("screens.help.pageTitle")}
      component={HelpScreen}
      navigation={props.navigation}
    />
  );
};

const SettingsScreenStack = (props) => {
  const { t } = useTranslation();

  return (
    <MyScreenStack
      name="settings"
      pageTitle={t("screens.settings.pageTitle")}
      component={SettingsScreen}
      navigation={props.navigation}
    />
  );
};

function getScreenStackOptions(
  navigation,
  pageTitle,
  headerTintColor,
  headerBackgroundColor,
  isModalScreen
) {
  return {
    title: pageTitle,
    headerLeft: () => (
      <TouchableOpacity
        onPress={() =>
          isModalScreen ? navigation.goBack() : navigation.toggleDrawer()
        }
      >
        <MyIcon
          name={isModalScreen ? "chevron-left" : "menu"}
          size={24}
          style={[AppStyles.headerNavigationIcons]}
        />
      </TouchableOpacity>
    ),
    headerTintColor: headerTintColor,
    headerTitleAlign: "center",
    headerStyle: {
      backgroundColor: headerBackgroundColor,
      height: IsPlatformIos() ? 76 : 56,
    },
  };
}

function MyScreenStack({ navigation, name, pageTitle, component, params }) {
  const appContext = useContext(AppContext);

  return (
    <Stack.Navigator initialRouteName={name}>
      <Stack.Screen
        name={name}
        component={component}
        initialParams={params}
        options={getScreenStackOptions(
          navigation,
          pageTitle,
          appContext.appTheme.text,
          appContext.appTheme.backgroundColor
        )}
      />
    </Stack.Navigator>
  );
}

export default function App() {
  return (
    <Suspense
      fallback={
        <View
          style={{ flex: 1, justifyContent: "center", alignItems: "center" }}
        >
          <Text>Loading...</Text>
        </View>
      }
    >
      <AppProvider>
        <MyApp />
      </AppProvider>
    </Suspense>
  );
}
