import React, { useRef, useState } from "react";
import { LayoutChangeEvent, StyleSheet } from "react-native";
import { Calendar } from "react-native-big-calendar";
import {
  Picker,
  PickerModes,
  SegmentedControl,
  View,
} from "react-native-ui-lib";
import { MaterialIcons } from "@expo/vector-icons";
import { AddEventDialog } from "@/components/pages/calendar/AddEventDialog";
import HeaderTemplate from "@/components/shared/HeaderTemplate";
import CalendarViewSwitch from "@/components/pages/calendar/CalendarViewSwitch";
import { ManuallyAddEventModal } from "@/components/pages/calendar/ManuallyAddEventModal";
import { CalendarEvent } from "@/contexts/CalendarContext";
import { useSettingsContext } from "@/contexts/SettingsContext";
import EditEventDialog from "./EditEventDialog";
import { useGetEvents } from "@/hooks/firebase/useGetEvents";
import { Text } from "react-native-ui-lib";

const modeMap = new Map([
  [0, "day"],
  [1, "week"],
  [2, "month"],
]);

const months = [
  "January",
  "February",
  "March",
  "April",
  "May",
  "June",
  "July",
  "August",
  "September",
  "October",
  "November",
  "December",
];

export default function CalendarPage() {
  const { calendarColor } = useSettingsContext();
  const [editVisible, setEditVisible] = useState<boolean>(false);
  const [eventForEdit, setEventForEdit] = useState<CalendarEvent>();

  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,
    },
  });

  const [isFamilyView, setIsFamilyView] = useState<boolean>(false);
  const [calendarHeight, setCalendarHeight] = useState(0);
  const [mode, setMode] = useState<"week" | "month" | "day">("week");
  const [selectedDate, setSelectedDate] = useState<Date>(new Date());
  const [selectedNewEventDate, setSelectedNewEndDate] = useState<
    Date | undefined
  >(undefined);

  const calendarContainerRef = useRef(null);
  const { data: events } = useGetEvents(isFamilyView);

  const onLayout = (event: LayoutChangeEvent) => {
    const { height } = event.nativeEvent.layout;
    setCalendarHeight(height);
  };

  const handleSegmentChange = (index: number) => {
    const selectedMode = modeMap.get(index);
    if (selectedMode) {
      setMode(selectedMode as "day" | "week" | "month");
    }
  };

  const handleMonthChange = (month: string) => {
    const currentDay = selectedDate.getDate();
    const currentYear = selectedDate.getFullYear();

    const newMonthIndex = months.indexOf(month);

    const updatedDate = new Date(currentYear, newMonthIndex, currentDay);

    setSelectedDate(updatedDate);
  };

  return (
    <View
      style={{ flex: 1, height: "100%", padding: 10 }}
      paddingH-22
      paddingT-0
    >
      <HeaderTemplate
        message={"Let's get your week started!"}
        isWelcome={true}
      />

      <View
        style={{ flex: 1, backgroundColor: "#fff", borderRadius: 30 }}
        ref={calendarContainerRef}
        onLayout={onLayout}
      >
        <View
          style={{
            flexDirection: "row",
            justifyContent: "space-between",
            alignItems: "center",
            paddingHorizontal: 10,
            paddingVertical: 8,
            borderRadius: 20,
            borderBottomLeftRadius: 0,
            borderBottomRightRadius: 0,
            backgroundColor: "white",
            marginBottom: 10,
          }}
        >
          <View row centerV gap-3>
            <Text style={{ fontFamily: "Manrope_500Medium", fontSize: 17 }}>
              {selectedDate.getFullYear()}
            </Text>
            <Picker
              value={months[selectedDate.getMonth()]} // Get the month from the date
              placeholder={"Select Month"}
              style={{ fontFamily: "Manrope_500Medium", fontSize: 17 }}
              mode={PickerModes.SINGLE}
              onChange={(itemValue) => handleMonthChange(itemValue as string)}
              trailingAccessory={<MaterialIcons name={"keyboard-arrow-down"} />}
              topBarProps={{
                title: selectedDate.getFullYear().toString(),
                titleStyle: { fontFamily: "Manrope_500Medium", fontSize: 17 },
              }}
            >
              {months.map((month) => (
                <Picker.Item key={month} label={month} value={month} />
              ))}
            </Picker>
          </View>

          <View>
            <SegmentedControl
              segments={[{ label: "D" }, { label: "W" }, { label: "M" }]}
              backgroundColor="#ececec"
              inactiveColor="#919191"
              activeBackgroundColor="#ea156c"
              activeColor="white"
              outlineColor="white"
              outlineWidth={3}
              segmentLabelStyle={styles.segmentslblStyle}
              onChangeIndex={handleSegmentChange}
              initialIndex={mode === "day" ? 0 : mode === "week" ? 1 : 2}
            />
          </View>
        </View>

        {calendarHeight > 0 && (
          <Calendar
            bodyContainerStyle={styles.calHeader}
            mode={mode}
            events={isFamilyView ? events ?? [] : events ?? []}
            eventCellStyle={(event) => ({ backgroundColor: event.eventColor })}
            onPressEvent={(event) => {
              setEditVisible(true);
              setEventForEdit(event);
            }}
            height={calendarHeight}
            activeDate={selectedDate}
            date={selectedDate}
            onPressCell={setSelectedNewEndDate}
            headerContentStyle={mode === "day" ? styles.dayModeHeader : {}}
          />
        )}
      </View>
      <CalendarViewSwitch viewSwitch={setIsFamilyView} />
      <AddEventDialog />
      {eventForEdit && (
        <EditEventDialog
          isVisible={editVisible}
          setIsVisible={() => {
            setEditVisible(!editVisible);
          }}
          event={eventForEdit}
        />
      )}

      <ManuallyAddEventModal
        key={`${selectedNewEventDate}`}
        initialDate={selectedNewEventDate}
        show={!!selectedNewEventDate}
        close={() => setSelectedNewEndDate(undefined)}
      />
    </View>
  );
}
