import React, { useCallback, useEffect, useRef, useState } from "react";
import { StyleSheet, TouchableOpacity } from "react-native";
import { ScrollView } from "react-native-gesture-handler";
import * as ImagePicker from "expo-image-picker";
import {
  Button,
  Colors,
  DateTimePicker,
  Image,
  Picker,
  Text,
  TextField,
  View,
} from "react-native-ui-lib";
import Ionicons from "@expo/vector-icons/Ionicons";
import * as tz from "tzdata";
import * as Localization from "expo-localization";
import debounce from "debounce";
import { ProfileType, useAuthContext } from "@/contexts/AuthContext";
import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData";
import { useChangeProfilePicture } from "@/hooks/firebase/useChangeProfilePicture";
import { colorMap } from "@/constants/colorMap";
import DeleteProfileDialogs from "../user_components/DeleteProfileDialogs";
import { AntDesign } from "@expo/vector-icons";
import { useDeleteUser } from "@/hooks/firebase/useDeleteUser";
import { useUpdateHouseholdName } from "@/hooks/firebase/useUpdateHouseholdName";
import { useGetHouseholdName } from "@/hooks/firebase/useGetHouseholdName";
import { useGetFamilyMembers } from "@/hooks/firebase/useGetFamilyMembers";
import { useDeleteFamily } from "@/hooks/firebase/useDeleteFamily";

const MyProfile = () => {
  const { user, profileData } = useAuthContext();
  const { data: familyMembers } = useGetFamilyMembers();
  const [takenColors, setTakenColors] = useState<string[]>([]);
  const { mutate: deleteFamily, isLoading } = useDeleteFamily();

  const { data: hhName, refetch: refetchHHName } = useGetHouseholdName(
    profileData.familyId
  );
  const [householdName, setHouseholdName] = useState<string>("");
  const [timeZone, setTimeZone] = useState<string>(
    profileData?.timeZone! ?? Localization.getCalendars()[0].timeZone
  );
  const [lastName, setLastName] = useState<string>(profileData?.lastName || "");
  const [firstName, setFirstName] = useState<string>(
    profileData?.firstName || ""
  );
  const [profileImage, setProfileImage] = useState<
    string | ImagePicker.ImagePickerAsset | null
  >(profileData?.pfp || null);

  const [selectedColor, setSelectedColor] = useState<string>(
    profileData?.eventColor ?? colorMap.pink
  );
  const [previousSelectedColor, setPreviousSelectedColor] = useState<string>(
    profileData?.eventColor ?? colorMap.pink
  );
  const [birthday, setBirthday] = useState<Date>(() => {
    if (profileData?.birthday) {
      if (profileData.birthday.toDate) {
        return profileData.birthday.toDate();
      }
      const date = new Date(profileData.birthday);
      return isNaN(date.getTime()) ? new Date() : date;
    }
    return new Date();
  });

  const [showDeleteDialog, setShowDeleteDialog] = useState<boolean>(false);

  const [isDeleteFamily, setIsDeleteFamily] = useState<boolean>(false);

  const handleHideDeleteDialog = () => {
    setShowDeleteDialog(false);
  };
  const handleShowDeleteDialog = (isFamily: boolean) => {
    setIsDeleteFamily(isFamily);
    setShowDeleteDialog(true);
  };

  const { mutateAsync: updateHouseholdName } = useUpdateHouseholdName();
  const { mutateAsync: updateUserData } = useUpdateUserData();
  const { mutateAsync: changeProfilePicture } = useChangeProfilePicture();
  const { mutateAsync: deleteAsync } = useDeleteUser();
  const isFirstRender = useRef(true);

  const handleUpdateUserData = async () => {
    await updateUserData({ newUserData: { firstName, lastName, timeZone } });
  };

  const handleUpdateHouseholdName = async () => {
    if (profileData?.familyId) {
      await updateHouseholdName({
        familyId: profileData.familyId,
        name: householdName,
      });
    }
  };

  const debouncedUserDataUpdate = debounce(handleUpdateUserData, 500);

  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false;
      return;
    }
    debouncedUserDataUpdate();
  }, [timeZone, lastName, firstName]);

  useEffect(() => {
    if (familyMembers) {
      const colors = familyMembers
        .filter((member) => member?.eventColor && member.uid !== user?.uid)
        .map((member) => member.eventColor!);
      setTakenColors(colors);
    }
  }, [familyMembers]);

  useEffect(() => {
    if (profileData) {
      setFirstName(profileData.firstName || "");
      setLastName(profileData.lastName || "");
      setTimeZone(
        profileData.timeZone || Localization.getCalendars()[0].timeZone!
      );
      if (profileData?.birthday) {
        if (profileData.birthday.toDate) {
          setBirthday(profileData.birthday.toDate());
        } else {
          const date = new Date(profileData.birthday);
          if (!isNaN(date.getTime())) {
            setBirthday(date);
          }
        }
      }
    }
  }, [profileData]);

  useEffect(() => {
    if (profileData?.familyId) {
      refetchHHName();
    }
  }, [profileData?.familyId]);

  useEffect(() => {
    setHouseholdName(hhName ?? "");
  }, [hhName]);

  const pickImage = async () => {
    const permissionResult =
      await ImagePicker.requestMediaLibraryPermissionsAsync();
    if (!permissionResult.granted) {
      alert("Permission to access camera roll is required!");
      return;
    }

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

    if (!result.canceled) {
      setProfileImage(result.assets[0].uri);
      await changeProfilePicture(result.assets[0]);
    }
  };

  const handleClearImage = async () => {
    await updateUserData({ newUserData: { pfp: null } });
    setProfileImage(null);
  };

  const pfpUri =
    profileImage && typeof profileImage === "object" && "uri" in profileImage
      ? profileImage.uri
      : profileImage;

  const handleChangeColor = (color: string) => {
    setPreviousSelectedColor(selectedColor);
    setSelectedColor(color);
    debouncedUpdateUserData(color);
  };

  const handleDeleteFamily = () => {
    if(profileData?.familyId){
      deleteFamily({familyId: profileData?.familyId}, {
        onSuccess: () => {

        },
        onError: (error) => {
          console.log("from delete fam:\n" + error);
        }
      })
    }
  }

  const debouncedUpdateUserData = useCallback(
    debounce(async (color: string) => {
      try {
        await updateUserData({
          newUserData: {
            eventColor: color,
          },
        });
      } catch (error) {
        console.error("Failed to update color:", error);
        setSelectedColor(previousSelectedColor);
      }
    }, 500),
    []
  );

  return (
    <ScrollView style={{ paddingBottom: 20, flex: 1 }}>
      <View style={styles.card}>
        <Text style={styles.subTit}>Your Profile</Text>
        <View row spread paddingH-15 centerV marginV-15>
          <TouchableOpacity onPress={pickImage}>
            {pfpUri ? (
              <Image
                key={pfpUri}
                style={[
                  styles.pfp,
                  (profileData?.eventColor && {
                    borderWidth: 2,
                    borderColor: profileData.eventColor,
                  }) ||
                    undefined,
                ]}
                source={pfpUri ? { uri: pfpUri } : null}
              />
            ) : (
              <View
                center
                style={{
                  aspectRatio: 1,
                  width: 65.54,
                  backgroundColor: profileData?.eventColor ?? colorMap.pink,
                  borderRadius: 20,
                }}
              >
                <Text style={styles.pfpTxt}>
                  {profileData?.firstName?.at(0)}
                  {profileData?.lastName?.at(0)}
                </Text>
              </View>
            )}
          </TouchableOpacity>

          <TouchableOpacity onPress={pickImage}>
            <Text style={styles.photoSet} color="#50be0c" onPress={pickImage}>
              {profileData?.pfp ? "Change" : "Add"} Photo
            </Text>
          </TouchableOpacity>

          {profileData?.pfp && (
            <TouchableOpacity onPress={handleClearImage}>
              <Text style={styles.photoSet}>Remove Photo</Text>
            </TouchableOpacity>
          )}
        </View>
        <View paddingH-15>
          {profileData?.userType == ProfileType.PARENT && (
            <>
              <Text text80 marginT-10 marginB-7 style={styles.label}>
                Household
              </Text>
              <TextField
                text70
                placeholder="Household name"
                style={styles.txtBox}
                value={householdName}
                onChangeText={async (value) => {
                  setHouseholdName(value);
                }}
                onEndEditing={() => handleUpdateHouseholdName()}
              />
            </>
          )}
          <Text text80 marginT-10 marginB-7 style={styles.label}>
            First name
          </Text>
          <TextField
            text70
            placeholder="First name"
            style={styles.txtBox}
            value={firstName}
            onChangeText={async (value) => {
              setFirstName(value);
            }}
          />
          <Text text80 marginT-10 marginB-7 style={styles.label}>
            Last name
          </Text>
          <TextField
            text70
            placeholder="Last name"
            style={styles.txtBox}
            value={lastName}
            onChangeText={async (value) => {
              setLastName(value);
            }}
          />
          <Text text80 marginT-10 marginB-7 style={styles.label}>
            Birthday
          </Text>
          <DateTimePicker
            style={styles.txtBox}
            mode="date"
            value={birthday}
            onChange={(date) => {
              if (date) {
                const validDate = new Date(date);
                if (!isNaN(validDate.getTime())) {
                  setBirthday(validDate);
                  updateUserData({
                    newUserData: {
                      birthday: validDate,
                    },
                  });
                }
              }
            }}
          />
          <Text text80 marginT-10 marginB-7 style={styles.label}>
            Email address
          </Text>
          <TextField
            editable={false}
            text70
            placeholder="Email address"
            value={user?.email?.toString()}
            style={styles.txtBox}
          />
        </View>
      </View>
      <View style={styles.card}>
        <Text style={styles.cardTitle} marginB-14>
          Color Preference
        </Text>
        <View row spread>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.pink)}
            disabled={takenColors.includes(colorMap.pink)}
          >
            <View
              style={[
                styles.colorBox,
                { opacity: takenColors.includes(colorMap.pink) ? 0.1 : 1 },
              ]}
              backgroundColor={colorMap.pink}
            >
              {selectedColor == colorMap.pink && (
                <AntDesign name="check" size={30} color="white" />
              )}
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.lightPink)}
            disabled={takenColors.includes(colorMap.lightPink)}
          >
            <View
              style={[
                styles.colorBox,
                { opacity: takenColors.includes(colorMap.lightPink) ? 0.1 : 1 },
              ]}
              backgroundColor={colorMap.lightPink}
            >
              {selectedColor == colorMap.lightPink && (
                <AntDesign name="check" size={30} color="black" />
              )}
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.orange)}
            disabled={takenColors.includes(colorMap.orange)}
          >
            <View
              style={[
                styles.colorBox,
                { opacity: takenColors.includes(colorMap.orange) ? 0.1 : 1 },
              ]}
              backgroundColor={colorMap.orange}
            >
              {selectedColor == colorMap.orange && (
                <AntDesign name="check" size={30} color="white" />
              )}
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.lightOrange)}
            disabled={takenColors.includes(colorMap.lightOrange)}
          >
            <View
              style={[
                styles.colorBox,
                {
                  opacity: takenColors.includes(colorMap.lightOrange) ? 0.1 : 1,
                },
              ]}
              backgroundColor={colorMap.lightOrange}
            >
              {selectedColor == colorMap.lightOrange && (
                <AntDesign name="check" size={30} color="black" />
              )}
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.green)}
            disabled={takenColors.includes(colorMap.green)}
          >
            <View
              style={[
                styles.colorBox,
                { opacity: takenColors.includes(colorMap.green) ? 0.1 : 1 },
              ]}
              backgroundColor={colorMap.green}
            >
              {selectedColor == colorMap.green && (
                <AntDesign name="check" size={30} color="white" />
              )}
            </View>
          </TouchableOpacity>
        </View>
        <View row spread marginT-10>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.lightGreen)}
            disabled={takenColors.includes(colorMap.lightGreen)}
          >
            <View
              style={[
                styles.colorBox,
                {
                  opacity: takenColors.includes(colorMap.lightGreen) ? 0.1 : 1,
                },
              ]}
              backgroundColor={colorMap.lightGreen}
            >
              {selectedColor == colorMap.lightGreen && (
                <AntDesign name="check" size={30} color="black" />
              )}
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.teal)}
            disabled={takenColors.includes(colorMap.teal)}
          >
            <View
              style={[
                styles.colorBox,
                { opacity: takenColors.includes(colorMap.teal) ? 0.1 : 1 },
              ]}
              backgroundColor={colorMap.teal}
            >
              {selectedColor == colorMap.teal && (
                <AntDesign name="check" size={30} color="white" />
              )}
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.lightTeal)}
            disabled={takenColors.includes(colorMap.lightTeal)}
          >
            <View
              style={[
                styles.colorBox,
                { opacity: takenColors.includes(colorMap.lightTeal) ? 0.1 : 1 },
              ]}
              backgroundColor={colorMap.lightTeal}
            >
              {selectedColor == colorMap.lightTeal && (
                <AntDesign name="check" size={30} color="black" />
              )}
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.purple)}
            disabled={takenColors.includes(colorMap.purple)}
          >
            <View
              style={[
                styles.colorBox,
                { opacity: takenColors.includes(colorMap.purple) ? 0.1 : 1 },
              ]}
              backgroundColor={colorMap.purple}
            >
              {selectedColor == colorMap.purple && (
                <AntDesign name="check" size={30} color="white" />
              )}
            </View>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => handleChangeColor(colorMap.lightPurple)}
            disabled={takenColors.includes(colorMap.lightPurple)}
          >
            <View
              style={[
                styles.colorBox,
                {
                  opacity: takenColors.includes(colorMap.lightPurple) ? 0.1 : 1,
                },
              ]}
              backgroundColor={colorMap.lightPurple}
            >
              {selectedColor == colorMap.lightPurple && (
                <AntDesign name="check" size={30} color="black" />
              )}
            </View>
          </TouchableOpacity>
        </View>
      </View>

      <View style={styles.card}>
        <Text style={styles.subTit}>Settings</Text>
        <Text style={styles.jakarta12}>Time Zone</Text>
        <View style={styles.viewPicker}>
          <Picker
            value={timeZone}
            onChange={(item) => setTimeZone(item as string)}
            showSearch
            floatingPlaceholder
            style={styles.inViewPicker}
            trailingAccessory={
              <View
                style={{
                  justifyContent: "center",
                  alignItems: "center",
                  height: "100%",
                  marginTop: -38,
                  paddingRight: 15,
                }}
              >
                <Ionicons
                  name={"chevron-down"}
                  style={{ alignSelf: "center" }}
                  size={20}
                  color={"#000000"}
                />
              </View>
            }
          >
            {timeZoneItems}
          </Picker>
        </View>
      </View>
      <TouchableOpacity
        onPress={() => handleShowDeleteDialog(false)}
        style={{ marginTop: 10, alignSelf: "center" }}
      >
        <Text
          style={{
            color: "#ff1637",
            fontFamily: "PlusJakartaSans_500Medium",
            fontSize: 15,
          }}
        >
          Delete Profile
        </Text>
      </TouchableOpacity>
      {profileData?.userType === ProfileType.PARENT && (
        <TouchableOpacity
          onPress={() => handleShowDeleteDialog(true)}
          style={{ marginTop: 20, alignSelf: "center" }}
        >
          <Text
            style={{
              color: "#ff1637",
              fontFamily: "PlusJakartaSans_500Medium",
              fontSize: 15,
            }}
          >
            Delete Family
          </Text>
        </TouchableOpacity>
      )}
      <DeleteProfileDialogs
        onFirstYes={() => {
          setShowDeleteDialog(false);
        }}
        visible={showDeleteDialog}
        onDismiss={handleHideDeleteDialog}
        onConfirm={() => {
          if(isDeleteFamily)
            //deletes family
            handleDeleteFamily();
          else
            {
              //deletes profile
              deleteAsync({});
            }
        }}
        isDeleteFamily={isDeleteFamily}
        householdName={householdName}
      />
    </ScrollView>
  );
};

const timeZoneItems = Object.keys(tz.zones)
  .sort()
  .map((zone) => (
    <Picker.Item
      key={zone}
      label={zone.replace("/", " / ").replace("_", " ")}
      value={zone}
    />
  ));

const styles = StyleSheet.create({
  cardTitle: {
    fontFamily: "Manrope_500Medium",
    fontSize: 15,
  },
  colorBox: {
    aspectRatio: 1,
    justifyContent: "center",
    alignItems: "center",
    width: 51,
    borderRadius: 12,
  },
  card: {
    marginVertical: 15,
    backgroundColor: "white",
    width: "100%",
    borderRadius: 12,
    paddingHorizontal: 20,
    paddingVertical: 21,
  },
  pfpTxt: {
    fontFamily: "Manrope_500Medium",
    fontSize: 30,
    color: "white",
  },
  pfp: {
    aspectRatio: 1,
    width: 65.54,
    backgroundColor: "gray",
    borderRadius: 20,
  },
  txtBox: {
    backgroundColor: "#fafafa",
    borderRadius: 50,
    borderWidth: 2,
    borderColor: "#cecece",
    padding: 15,
    height: 45,
    fontFamily: "PlusJakartaSans_500Medium",
    fontSize: 13,
  },
  subTit: {
    fontFamily: "Manrope_500Medium",
    fontSize: 15,
  },
  label: {
    fontFamily: "PlusJakartaSans_500Medium",
    fontSize: 12,
    color: "#a1a1a1",
  },
  photoSet: {
    fontFamily: "PlusJakartaSans_500Medium",
    fontSize: 13.07,
  },
  jakarta12: {
    paddingVertical: 10,
    fontFamily: "PlusJakartaSans_500Medium",
    fontSize: 12,
    color: "#a1a1a1",
  },
  viewPicker: {
    borderRadius: 50,
    backgroundColor: Colors.grey80,
    marginBottom: 16,
    borderColor: Colors.grey50,
    borderWidth: 1,
    marginTop: 0,
    height: 40,
    zIndex: 10,
  },
  inViewPicker: {
    borderRadius: 50,
    paddingVertical: 12,
    paddingHorizontal: 16,
    marginBottom: 16,
    marginTop: -20,
    height: 40,
    zIndex: 10,
  },
});

export default MyProfile;
