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,
  Constants,
  GetDataFromList,
  GetMultipleData,
} 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 {
  LayersEditActionColorModeSelectionModalContent,
  LightsEditActionModalContent,
} from "./src/Screens/Device/modals/EditActions/Lights";
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 { EditActionAnimationSelectionModalContent } from "./src/Screens/Device/modals/EditActions";
import UpdateSceneNameModalContent from "./src/Screens/Device/modals/UpdateSceneName";
import SettingsChangeDeviceDisplayNameModalContent from "./src/Screens/Device/modals/SettingsChangeDeviceDisplayName";
import HelpScreen from "./src/Screens/Device/Help";

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

const SettingsScreen = lazy(() => import("./src/Screens/Settings"));
const FaqScreen = lazy(() => import("./src/Screens/FAQ"));
const FeedbackScreen = lazy(() => import("./src/Screens/Feedback"));

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 ? [] : 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,
    },
  };

  return (
    <SafeAreaView style={{ height: "100%" }}>
      <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="modalLayerSection"
            component={LayerSelectionModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.modalLayerSection.pageTitle"
                ),
              })
            }
          />

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

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

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

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

          <Stack.Screen
            name="modalUpdateSceneName"
            component={UpdateSceneNameModalContent}
            options={({ navigation }) =>
              options({
                navigation: navigation,
                pageTitle: t(
                  "screens.device.scenes.modalUpdateSceneName.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.Navigator>
      </NavigationContainer>

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

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.Navigator>
  );
}

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

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()
        }
        style={{ marginLeft: 20 }}
      >
        <MyIcon name={isModalScreen ? "chevron-left" : "menu"} size={24} />
      </TouchableOpacity>
    ),
    headerTintColor: headerTintColor,
    headerStyle: {
      backgroundColor: headerBackgroundColor,
    },
  };
}

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>
  );
}
