import React, { useEffect, useState } from 'react';
import { View } from 'react-native';
import moment from 'moment';
import { Modal } from '../../Modal';

import { styles } from './style';
import { Colors } from '../../../theme';
import { Calendar } from 'react-native-calendars';
import { Button } from 'src/components/Button';
import { ButtonVariants } from 'src/types/components';

export default function RangeCalendar({
  isModalVisible,
  closeModal,
  allowRangeSelection = true,
  disableFutureDates = false,
  highlightedDates,
  selectedDate
}: {
  isModalVisible: boolean;
  closeModal: (startDate?: string | null, endDate?: string | null) => void;
  allowRangeSelection?: boolean;
  disableFutureDates?: boolean;
  highlightedDates?: string[];
  selectedDate?: string;
}) {
  const [selectedStartDate, setSelectedStartDate] = useState<string | null>(null);
  const [selectedEndDate, setSelectedEndDate] = useState<string | null>(null);

  useEffect(() => {
    if (selectedDate) {
      setSelectedStartDate(selectedDate);
    }
  }, [selectedDate]);

  const customThemeStyles = {
    textSectionTitleColor: Colors.ORANGE,
    todayTextColor: Colors.DARK_BLUE,
    dayTextColor: Colors.DARK_BLUE,
    textDisabledColor: Colors.LIGHT_GRAY,
    dotColor: Colors.DARK_BLUE,
    arrowColor: Colors.DARK_BLUE,
    monthTextColor: Colors.DARK_BLUE,
    indicatorColor: Colors.DARK_BLUE,
    textDayFontWeight: 'normal',
    textMonthFontWeight: 'bold',
    textDayHeaderFontWeight: 'bold',
    textDayFontSize: 14,
    textMonthFontSize: 14,
    textDayHeaderFontSize: 12,
    selectedDayBackgroundColor: Colors.ORANGE,
    'stylesheet.calendar.header': {
      header: styles.calendarHeader
    },
  };

  const onDayPress = (day: any) => {
    if (!allowRangeSelection) {
      setSelectedStartDate(day.dateString);
      return;
    } 
    if (!selectedStartDate || (selectedStartDate && selectedEndDate)) {
      setSelectedStartDate(day.dateString);
      setSelectedEndDate(null);
    } else if (!selectedEndDate) {
      if (day.dateString < selectedStartDate) {
        setSelectedEndDate(selectedStartDate);
        setSelectedStartDate(day.dateString);
      } else {
        setSelectedEndDate(day.dateString);
      }
    }
  };

  const markedDates = (() => {
    const marked: { [key: string]: any } = {};
    let start = selectedStartDate as unknown as string;
    let end = selectedEndDate as unknown as string;
    if (selectedDate && !selectedStartDate) {
      marked[selectedDate] = {
        selected: true,
        startingDay: true,
        endingDay: true,
        color: Colors.ORANGE,
        textColor: 'white',
      };
    }
    if (disableFutureDates) {
      const today = moment().add(1, 'day');
      const lastDay = moment().add(2, 'years');
      while (today.isBefore(lastDay, 'day')) {
        const dateString = today.format('YYYY-MM-DD');
        if (!marked[dateString]) {
          marked[dateString] = {  disableTouchEvent: true, disabled: true };
        }
        today.add(1, 'day');
      }
    }
    if (highlightedDates) {
      const datesSet = new Set(highlightedDates);

      const startDateMoment = moment(highlightedDates[0]);
      const endDateMoment = moment(highlightedDates[highlightedDates.length - 1]);
    
      for (let m = moment(startDateMoment); m.diff(endDateMoment, 'days') <= 0; m.add(1, 'days')) {
        const dateString = m.format('YYYY-MM-DD');
        if (!datesSet.has(dateString)) {
          marked[dateString] = { disableTouchEvent: true, disabled: true };
        }
      }

    }
    if (start && end) {
      marked[start] = { startingDay: true, color: Colors.ORANGE, textColor: 'white' };
      let day = start;
      while (day < end) {
        day = moment(day).add(1, 'days').format('YYYY-MM-DD');
        if (day === end) {
          marked[day] = { endingDay: true, color: Colors.ORANGE, textColor: 'white' };
        } else {
          marked[day] = { color: 'transparent', textColor: Colors.DARK_BLUE };
        }
      }
    } else if (start) {
      marked[start] = {
        selected: true,
        startingDay: true,
        endingDay: true,
        color: Colors.ORANGE,
        textColor: 'white',
      };
    }
    return marked;
  })();

  const resetSelections = () => {
    closeModal();
    setSelectedStartDate(null);
    setSelectedEndDate(null);
  };

  const handleClose = () => {
    closeModal(selectedStartDate, selectedEndDate);
    setSelectedStartDate(null);
    setSelectedEndDate(null);
  };

  return (
    <Modal
      visibleInPercent={'auto'}
      visible={isModalVisible}
      onRequestClose={resetSelections}
      headerTitle={allowRangeSelection ? "Select Dates" : "Select Date" }
    >
      <View style={styles.modalContent}>
        <Calendar
          onDayPress={onDayPress}
          markingType={'period'}
          markedDates={markedDates}
          enableSwipeMonths={true}
          firstDay={1}
          theme={{
            ...customThemeStyles,
          }}
          minDate={highlightedDates ? highlightedDates[0] : undefined}
          maxDate={highlightedDates ? highlightedDates[highlightedDates.length - 1] : undefined}
          current={selectedDate}
        />
      </View>
      <View style={styles.modalFooter}>
        <Button
          children="Done"
          onPress={handleClose}
          disabled={!selectedStartDate}
          variant={!selectedStartDate ? ButtonVariants.OPACITY : ButtonVariants.FILL}
          containerStyles={{ borderWidth: 0 }}
         />
      </View>
    </Modal>
  );
}
