import React, { useState, useEffect } from "react";
import "../styles/CalendarWeek.css";

const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

const CalendarWeek = ({
  participants,
  startDate,
  endDate,
  maxParticipants,
  hoveredInfo,
  setHoveredInfo,
}) => {
  const [currentWeekIndex, setCurrentWeekIndex] = useState(0);
  const [weeks, setWeeks] = useState([]);
  const [schedule, setSchedule] = useState({});

  const handlePrevWeek = () => {
    setCurrentWeekIndex(Math.max(0, currentWeekIndex - 1));
  };

  const handleNextWeek = () => {
    setCurrentWeekIndex(Math.min(weeks.length - 1, currentWeekIndex + 1));
  };

  useEffect(() => {
    const start = new Date(startDate);
    start.setDate(
      start.getDate() - (start.getDay() === 0 ? 6 : start.getDay() - 1)
    );
    const end = new Date(endDate);

    let weeksTemp = [];
    while (start <= end) {
      const weekStart = new Date(start);
      const weekDates = Array.from({ length: 7 }).map((_, index) => {
        const date = new Date(weekStart);
        date.setDate(date.getDate() + index);
        return date;
      });

      weeksTemp.push(weekDates);
      start.setDate(start.getDate() + 7);
    }
    setWeeks(weeksTemp);

    let newSchedule = {};
    participants.forEach((participant) => {
      participant.availableSchedules.forEach(
        ({ availableDate, availableTimes }) => {
          const date = new Date(availableDate);
          availableTimes.forEach((time) => {
            const hour = Math.floor(time / 2);
            const minute = (time % 2) * 30;
            const timeString = `${hour.toString().padStart(2, "0")}:${minute
              .toString()
              .padStart(2, "0")}`;
            const dateString = `${date.getFullYear()}-${(date.getMonth() + 1)
              .toString()
              .padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`;
            if (!newSchedule[dateString]) {
              newSchedule[dateString] = [];
            }
            newSchedule[dateString].push({
              time: timeString,
              name: participant.name,
            });
          });
        }
      );
    });
    setSchedule(newSchedule);
  }, [participants, startDate, endDate]);

  const calculateOpacity = (dateString, timeString) => {
    const availableCount =
      schedule[dateString]?.filter((s) => s.time === timeString).length || 0;
    return 100 - (availableCount / maxParticipants) * 100;
  };

  const handleMouseEnter = (dateString, timeString) => {
    const availableParticipants =
      schedule[dateString]
        ?.filter((s) => s.time === timeString)
        .map((s) => s.name) || [];
    setHoveredInfo({
      date: dateString,
      time: timeString,
      participants: availableParticipants,
    });
  };

  const handleMouseLeave = () => {
    setHoveredInfo(null);
  };

  const weekDates = weeks[currentWeekIndex] || [];

  return (
    <div className="wrap">
      <div className="button-container">
        <button onClick={handlePrevWeek} disabled={currentWeekIndex === 0}>
          Prev Week
        </button>
        <button
          onClick={handleNextWeek}
          disabled={currentWeekIndex === weeks.length - 1}
        >
          Next Week
        </button>
      </div>
      <table className="calendar-container">
        <thead>
          <tr>
            <th>Time</th>
            {weekDates.map((date) => (
              <th key={date.toISOString()}>
                {date.getMonth() + 1}/{date.getDate()} ({days[date.getDay()]})
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {[...Array(48).keys()].map((timeSlot) => {
            const hour = Math.floor(timeSlot / 2);
            const minute = (timeSlot % 2) * 30;
            return (
              <tr key={timeSlot}>
                <td>
                  {hour.toString().padStart(2, "0") +
                    ":" +
                    minute.toString().padStart(2, "0")}
                </td>
                {weekDates.map((date) => {
                  const dateString = `${date.getFullYear()}-${(
                    date.getMonth() + 1
                  )
                    .toString()
                    .padStart(2, "0")}-${date
                    .getDate()
                    .toString()
                    .padStart(2, "0")}`;
                  const timeString = `${hour
                    .toString()
                    .padStart(2, "0")}:${minute.toString().padStart(2, "0")}`;
                  const opacity = calculateOpacity(dateString, timeString);
                  const cellStyle = { opacity: `${opacity}%` };
                  return (
                    <td
                      key={`${date.toISOString()}-${timeString}`}
                      style={cellStyle}
                      onMouseEnter={() =>
                        handleMouseEnter(dateString, timeString)
                      }
                      onMouseLeave={handleMouseLeave}
                    />
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
      {hoveredInfo && (
        <div className="possibleMan" style={{ textAlign: "center" }}>
          <strong>가능한 사람:</strong>
          <ul>
            {hoveredInfo.participants.map((name) => (
              <li key={name}>{name}</li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
};

export default CalendarWeek;