import {
  startOfMonth,
  endOfMonth,
  startOfWeek,
  endOfWeek,
  eachDayOfInterval,
  format,
  isSameMonth,
  isSameDay,
  isToday,
  parseISO,
} from "date-fns";
import type { CalendarEvent, Calendar } from "../types";
import { eventStart, eventEnd } from "../types";

interface MonthViewProps {
  currentDate: Date;
  events: CalendarEvent[];
  calendars: Calendar[];
  visibleCalendarIds: Set<string>;
  onDateClick: (date: Date) => void;
  onEventClick: (event: CalendarEvent) => void;
}

export default function MonthView({
  currentDate,
  events,
  calendars,
  visibleCalendarIds,
  onDateClick,
  onEventClick,
}: MonthViewProps) {
  const monthStart = startOfMonth(currentDate);
  const monthEnd = endOfMonth(currentDate);
  const calStart = startOfWeek(monthStart);
  const calEnd = endOfWeek(monthEnd);
  const days = eachDayOfInterval({ start: calStart, end: calEnd });

  const calColorMap = new Map(calendars.map((c) => [c.id, c.color]));

  const filteredEvents = events.filter((e) => visibleCalendarIds.has(e.calendar_id));

  const getEventsForDay = (day: Date) =>
    filteredEvents.filter((e) => {
      const start = parseISO(eventStart(e));
      const end = parseISO(eventEnd(e));
      return (
        isSameDay(start, day) ||
        isSameDay(end, day) ||
        (start < day && end > day)
      );
    });

  return (
    <div className="flex flex-col h-full">
      <div className="grid grid-cols-7 border-b border-gray-200 dark:border-gray-700">
        {["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map((d) => (
          <div
            key={d}
            className="py-2 text-center text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide"
          >
            {d}
          </div>
        ))}
      </div>
      <div className="grid grid-cols-7 flex-1 auto-rows-fr">
        {days.map((day, i) => {
          const inMonth = isSameMonth(day, currentDate);
          const today = isToday(day);
          const dayEvents = getEventsForDay(day);

          return (
            <div
              key={day.toISOString()}
              className={`min-h-[80px] border-b border-r border-gray-100 dark:border-gray-700/50 p-1 cursor-pointer transition-colors hover:bg-gray-50 dark:hover:bg-gray-800/50
                ${i % 7 === 0 ? "border-l" : ""}
                ${!inMonth ? "bg-gray-50/50 dark:bg-gray-900/30" : ""}`}
              onClick={() => onDateClick(day)}
            >
              <div className="flex justify-center mb-1">
                <span
                  className={`text-xs w-6 h-6 flex items-center justify-center rounded-full font-medium
                    ${today ? "bg-blue-600 text-white" : ""}
                    ${!today && inMonth ? "text-gray-700 dark:text-gray-300" : ""}
                    ${!today && !inMonth ? "text-gray-400 dark:text-gray-600" : ""}`}
                >
                  {format(day, "d")}
                </span>
              </div>
              <div className="space-y-0.5 overflow-hidden">
                {dayEvents.slice(0, 3).map((evt) => (
                  <button
                    key={evt.id + day.toISOString()}
                    onClick={(e) => {
                      e.stopPropagation();
                      onEventClick(evt);
                    }}
                    className="w-full text-left text-[10px] leading-tight px-1.5 py-0.5 rounded truncate text-white font-medium transition-opacity hover:opacity-80"
                    style={{
                      backgroundColor:
                        calColorMap.get(evt.calendar_id) || "#3B82F6",
                    }}
                  >
                    {!evt.all_day && (
                      <span className="opacity-80">
                        {format(parseISO(eventStart(evt)), "h:mm")}{" "}
                      </span>
                    )}
                    {evt.title}
                  </button>
                ))}
                {dayEvents.length > 3 && (
                  <div className="text-[10px] text-gray-500 dark:text-gray-400 text-center font-medium">
                    +{dayEvents.length - 3} more
                  </div>
                )}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}
