import * as ImagePicker from "expo-image-picker";
import { Pressable, Text } from "react-native";
import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
import React, { useGlobal } from "reactn";

import { responsiveWidth } from "../actions/responsiveSizes.js";
import Page from "../layouts/Page";

import alert from "../components/Alert.js";
import Avatar from "../components/Avatar";
import InputRow from "../components/InputRow";
import ItemRowList from "../components/ItemRowList.js";

import firebase, { usersRef } from "../config/firebase";

import { uploadFileToFirebase } from "../helpers/uploadToFirebase";
import { Routes } from "../navigation/Routes.js";
import { Fonts, gutters, Palette, Style } from "../styles";

import { useUserData } from "../providers/UserDataProvider.js";

export default ({ navigation }) => {
  const { setIsLoading, setTooltip } = useMinuit();
  const { onSignOut } = useUserData();

  const [currentUID] = useGlobal("currentUID");
  const [currentUserData] = useGlobal("currentUserData");

  const settingsList = [
    {
      title: "Nom du compte",
      key: "name",
      value: currentUserData?.name || "",
      type: "string",
    },
    {
      title: "Adresse email",
      key: "email",
      value: currentUserData?.email || "",
      type: "string",
    },
    {
      title: "Mot de passe",
      key: "password",
      value: "",
      type: "string",
    },
    {
      title: "Notifications",
      key: "notifications",
      value: !!currentUserData?.notifications,
      type: "boolean",
    },
    {
      title: "Langue",
      key: "language",
      value: currentUserData?.language || "",
      type: "string",
    },
  ];

  const destructiveSettingsList = [
    {
      title: "Supprimer mon compte",
      action: () => onDeleteUserAccount(),
      textStyle: {
        color: Palette.red,
      },
    },
  ].filter(({ condition = true }) => condition);

  const onChangePicture = async () => {
    try {
      setIsLoading(true);

      let result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.Images,
        allowsEditing: true,
        aspect: [4, 4],
        quality: 1,
      });

      if (result?.assets?.[0]?.uri) {
        const { resultURI = null } = await uploadFileToFirebase({
          uri: result?.assets?.[0]?.uri,
          path: `users/${currentUID}/profilePicture.png`,
        });

        if (resultURI) {
          await usersRef.doc(currentUID).update({
            profilePictureURL: resultURI,
          });

          await firebase.auth().currentUser.updateProfile({
            photoURL: resultURI,
          });

          setTooltip({
            type: "success",
            text: "Photo de profil mise à jour",
          });
        } else {
          throw new Error("Erreur changement photo de profil");
        }
      }
    } catch (error) {
      console.log(error);

      setTooltip({
        type: "error",
        text: error.message,
      });
    } finally {
      setIsLoading(false);
    }
  };

  const onUpdateValue = async ({
    key,
    value = null,
    currentPassword = null,
  }) => {
    try {
      setIsLoading(true);
      const user = firebase.auth().currentUser;

      const reauthenticateUser = async () => {
        try {
          const credential = firebase.auth.EmailAuthProvider.credential(
            user?.email,
            currentPassword
          );

          await user.reauthenticateWithCredential(credential);
        } catch (error) {
          throw new Error("Erreur authentification");
        }
      };

      // Validate input except for booleans where false is allowed
      const isInvalidString =
        typeof value === "string" && value.trim().length === 0;
      const isNullish = value === null || value === undefined;
      if (isNullish || isInvalidString) {
        throw new Error("Vérifiez les informations saisies");
      }

      if (key === "name") {
        await user.updateProfile({
          displayName: value,
        });
      }

      if (["email", "password"].includes(key)) {
        await reauthenticateUser();

        if (key === "email") {
          try {
            await user.updateEmail(value);
          } catch (e) {
            throw new Error("Erreur changement email");
          }
        }

        if (key === "password") {
          try {
            await user.updatePassword(value);
          } catch (e) {
            throw new Error("Erreur changement mot de passe");
          }
        }
      }

      if (key !== "password") {
        await usersRef.doc(currentUID).update({
          [key]: value,
        });
      }

      setTooltip({
        type: "success",
        text: "Modifications enregistrées",
      });
    } catch (error) {
      console.log(error);

      setTooltip({
        type: "error",
        text: error.message,
      });
    } finally {
      setIsLoading(false);
    }
  };

  const onDeleteUserAccount = async () => {
    alert(
      "Êtes-vous sûr?",
      "La suppression de votre compte entraînera la suppression de toutes les données liées.",
      [
        {
          text: "Annuler",
          onPress: () => {},
          style: "cancel",
        },
        {
          text: "Confirmer",
          onPress: async () => {
            try {
              setIsLoading(true);

              await firebase
                .functions()
                .httpsCallable("users-deleteUserAccount")();

              await onSignOut();

              setTooltip({
                type: "success",
                text: "Compte supprimé avec succès!",
              });

              navigation.reset({
                index: 0,
                routes: [
                  {
                    name: Routes.Login,
                  },
                ],
              });
            } catch (error) {
              setTooltip({
                type: "error",
                text: error.message,
              });
            } finally {
              setIsLoading(false);
            }
          },
          style: "confirm",
        },
      ],
      { cancelable: false }
    );
  };

  return (
    <Page headerType="NAVIGATE" title={"Paramètres du compte"} scrollEnabled>
      <Pressable
        onPress={onChangePicture}
        style={[Style.containerCenter, { marginBottom: gutters }]}
      >
        <Avatar
          name={currentUserData?.name}
          url={currentUserData?.profilePictureURL || null}
          forceRawImage
          size={responsiveWidth(30)}
          containerStyle={{
            marginBottom: gutters / 2,
            ...Style.defaultShadows,
          }}
        />
        <Text
          style={Fonts({
            type: "section",
            style: { color: Palette.primary, textDecorationLine: "underline" },
          })}
        >
          Modifier
        </Text>
      </Pressable>

      {settingsList.map((setting) => {
        const { title, key, value, type } = setting;

        return (
          <InputRow
            key={key}
            itemKey={key}
            value={value}
            type={type}
            title={title}
            onUpdateValue={onUpdateValue}
          />
        );
      })}

      <ItemRowList
        title={"Gérer mon abonnement"}
        action={() => {}}
        containerStyle={{}}
      />

      {destructiveSettingsList.map((setting, index) => (
        <ItemRowList key={index} {...setting} containerStyle={{}} />
      ))}
    </Page>
  );
};
