import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Calendar } from "react-native-big-calendar";
import { ActivityIndicator, ScrollView, StyleSheet, View, ViewStyle } from "react-native";
import { useGetEvents } from "@/hooks/firebase/useGetEvents";
import { useAtom, useAtomValue, useSetAtom } from "jotai";
import {
  editVisibleAtom,
  eventForEditAtom,
  isAllDayAtom,
  modeAtom,
  refreshTriggerAtom,
  selectedDateAtom,
  selectedNewEventDateAtom,
} from "@/components/pages/calendar/atoms";
import { useAuthContext } from "@/contexts/AuthContext";
import { CalendarEvent } from "@/components/pages/calendar/interfaces";
import { Text } from "react-native-ui-lib";
import { addDays, compareAsc, isWithinInterval, subDays } from "date-fns";
import {useCalSync} from "@/hooks/useCalSync";
import {useSyncEvents} from "@/hooks/useSyncOnScroll";

interface EventCalendarProps {
  calendarHeight: number;
  // WAS USED FOR SCROLLABLE CALENDARS, PERFORMANCE WAS NOT OPTIMAL
  calendarWidth: number;
}

const getTotalMinutes = () => {
  const date = new Date();
  return Math.abs(date.getUTCHours() * 60 + date.getUTCMinutes() - 200);
};

export const EventCalendar: React.FC<EventCalendarProps> = React.memo(
  ({ calendarHeight }) => {
    const { data: events, isLoading, refetch } = useGetEvents();
    const { profileData } = useAuthContext();
    const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom);
    const [mode, setMode] = useAtom(modeAtom);

    const setEditVisible = useSetAtom(editVisibleAtom);
    const [isAllDay, setIsAllDay] = useAtom(isAllDayAtom);
    const setEventForEdit = useSetAtom(eventForEditAtom);
    const shouldRefresh = useAtomValue(refreshTriggerAtom);
    const setSelectedNewEndDate = useSetAtom(selectedNewEventDateAtom);

    const {isSyncing} = useSyncEvents()
    const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes());
    useCalSync()

    const todaysDate = new Date();

    const handlePressEvent = useCallback(
      (event: CalendarEvent) => {
        if (mode === "day" || mode === "week") {
          setEditVisible(true);
          // console.log({event});
                    setEventForEdit(event);
                } else {
                    setMode("day");
                    setSelectedDate(event.start);
                }
            },
            [setEditVisible, setEventForEdit, mode]
        );

    const handlePressCell = useCallback(
      (date: Date) => {
        if (mode === "day" || mode === "week") {
          setSelectedNewEndDate(date);
        } else {
          setMode("day");
          setSelectedDate(date);
        }
      },
      [mode, setSelectedNewEndDate, setSelectedDate]
    );

    const handlePressDayHeader = useCallback(
      (date: Date) => {
        if (mode === "day") {
          setIsAllDay(true);
          setSelectedNewEndDate(date);
          setEditVisible(true);
        }
        if (mode === 'week')
        {
          setSelectedDate(date)

          setMode("day")
        }
      },
      [mode, setSelectedNewEndDate]
    );

    const handleSwipeEnd = useCallback(
      (date: Date) => {
        setSelectedDate(date);
      },
      [setSelectedDate]
    );

    const memoizedEventCellStyle = useCallback(
      (event: CalendarEvent) => ({ backgroundColor: event.eventColor , fontSize: 14}),
      []
    );

    const memoizedWeekStartsOn = useMemo(
      () => (profileData?.firstDayOfWeek === "Mondays" ? 1 : 0),
      [profileData]
    );

    // console.log({memoizedWeekStartsOn, profileData: profileData?.firstDayOfWeek,

    const isSameDate = useCallback((date1: Date, date2: Date) => {
      return (
        date1.getDate() === date2.getDate() &&
        date1.getMonth() === date2.getMonth() &&
        date1.getFullYear() === date2.getFullYear()
      );
    }, []);

    const dayHeaderColor = useMemo(() => {
      return isSameDate(todaysDate, selectedDate) ? "white" : "#4d4d4d";
    }, [selectedDate, mode]);

    const dateStyle = useMemo(() => {
      if (mode === "week") return undefined;
      return isSameDate(todaysDate, selectedDate) && mode === "day"
        ? styles.dayHeader
        : styles.otherDayHeader;
    }, [selectedDate, mode]);

    const memoizedHeaderContentStyle = useMemo(() => {
      if (mode === "day") {
        return styles.dayModeHeader;
      } else if (mode === "week") {
        return styles.weekModeHeader;
      } else if (mode === "month") {
        return styles.monthModeHeader;
      } else {
        return {};
      }
    }, [mode]);

    const { enrichedEvents, filteredEvents } = useMemo(() => {
      const startTime = Date.now(); // Start timer

      const startOffset = mode === "month" ? 40 : mode === "week" ? 10 : 1;
      const endOffset = mode === "month" ? 40 : mode === "week" ? 10 : 1;

      const filteredEvents =
        events?.filter(
          (event) =>
            event.start &&
            event.end &&
            isWithinInterval(event.start, {
              start: subDays(selectedDate, startOffset),
              end: addDays(selectedDate, endOffset),
            }) &&
            isWithinInterval(event.end, {
              start: subDays(selectedDate, startOffset),
              end: addDays(selectedDate, endOffset),
            })
        ) ?? [];

      const enrichedEvents = filteredEvents.reduce((acc, event) => {
        const dateKey = event.start.toISOString().split("T")[0];
        acc[dateKey] = acc[dateKey] || [];
        acc[dateKey].push({
          ...event,
          overlapPosition: false,
          overlapCount: 0,
        });

        acc[dateKey].sort((a, b) => compareAsc(a.start, b.start));

        return acc;
      }, {} as Record<string, CalendarEvent[]>);

      const endTime = Date.now();
      // console.log("memoizedEvents computation time:", endTime - startTime, "ms");

      return { enrichedEvents, filteredEvents };
    }, [events, selectedDate, mode]);

    const renderCustomDateForMonth = (date: Date) => {
      const circleStyle = useMemo<ViewStyle>(
        () => ({
          width: 30,
          height: 30,
          justifyContent: "center",
          alignItems: "center",
          borderRadius: 15,
        }),
        []
      );

      const defaultStyle = useMemo<ViewStyle>(
        () => ({
          ...circleStyle,
        }),
        [circleStyle]
      );

      const currentDateStyle = useMemo<ViewStyle>(
        () => ({
          ...circleStyle,
          backgroundColor: "#4184f2",
        }),
        [circleStyle]
      );

      const renderDate = useCallback(
        (date: Date) => {
          const isCurrentDate = isSameDate(todaysDate, date);
          const appliedStyle = isCurrentDate ? currentDateStyle : defaultStyle;

          return (
            <View style={{ alignItems: "center" }}>
              <View style={appliedStyle}>
                <Text style={{ color: isCurrentDate ? "white" : "black" }}>
                  {date.getDate()}
                </Text>
              </View>
            </View>
          );
        },
        [todaysDate, currentDateStyle, defaultStyle] // dependencies
      );

      return renderDate(date);
    };

    useEffect(() => {
      setOffsetMinutes(getTotalMinutes());
    }, [events, mode]);

    useEffect(() => {
      refetch()
      .then(() => {
        console.log('✅ Events refreshed successfully');
      })
      .catch((error) => {
        console.error('❌ Events refresh failed:', error);
      });
    }, [shouldRefresh, refetch])
    

    if (isLoading) {
      return (
        <View style={styles.loadingContainer}>
          {isSyncing && <Text>Syncing...</Text>}
                    <ActivityIndicator size="large" color="#0000ff"/>
                </View>
            );
        }

    // console.log(enrichedEvents, filteredEvents)

    return (
      <>
                {isSyncing && (
                    <View style={styles.loadingContainer}>
                        {isSyncing && <Text>Syncing...</Text>}
                        <ActivityIndicator size="large" color="#0000ff"/>
                    </View>
                )}
                <Calendar
                    bodyContainerStyle={styles.calHeader}
                    swipeEnabled
                    mode={mode}
                    // enableEnrichedEvents={true}
                    sortedMonthView
                    // enrichedEventsByDate={enrichedEvents}
                    events={filteredEvents}
                    eventCellStyle={memoizedEventCellStyle}
                    onPressEvent={handlePressEvent}
                    weekStartsOn={memoizedWeekStartsOn}
                    height={calendarHeight}
                    activeDate={todaysDate}
                    date={selectedDate}
                    onPressCell={handlePressCell}
                    headerContentStyle={memoizedHeaderContentStyle}
                    onSwipeEnd={handleSwipeEnd}
                    scrollOffsetMinutes={offsetMinutes}
                    theme={{
                        palette: {
                            nowIndicator: profileData?.eventColor || "#fd1575",
                            gray: {
                                "100": "#e8eaed",
                                "200": "#e8eaed",
                                "500": "#b7b7b7",
                                "800": "#919191",
                            },
                        },
                        typography: {
                            fontFamily: "PlusJakartaSans_500Medium",
                            sm: {fontFamily: "Manrope_600SemiBold", fontSize: 8},
                            xl: {
                                fontFamily: "PlusJakartaSans_500Medium",
                                fontSize: 14,
                            },
                            moreLabel: {},
                            xs: {fontSize: 10},
                        },
                    }}
                    dayHeaderStyle={dateStyle}
                    dayHeaderHighlightColor={"white"}
                    showAdjacentMonths
                    headerContainerStyle={mode !== "month" ? {
                        overflow:"hidden",
                    } : {}}
                    hourStyle={styles.hourStyle}
            onPressDateHeader={handlePressDayHeader}
                    ampm
                    // renderCustomDateForMonth={renderCustomDateForMonth}
                />
            </>

        );
    }
);

const styles = StyleSheet.create({
    segmentslblStyle: {
        fontSize: 12,
        fontFamily: "Manrope_600SemiBold",
    },
    calHeader: {
        borderWidth: 0,
    },
    dayModeHeader: {
        alignSelf: "flex-start",
        justifyContent: "space-between",
        alignContent: "center",
        width: 38,
        right: 42,
        height: 13,
    },
    weekModeHeader: {},
    monthModeHeader: {},
    loadingContainer: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        position: "absolute",
        width: "100%",
        height: "100%",
        zIndex: 100,
        backgroundColor: "rgba(255, 255, 255, 0.9)",
    },
    dayHeader: {
        backgroundColor: "#4184f2",
        aspectRatio: 1,
        borderRadius: 100,
        alignItems: "center",
        justifyContent: "center",
    },
    otherDayHeader: {
        backgroundColor: "transparent",
        color: "#919191",
        aspectRatio: 1,
        borderRadius: 100,
        alignItems: "center",
        justifyContent: "center",
    },
    hourStyle: {
        color: "#5f6368",
        fontSize: 12,
        fontFamily: "Manrope_500Medium",
    },
});
