import {useQuery, useQueryClient} from "react-query";
import firestore from "@react-native-firebase/firestore";
import {useAuthContext} from "@/contexts/AuthContext";
import {useAtomValue} from "jotai";
import {isFamilyViewAtom} from "@/components/pages/calendar/atoms";
import {colorMap} from "@/constants/colorMap";
import {uuidv4} from "@firebase/util";
import {useEffect} from "react";

const createEventHash = (event: any): string => {
    const str = `${event.startDate?.seconds || ''}-${event.endDate?.seconds || ''}-${
        event.title || ''
    }-${event.location || ''}-${event.allDay ? 'true' : 'false'}`;

    let hash = 0;
    for (let i = 0; i < str.length; i++) {
        const char = str.charCodeAt(i);
        hash = ((hash << 5) - hash) + char;
        hash = hash & hash;
    }
    return hash.toString(36);
};


export const useGetEvents = () => {
    const {user, profileData} = useAuthContext();
    const isFamilyView = useAtomValue(isFamilyViewAtom);
    const queryClient = useQueryClient();

    useEffect(() => {
        if (!profileData?.familyId) {
            console.log('[SYNC] No family ID available, skipping listener setup');
            return;
        }

        console.log('[SYNC] Setting up sync listener', {
            familyId: profileData.familyId,
            userId: user?.uid,
            isFamilyView
        });

        const unsubscribe = firestore()
            .collection('Households')
            .where("familyId", "==", profileData.familyId)
            .onSnapshot((snapshot) => {
                console.log('[SYNC] Snapshot received', {
                    empty: snapshot.empty,
                    size: snapshot.size,
                    changes: snapshot.docChanges().length
                });

                snapshot.docChanges().forEach((change) => {
                    console.log('[SYNC] Processing change', {
                        type: change.type,
                        docId: change.doc.id,
                        newData: change.doc.data()
                    });

                    if (change.type === 'modified') {
                        const data = change.doc.data();
                        console.log('[SYNC] Modified document data', {
                            hasLastSyncTimestamp: !!data?.lastSyncTimestamp,
                            hasLastUpdateTimestamp: !!data?.lastUpdateTimestamp,
                            allFields: Object.keys(data || {})
                        });

                        if (data?.lastSyncTimestamp) {
                            console.log('[SYNC] Sync timestamp change detected', {
                                timestamp: data.lastSyncTimestamp.toDate(),
                                householdId: change.doc.id,
                                queryKey: ["events", user?.uid, isFamilyView]
                            });

                            console.log('[SYNC] Invalidating queries...');
                            queryClient.invalidateQueries(["events", user?.uid, isFamilyView]);
                            console.log('[SYNC] Queries invalidated');
                        } else {
                            console.log('[SYNC] Modified document without lastSyncTimestamp', {
                                householdId: change.doc.id
                            });
                        }
                    }
                });
            }, (error) => {
                console.error('[SYNC] Listener error:', {
                    message: error.message,
                    code: error.code,
                    stack: error.stack
                });
            });

        console.log('[SYNC] Listener setup complete');

        return () => {
            console.log('[SYNC] Cleaning up sync listener', {
                familyId: profileData.familyId,
                userId: user?.uid
            });
            unsubscribe();
        };
    }, [profileData?.familyId, user?.uid, isFamilyView, queryClient]);


    return useQuery({
        queryKey: ["events", user?.uid, isFamilyView],
        queryFn: async () => {
            console.log(`Fetching events - Family View: ${isFamilyView}, User: ${user?.uid}`);

            const db = firestore();
            const userId = user?.uid;
            const familyId = profileData?.familyId;
            let allEvents = [];

            if (isFamilyView) {
                const [publicFamilyEvents, privateCreatorEvents, privateAttendeeEvents, userAttendeeEvents, userCreatorEvents] = await Promise.all([
                    // Public family events
                    db.collection("Events")
                        .where("familyId", "==", familyId)
                        .where("private", "==", false)
                        .get(),

                    // Private events user created
                    db.collection("Events")
                        .where("familyId", "==", familyId)
                        .where("private", "==", true)
                        .where("creatorId", "==", userId)
                        .get(),

                    // Private events user is attending
                    db.collection("Events")
                        .where("private", "==", true)
                        .where("attendees", "array-contains", userId)
                        .get(),

                    // All events where user is attendee
                    db.collection("Events")
                        .where("attendees", "array-contains", userId)
                        .get(),

                    // ALL events where user is creator (regardless of attendees)
                    db.collection("Events")
                        .where("creatorId", "==", userId)
                        .get()
                ]);

                console.log(`Found ${publicFamilyEvents.size} public events, ${privateCreatorEvents.size} private creator events, ${privateAttendeeEvents.size} private attendee events, ${userAttendeeEvents.size} user attendee events, ${userCreatorEvents.size} user creator events`);

                allEvents = [
                    ...publicFamilyEvents.docs.map(doc => ({...doc.data(), id: doc.id})),
                    ...privateCreatorEvents.docs.map(doc => ({...doc.data(), id: doc.id})),
                    ...privateAttendeeEvents.docs.map(doc => ({...doc.data(), id: doc.id})),
                    ...userAttendeeEvents.docs.map(doc => ({...doc.data(), id: doc.id})),
                    ...userCreatorEvents.docs.map(doc => ({...doc.data(), id: doc.id}))
                ];
            } else {
                const [creatorEvents, attendeeEvents] = await Promise.all([
                    db.collection("Events")
                        .where("creatorId", "==", userId)
                        .get(),
                    db.collection("Events")
                        .where("attendees", "array-contains", userId)
                        .get()
                ]);

                console.log(`Found ${creatorEvents.size} creator events, ${attendeeEvents.size} attendee events`);

                allEvents = [
                    ...creatorEvents.docs.map(doc => ({...doc.data(), id: doc.id})),
                    ...attendeeEvents.docs.map(doc => ({...doc.data(), id: doc.id}))
                ];
            }

            const uniqueEventsMap = new Map();
            const processedHashes = new Set();

            allEvents.forEach(event => {
                    const eventHash = createEventHash(event);

            console.log(`Processing ${uniqueEventsMap.size} unique events`);

                const processedEvent = {
                    ...event,
                    id: event.id || uuidv4(),
                    creatorId: event.creatorId || userId
                };

                // Only add the event if we haven't seen this hash before
                if (!processedHashes.has(eventHash)) {
                    processedHashes.add(eventHash);
                    uniqueEventsMap.set(processedEvent.id, processedEvent);
                } else {
                    console.log(`Duplicate event detected and skipped using hash: ${eventHash}`);
                }
            });

            console.log(`Processing ${uniqueEventsMap.size} unique events after deduplication`);

            const processedEvents = await Promise.all(
                Array.from(uniqueEventsMap.values()).map(async (event) => {
                    const profileSnapshot = await db
                        .collection("Profiles")
                        .doc(event.creatorId)
                        .get();

                    const profileData = profileSnapshot.data();
                    const eventColor = profileData?.eventColor || colorMap.pink;

                    return {
                        ...event,
                        start: event.allDay
                            ? new Date(new Date(event.startDate.seconds * 1000).setHours(0, 0, 0, 0))
                            : new Date(event.startDate.seconds * 1000),
                        end: event.allDay
                            ? new Date(new Date(event.endDate.seconds * 1000).setHours(0, 0, 0, 0))
                            : new Date(event.endDate.seconds * 1000),
                        hideHours: event.allDay,
                        eventColor,
                        notes: event.notes,
                    };
                })
            );


            console.log(`Events processing completed, returning ${processedEvents.length} events`);
            return processedEvents;
        },
        staleTime: 5 * 60 * 1000,
        cacheTime: 30 * 60 * 1000,
        keepPreviousData: true,
        onError: (error) => {
            console.error('Error fetching events:', error);
        }
    });
};
