import {Text, TouchableOpacity, View} from "react-native-ui-lib";
import React, {useEffect, useState} from "react";
import {useToDosContext} from "@/contexts/ToDosContext";
import ToDoItem from "./ToDoItem";
import {addDays, format, isToday, isTomorrow, isWithinInterval,} from "date-fns";
import {AntDesign} from "@expo/vector-icons";
import {IToDo} from "@/hooks/firebase/types/todoData";
import DropdownIcon from "@/assets/svgs/DropdownIcon";
import {Dropdown} from "react-native-element-dropdown";
import {ProfileType, useAuthContext} from "@/contexts/AuthContext";
import {ActivityIndicator, Dimensions, StyleSheet} from "react-native";
import {UserProfile} from "@/hooks/firebase/types/profileTypes";

const FILTER_OPTIONS = {
    ME: "Me",
    EVERYONE: "Everyone"
};

const groupToDosByDate = (toDos: IToDo[]) => {
  let sortedTodos = toDos.sort((a, b) => {
    const dateA = a.date === null ? new Date() : a.date;
    const dateB = b.date === null ? new Date() : b.date;
    return dateA - dateB;
  });

  return sortedTodos.reduce(
    (groups, toDo) => {
      let dateKey;
      let subDateKey;

      const isNext7Days = (date: Date) => {
        const today = new Date();
        return isWithinInterval(date, { start: today, end: addDays(today, 7) });
      };

      const isNext30Days = (date: Date) => {
        const today = new Date();
        return isWithinInterval(date, {
          start: today,
          end: addDays(today, 30),
        });
      };

      const isOverdue = (date: Date) => {
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        return date < today;
      };
      
      if (isOverdue(toDo.date) && !toDo.done) {
        dateKey = "Overdue";
      } else if (toDo.date === null || isToday(toDo.date)) {
        dateKey = "Today";
      } else if (isTomorrow(toDo.date)) {
        dateKey = "Tomorrow";
      } else if (isNext7Days(toDo.date)) {
        dateKey = "Next 7 Days";
      } else if (isNext30Days(toDo.date)) {
        dateKey = "Next 30 Days";
        subDateKey = format(toDo.date, "MMM d");
      } else {
        dateKey = "Later";
        subDateKey = format(toDo.date, "MMM d, yyyy");
      }

      if (!groups[dateKey]) {
        groups[dateKey] = {
          items: [],
          subgroups: {},
        };
      }

      if ((dateKey === "Next 30 Days" || dateKey === "Later") && subDateKey) {
        if (!groups[dateKey].subgroups[subDateKey]) {
          groups[dateKey].subgroups[subDateKey] = [];
        }
        groups[dateKey].subgroups[subDateKey].push(toDo);
      } else {
        groups[dateKey].items.push(toDo);
      }

      return groups;
    },
    {} as {
      [key: string]: {
        items: IToDo[];
        subgroups: { [key: string]: IToDo[] };
      };
    }
  );
};

const resolveFilterOptions = (members, user) => {

    let options = [];
    members?.forEach((member) => {
        let label = member?.firstName;
        if (member.uid === user?.uid) {
            label = FILTER_OPTIONS.ME;
        }

        if (member.userType !== ProfileType.FAMILY_DEVICE) {
         options.push({value: member?.uid, label: label});
        }
    });
    options.push({value: FILTER_OPTIONS.EVERYONE, label: FILTER_OPTIONS.EVERYONE})

    return options;
}

const ToDosList = ({ isSettings, members }: { isSettings?: boolean, members?: Array<UserProfile> }) => {
  const { toDos } = useToDosContext();
  const [localTodos, setLocalTodos] = useState([]);

  useEffect(() => {
      setLocalTodos(toDos);
  }, [toDos]);

  const [groupedToDos, setGroupedToDos] = useState([]);
  const { user } = useAuthContext()

  const [expandedGroups, setExpandedGroups] = useState<{
    [key: string]: boolean;
  }>({});

  const [expandNoDate, setExpandNoDate] = useState<boolean>(true);
  const [selectedFilter, setSelectedFilter] = useState(null);
  const [filterOptions, setFilterOptions] = useState([]);

  useEffect(() => {
      let options = resolveFilterOptions(members, user);
      setFilterOptions(options);

      let selectedOption = options?.find((option) => option.value === user?.uid);
      setSelectedFilter(selectedOption);
  }, [JSON.stringify(members)]);

  useEffect(() => {
      if (localTodos && selectedFilter) {
          let resolvedGroupedTodos;
          if (selectedFilter?.value === FILTER_OPTIONS.EVERYONE) {
              let filtered = localTodos?.filter((todo) =>
                  todo.assignees?.some(assigneeId =>
                      members.some(member => member.uid === assigneeId)
                  )
              );

              resolvedGroupedTodos = groupToDosByDate(filtered ?? []);
          } else {
              let filtered = localTodos?.filter((todo) => todo.assignees?.includes(selectedFilter.value)) || [];

              resolvedGroupedTodos = groupToDosByDate(filtered || []);
          }
          setGroupedToDos(resolvedGroupedTodos || []);
      }
  }, [selectedFilter, JSON.stringify(localTodos)]);

  const toggleExpand = (dateKey: string) => {
    setExpandedGroups((prev) => ({
      ...prev,
      [dateKey]: !prev[dateKey],
    }));
  };

  const noDateToDos = groupedToDos["No Date"]?.items || [];
  const datedToDos = Object.keys(groupedToDos)
  .filter((key) => key !== "No Date")
  .sort((a, b) => {
    const order = ["Overdue", "Today", "Tomorrow", "Next 7 Days", "Next 30 Days", "Later"];
    return order.indexOf(a) - order.indexOf(b);
  });

  const renderTodoGroup = (dateKey: string) => {
    const isExpanded = expandedGroups[dateKey] || false;

    if (dateKey === "Next 30 Days" || dateKey === "Later") {
      const subgroups = Object.entries(groupedToDos[dateKey].subgroups).sort(
        ([dateA], [dateB]) => {
          const dateAObj = new Date(dateA);
          const dateBObj = new Date(dateB);
          return dateAObj.getTime() - dateBObj.getTime();
        }
      );

      return (
        <View key={dateKey}>
          <TouchableOpacity
            onPress={() => toggleExpand(dateKey)}
            style={{
              flexDirection: "row",
              justifyContent: "space-between",
              alignItems: "center",
              paddingHorizontal: 0,
              marginBottom: 4,
              marginTop: 15,
            }}
          >
            <Text
              style={{
                fontFamily: "Manrope_700Bold",
                fontSize: 15,
                color: "#484848",
              }}
            >
              {dateKey}
            </Text>
            <AntDesign
              name={isExpanded ? "caretdown" : "caretright"}
              size={24}
              color="#fd1575"
            />
          </TouchableOpacity>

          {isExpanded &&
            subgroups.map(([subDate, items]) => {
              const sortedItems = [
                ...items.filter((toDo) => !toDo.done),
                ...items.filter((toDo) => toDo.done),
              ];

              return (
                <View key={subDate} marginT-15>
                  <View
                    style={{
                      marginBottom: 8,
                    }}
                  >
                    <Text
                      style={{
                        fontFamily: "Manrope_600SemiBold",
                        fontSize: 14,
                        color: "#919191",
                      }}
                    >
                      {subDate}
                    </Text>
                  </View>

                  {sortedItems.map((item) => (
                    <ToDoItem
                      isSettings={isSettings}
                      key={item.id}
                      item={item}
                      is7Days={false}
                      localTodos={localTodos}
                      setLocalTodos={setLocalTodos}
                    />
                  ))}
                </View>
              );
            })}
        </View>
      );
    }

    const sortedToDos = [
      ...groupedToDos[dateKey].items.filter((toDo) => !toDo.done),
      ...groupedToDos[dateKey].items.filter((toDo) => toDo.done),
    ];

    return (
      <View key={dateKey}>
        <TouchableOpacity
          onPress={() => toggleExpand(dateKey)}
          style={{
            flexDirection: "row",
            justifyContent: "space-between",
            alignItems: "center",
            paddingHorizontal: 0,
            marginBottom: 4,
            marginTop: 15,
          }}
        >
          <Text
            style={{
              fontFamily: "Manrope_700Bold",
              fontSize: 15,
              color: "#484848",
            }}
          >
            {dateKey}
          </Text>
          <AntDesign
            name={isExpanded ? "caretdown" : "caretright"}
            size={24}
            color="#fd1575"
          />
        </TouchableOpacity>

        {isExpanded &&
          sortedToDos.map((item) => (
            <ToDoItem
              isSettings={isSettings}
              key={item.id}
              item={item}
              is7Days={dateKey === "Next 7 Days"}
              localTodos={localTodos}
              setLocalTodos={setLocalTodos}
            />
          ))}
      </View>
    );
  };

  const containerHeight = Dimensions.get('screen').height;
  return (
    <View style={{ marginBottom: 110  }} >
        {!toDos &&
            <View style={styles.loaderContainer}>
                <ActivityIndicator size="large" color="blue" />
            </View>
        }
        <Dropdown
            style={{ marginBottom: 15 }}
            data={filterOptions}
            value={selectedFilter}
            placeholder="Filter todos"
            placeholderStyle={{
                color: "#a2a2a2",
                fontFamily: "Manrope_500Medium",
                fontSize: 13.2,
            }}
            labelField="label"
            valueField="value"
            iconColor="white"
            activeColor={"#fd1775"}
            containerStyle={styles.dropdownStyle}
            itemTextStyle={styles.itemText}
            itemContainerStyle={styles.itemStyle}
            selectedTextStyle={styles.selectedText}
            renderLeftIcon={() => (
                <DropdownIcon
                    style={{ marginRight: 8 }}
                />
            )}
            renderItem={(item, selected) => {
                return (
                  <View height={36.02} centerV>
                  <Text style={[
                      styles.itemText,
                      selected && { color: 'white' }
                  ]}>
                      {item.label}
                  </Text>
              </View>
                );
            }}
            onChange={(item) => {
              setSelectedFilter(item);
            }}
        />
      {noDateToDos.length > 0 && (
        <View key="No Date">
          <View row spread paddingH-19 marginB-12>
            <Text
              text70
              style={{
                fontWeight: "bold",
              }}
            >
              Unscheduled
            </Text>
            <AntDesign
              name={expandNoDate ? "caretdown" : "caretright"}
              size={24}
              color="#fd1575"
              onPress={() => {
                setExpandNoDate(!expandNoDate);
              }}
            />
          </View>
          {expandNoDate &&
            noDateToDos
              .sort((a, b) => Number(a.done) - Number(b.done))
              .map((item) => (
                <ToDoItem isSettings={isSettings} key={item.id} item={item} localTodos={localTodos} setLocalTodos={setLocalTodos} />
              ))}
        </View>
      )}

      {datedToDos.map(renderTodoGroup)}
    </View>
  );
};

const styles = StyleSheet.create({
    itemText: {
        fontFamily: "Manrope_400Regular",
        fontSize: 15.42,
        paddingLeft: 15,
    },
    selectedText: {
        fontFamily: "Manrope_500Medium",
        fontSize: 13.2,
        color: "#fd1775",
    },
    dropdownStyle: { borderRadius: 6.61, minHeight: 10, maxHeight: "100%", width: 187 },
    itemStyle: { padding: 0, margin: 0 },
    loaderContainer: {
        ...StyleSheet.absoluteFillObject,
        justifyContent: 'center',
        alignItems: 'center',
        zIndex: 999,
    },
});

export default ToDosList;
