import { View, Text, TouchableOpacity, Icon } from "react-native-ui-lib";
import React, {useEffect, useState} from "react";
import { useToDosContext } from "@/contexts/ToDosContext";
import {
  addDays,
  format,
  isToday,
  isTomorrow,
  isWithinInterval,
} from "date-fns";
import { AntDesign } from "@expo/vector-icons";
import { IToDo } from "@/hooks/firebase/types/todoData";
import ToDoItem from "../../todos/ToDoItem";
import { UserProfile } from "@/hooks/firebase/types/profileTypes";
import { ScrollView } from "react-native-gesture-handler";

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 filterToDosByUser = (toDos: IToDo[], uid: string | undefined) => {
  if (!uid) return [];
  return toDos.filter((todo) => todo.assignees?.includes(uid));
};

const SingleUserChoreList = ({ user }: { user: UserProfile }) => {
  const { toDos } = useToDosContext();
  const [localTodos, setLocalTodos] = useState([]);
  const [groupedToDos, setGroupedToDos] = useState([]);

  useEffect(() => {
      const userTodos = filterToDosByUser(toDos, user.uid);
      setLocalTodos(userTodos);
  }, [toDos, user]);

  useEffect(() => {
      const grouped = groupToDosByDate(localTodos);
      setGroupedToDos(grouped);
  }, [localTodos]);

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

  const [expandNoDate, setExpandNoDate] = useState<boolean>(true);

  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
                        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
              key={item.id}
              item={item}
              is7Days={dateKey === "Next 7 Days"}
              localTodos={localTodos}
              setLocalTodos={setLocalTodos}
            />
          ))}
      </View>
    );
  };

  return (
    <View
      marginT-10
      backgroundColor="#f9f8f7"
      style={{
        minHeight: 600,
        maxHeight: 600,
        borderRadius: 9.11,
        overflow: "hidden",
      }}
      width={355}
    >
      <ScrollView showsVerticalScrollIndicator={false}>
        <View paddingH-10 paddingB-90>
          {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 key={item.id} item={item} localTodos={localTodos} setLocalTodos={setLocalTodos} />)}
            </View>
          )}

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

export default SingleUserChoreList;
