import React, { useState, useEffect } from "react";
import { View, StyleSheet, Text, Modal, TextInput, ScrollView, Dimensions, Pressable, TouchableOpacity } from "react-native";
import axios from "axios";
import { format, parseISO } from "date-fns";
import ScheduleEditor from "./scheduleEditor";
import Animated, {
  SlideInDown,
  SlideOutDown,
  FadeIn,
  FadeOut,
} from 'react-native-reanimated';
import moment from "moment";
import Timetable from "react-native-calendar-timetable";
import Rectangle from "../common/rectanglev2";
import ButtonComp from "../common/Button";

const CALENDAR_WIDTH = 807;
const CALENDAR_HEIGHT = 670;

const AnimatedPressable = Animated.createAnimatedComponent(Pressable);


const EditSchedule = () => {
    // Set up the date range for Monday to Friday of the current week
    const [from] = React.useState(moment().startOf('week').add(1, 'days').toDate());
    const [till] = React.useState(moment().startOf('week').add(5, 'days').toDate());
    const [isOpen, setOpen] = useState(false);
    const [isAddingSchedule, setIsAddingSchedule] = useState(false);
    const [scheduleName, setScheduleName] = useState('');
    const [tempSchedules, setTempSchedules] = useState([]);
    const [currentSchedule, setCurrentSchedule] = useState( {
        id: 0,
        name: "Default Schedule",
        items: [
        {
          title: 'Monday',
          startDate: moment().startOf('week').add(1, 'days').hour(8).toDate(),
          endDate: moment().startOf('week').add(1, 'days').hour(10).toDate(),
        },
        {
          title: 'Tuesday',
          startDate: moment().startOf('week').add(2, 'days').hour(8).toDate(),
          endDate: moment().startOf('week').add(2, 'days').hour(10).toDate(),
        },
        {
          title: 'Wednesday',
          startDate: moment().startOf('week').add(3, 'days').hour(8).toDate(),
          endDate: moment().startOf('week').add(3, 'days').hour(10).toDate(),
        },
        {
          title: 'Thursday',
          startDate: moment().startOf('week').add(4, 'days').hour(8).toDate(),
          endDate: moment().startOf('week').add(4, 'days').hour(10).toDate(),
        },
        {
          title: 'Friday',
          startDate: moment().startOf('week').add(5, 'days').hour(8).toDate(),
          endDate: moment().startOf('week').add(5, 'days').hour(10).toDate(),
        },
      ]
    });

    const range = { from, till };
    // Set up the event data
    // useEffect(() => {
        // fetchSchedules();
    // }, []);
    const fetchSchedules = async () => {
        try {
            const response = await axios.get('http://localhost:3000/api/schedules');
            setAllSchedules(response.data);
        } catch (error) {
            console.error('Error fetching schedules:', error);
        }
    };

    const sendSchedulesToDatabase = async (schedules) => {
        try {
            const response = await axios.post('http://localhost:3000/api/update-schedules', allSchedules);
            console.log(response.data, 'schedules updated');
        } catch (error) {
            console.error('Error updating schedules:', error);
        }
    };
    // the data below will eventually be fetched from the database
    const [allSchedules, setAllSchedules] = React.useState([
        {
            id: 0,
            name: "Default Schedule",
            items: [
            {
              title: 'Monday',
              startDate: moment().startOf('week').add(1, 'days').hour(8).toDate(),
              endDate: moment().startOf('week').add(1, 'days').hour(10).toDate(),
            },
            {
              title: 'Tuesday',
              startDate: moment().startOf('week').add(2, 'days').hour(8).toDate(),
              endDate: moment().startOf('week').add(2, 'days').hour(10).toDate(),
            },
            {
              title: 'Wednesday',
              startDate: moment().startOf('week').add(3, 'days').hour(8).toDate(),
              endDate: moment().startOf('week').add(3, 'days').hour(10).toDate(),
            },
            {
              title: 'Thursday',
              startDate: moment().startOf('week').add(4, 'days').hour(8).toDate(),
              endDate: moment().startOf('week').add(4, 'days').hour(10).toDate(),
            },
            {
              title: 'Friday',
              startDate: moment().startOf('week').add(5, 'days').hour(8).toDate(),
              endDate: moment().startOf('week').add(5, 'days').hour(10).toDate(),
            },
          ]
        },
        // You can add more schedules here
      ]);

    // Combine allSchedules and tempSchedules
    const combinedSchedules = [...allSchedules, ...tempSchedules];

    const handleScheduleCreation = (selectedDays, startHour, startMinute, endHour, endMinute) => {
        const daysIndex = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"];
        console.log(selectedDays, 'selectedDays');
        const newItems = selectedDays.map((day) => {
            return {
                title: day,
                startDate: moment().startOf('week').add(daysIndex.indexOf(day) + 1, 'days').hour(startHour).minute(startMinute).toDate(),
                endDate: moment().startOf('week').add(daysIndex.indexOf(day) + 1, 'days').hour(endHour).minute(endMinute).toDate()
            };
        });

        setCurrentSchedule(prevSchedule => {
            const updatedItems = [...prevSchedule.items];
            newItems.forEach(newItem => {
                const index = updatedItems.findIndex(item => item.title === newItem.title);
                if (index !== -1) {
                    updatedItems[index] = newItem; // Update existing item
                } else {
                    updatedItems.push(newItem); // Add new item
                }
            });
            return { ...prevSchedule, items: updatedItems };
        });
        setTempSchedules(prevSchedules => {
            return prevSchedules.map(schedule => {
                if (schedule.id === currentSchedule.id) {
                    const updatedItems = [...schedule.items];
                    newItems.forEach(newItem => {
                        const index = updatedItems.findIndex(item => item.title === newItem.title);
                        if (index !== -1) {
                            updatedItems[index] = newItem; // Update existing item
                        } else {
                            updatedItems.push(newItem); // Add new item
                        }
                    });
                    return { ...schedule, items: updatedItems };
                }
                return schedule;
            });
        });
    };



    useEffect(() => {
        console.log('Current Schedule updateds:', currentSchedule);
    }, [currentSchedule]);

    useEffect(() => {
        console.log('Temp Schedules updated:', JSON.stringify(tempSchedules, null, 2));
    }, [tempSchedules]);



    const CustomHeader = ({ date }) => (
        <View style={styles.headerContainer}>
            <Text style={styles.headerText}>{moment(date).format('ddd')}</Text>
        </View>
    );

    const calculateDayIndex = (date) => {
        return moment(date).isoWeekday();
    };

    const addNewSchedule = () => {
        if (scheduleName.trim()) {
            const newSchedule = {
                id: allSchedules.length + tempSchedules.length,
                name: scheduleName,
                items: []
            };
            setTempSchedules(prevTempSchedules => [...prevTempSchedules, newSchedule]);
            setCurrentSchedule(newSchedule);
            setScheduleName('');
            setIsAddingSchedule(false);
        }
    };

    // tempSchedules could be an array of schedules, so we need to save all the schedules in scheduleToSave
    const handleSave = async () => {
        try {
            // this is only saving the current schedule, not all the schedules in tempSchedules
            const schedulesToSave = tempSchedules;
            // there are two scenarios:
            // 1. the schedule is already in allSchedules, so we need to update it
            // 2. the schedule is not in allSchedules, so we need to add it
            // map over all the schedules if the current schedule exists in temp schedule update it with the new items else just return the schedule
            const revisedSchedules = allSchedules.map(schedule => {
                const tempScheduleExists = schedulesToSave.find(tempSchedule => tempSchedule.id === schedule.id)
                return tempScheduleExists ? { ...schedule, items: tempScheduleExists.items } : schedule
            });

            // filter allSchedules
            // now allSchedules has the updated schedules and the new schedules, we want to keep the schedules where the tempid doesnt match with allSchedules id
            const newSchedules = schedulesToSave.filter(tempSched => !allSchedules.some(sched => tempSched.id === sched.id));
            // add those schedules to all schedules state
            setAllSchedules([...revisedSchedules, ...newSchedules]);

            // send the updated schedules to the database
            await sendSchedulesToDatabase(allSchedules);

            // empty the tempState
            setTempSchedules([]);

            console.log(JSON.stringify(allSchedules, null, 2), 'allSchedules');
        } catch (error) {
            console.error('Error saving schedules:', error);
        }
    };

    const handleScheduleViewChange = (scheduleName) => {
        
        const selectedSchedule = combinedSchedules.find(schedule => schedule.name === scheduleName);
        if (selectedSchedule) {
            setCurrentSchedule(selectedSchedule);
        }
    };

    return (
        <View style={styles.container}>
            <View style={styles.contentContainer}>
                <View style={styles.schedulesContainer}>
                    <ScrollView horizontal showsHorizontalScrollIndicator={false}>
                        {combinedSchedules.map((schedule, index) => (
                            <TouchableOpacity 
                                key={index} 
                                style={currentSchedule.name === schedule.name ? styles.activeSchedule : styles.schedule} 
                                onPress={() => handleScheduleViewChange(schedule.name)}
                            >
                                <Text style={currentSchedule.name === schedule.name ? styles.activeScheduleText : styles.scheduleText}>
                                    {schedule.name}
                                </Text>
                            </TouchableOpacity>
                        ))}
                        <TouchableOpacity
                            style={styles.addScheduleButton}
                            onPress={() => setIsAddingSchedule(true)}
                        >
                            <Text style={styles.addScheduleButtonText}>+</Text>
                        </TouchableOpacity>
                    </ScrollView>
                </View>
                {isAddingSchedule && (
                    <Animated.View style={styles.addScheduleInputContainer} entering={FadeIn.springify().damping(17)} exiting={FadeOut}>
                        <TextInput
                            style={styles.addScheduleInput}
                            value={scheduleName}
                            onChangeText={setScheduleName}
                            placeholder="New Schedule Name"
                            onSubmitEditing={addNewSchedule}
                        />
                        <TouchableOpacity onPress={addNewSchedule} style={styles.addButton}>
                            <Text style={styles.addButtonText}>Add</Text>
                        </TouchableOpacity>
                        <TouchableOpacity onPress={() => setIsAddingSchedule(false)} style={styles.cancelButton}>
                            <Text style={styles.cancelButtonText}>Cancel</Text>
                        </TouchableOpacity>
                    </Animated.View>
                )}
                <View style={styles.outerCalendarContainer}>
                    <Timetable
                        items={currentSchedule.items}
                        range={range}
                        timeWidth={50}
                        hourHeight={40}
                        renderHeader={CustomHeader}
                        renderItem={props => {
                            const dayIndex = calculateDayIndex(props.item.startDate);
                            return (
                                <Rectangle 
                                    {...props} 
                                    dayIndex={dayIndex} 
                                    daysTotal={5} 
                                    index={props.index}
                                    event={currentSchedule[dayIndex - 1]} // Pass the event data
                                />
                            );
                        }}
                        is12Hour={true}
                        fromHour={8}
                        toHour={18}
                        style={styles.timetable}
                        columnWidth={700 / 5 - 1}
                        hideNowLine={true}
                    />
                </View>
                <View style={styles.searchButtonContainer}>
                    {
                        currentSchedule.items.length > 0 ? (
                            <ButtonComp title="Edit" buttonStyle={styles.searchButton} onPress={() => setOpen(true)} />
                        ) : (
                            <ButtonComp title="Create" buttonStyle={styles.searchButton} onPress={() => setOpen(true)} />
                        )
                    }
                    
                    <ButtonComp title="Save" buttonStyle={styles.searchButton} onPress={handleSave} />
                </View>
            </View>
            {isOpen && (
                <>
                    <AnimatedPressable onPress={() => setOpen(false)} style={styles.backdrop} entering={FadeIn} exiting={FadeOut} />
                    <Animated.View style={styles.sheet} entering={SlideInDown.springify().damping(17)} exiting={SlideOutDown.springify().damping(17)}>
                        <ScheduleEditor handleScheduleCreation={handleScheduleCreation} />
                    </Animated.View>
                </>
            )}
        </View>
    );
};



I have this schedule component. As you can see when i create new schedules i end up merging the new schedules with the schedules that I recieved from the backend. Then I send all the schedules to the backend to be inserted into the database. I'm wondering how should i differentiate between the new schedules and the schedules that were already present in the backend. Should i do this differentiation in the frontend or the backend?