import React, {useCallback, useEffect, useMemo, useState} from "react";
import {Calendar} from "react-native-big-calendar";
import {ActivityIndicator, StyleSheet, View, ViewStyle} from "react-native";
import {useGetEvents} from "@/hooks/firebase/useGetEvents";
import {useAtom, useSetAtom} from "jotai";
import {
    editVisibleAtom,
    eventForEditAtom,
    modeAtom,
    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";

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} = useGetEvents();
        const {profileData} = useAuthContext();
        const [selectedDate, setSelectedDate] = useAtom(selectedDateAtom);
        const [mode, setMode] = useAtom(modeAtom);

        const setEditVisible = useSetAtom(editVisibleAtom);
        const setEventForEdit = useSetAtom(eventForEditAtom);
        const setSelectedNewEndDate = useSetAtom(selectedNewEventDateAtom);

        const [offsetMinutes, setOffsetMinutes] = useState(getTotalMinutes());

        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 handleSwipeEnd = useCallback(
            (date: Date) => {
                setSelectedDate(date);
            },
            [setSelectedDate]
        );

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

        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]);

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

        // console.log(enrichedEvents, filteredEvents)

        return (
            <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: 15},
                        xl: {
                            fontFamily: "PlusJakartaSans_500Medium",
                            fontSize: 16,
                        },
                        moreLabel: {},
                        xs: {fontSize: 10},
                    },
                }}
                dayHeaderStyle={dateStyle}
                dayHeaderHighlightColor={"white"}
                showAdjacentMonths
                hourStyle={styles.hourStyle}
                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",
    },
    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",
    },
});
