import { useState, useEffect } from 'react';
import { Box } from '@mui/material';
import {
  CalendarContainer,
  CalendarGrid,
  CalendarDay,
  CalendarWeekday,
} from './Calendar.styles';
import { CalendarHeader } from './CalendarHeader';
import { weekdayNames } from './constants';
import { isPastDate } from '../utils';

const getToday = () => {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  return today;
};

const parseValue = (dateString) => {
  if (!dateString) return null;
  const date = new Date(dateString);
  return Number.isNaN(date.getTime()) ? null : date;
};

export const Calendar = ({ value, onChange, onClose }) => {
  const initialDate = parseValue(value);
  const [currentDate, setCurrentDate] = useState(initialDate || new Date());
  const [selectedDate, setSelectedDate] = useState(initialDate);

  useEffect(() => {
    const date = parseValue(value);
    if (date) {
      setCurrentDate(date);
      setSelectedDate(date);
    }
  }, [value]);

  const year = currentDate.getFullYear();
  const month = currentDate.getMonth();

  const firstDayOfMonth = new Date(year, month, 1);
  const lastDayOfMonth = new Date(year, month + 1, 0);
  const firstDayOfWeek = (firstDayOfMonth.getDay() + 6) % 7;
  const daysInMonth = lastDayOfMonth.getDate();

  const today = getToday();
  const isPrevMonthDisabled =
    year < today.getFullYear() ||
    (year === today.getFullYear() && month <= today.getMonth());

  const handlePrevMonth = () => {
    if (isPrevMonthDisabled) return;
    setCurrentDate(new Date(year, month - 1, 1));
  };

  const handleNextMonth = () => {
    setCurrentDate(new Date(year, month + 1, 1));
  };

  const handleDateClick = (day) => {
    const newDate = new Date(year, month, day);
    if (isPastDate(newDate)) return;

    setSelectedDate(newDate);

    const formattedDate = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
    onChange(formattedDate);
    onClose();
  };

  const isToday = (day) =>
    day === today.getDate() &&
    month === today.getMonth() &&
    year === today.getFullYear();

  const isDayPast = (day) => isPastDate(new Date(year, month, day));

  const isSelected = (day) => {
    if (!selectedDate) return false;
    return (
      day === selectedDate.getDate() &&
      month === selectedDate.getMonth() &&
      year === selectedDate.getFullYear()
    );
  };

  const days = [];

  for (let i = 0; i < firstDayOfWeek; i++) {
    days.push(null);
  }

  for (let day = 1; day <= daysInMonth; day++) {
    days.push(day);
  }

  return (
    <CalendarContainer>
      <CalendarHeader
        month={month}
        year={year}
        onPrevMonth={handlePrevMonth}
        onNextMonth={handleNextMonth}
        isPrevMonthDisabled={isPrevMonthDisabled}
      />

      <Box>
        <CalendarGrid>
          {weekdayNames.map((dayName) => (
            <CalendarWeekday key={dayName}>{dayName}</CalendarWeekday>
          ))}
          {days.map((day, index) =>
            day === null ? (
              <Box key={`empty-${index}`} sx={{ height: '2.5rem' }} />
            ) : (
              <CalendarDay
                key={day}
                onClick={() => handleDateClick(day)}
                isToday={isToday(day)}
                isSelected={isSelected(day)}
                isDisabled={isDayPast(day)}
              >
                {day}
              </CalendarDay>
            ),
          )}
        </CalendarGrid>
      </Box>
    </CalendarContainer>
  );
};
