import moment from "moment";
import "moment/locale/ru";
import React, { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { Link } from "react-router-dom";

import {
  setEditReport,
  setReportDate,
  setRequestDate,
  setSendRequest
} from "@redux/reportSlice";

import {
  calendarHelper,
  correctDay,
  getCorrectDate,
  getReports,
  hourOfNum
} from "@utils/calendarHelper";
import { getCorrectYYMMDD } from "@utils/helper";

import { apiRequest } from "@api/request";

import "@components/Calendar/calendarComponent.scss";
import BaseButton from "@components/Common/BaseButton/BaseButton";

import arrowLeft from "assets/icons/arrows/arrowCalendar_left.png";
import arrowRight from "assets/icons/arrows/arrowCalendar_right.png";
import calendarIcon from "assets/icons/calendar.svg";
import rectangle from "assets/images/rectangle__calendar.webp";

export const ProfileCalendarComponent = React.memo(
  ({
    userId,
    value,
    setValueHandler,
    reports,
    totalHours,
    startRangeDays,
    toggleRangeDays,
    startDate,
    setStartDateRange
  }) => {
    const dispatch = useDispatch();

    // const [l, setL] = useState(1);
    const [calendar, setCalendar] = useState([]);
    const [month, setMonth] = useState("");
    const [endDate, setEndDate] = useState(null);
    const [totalRangeHours, setTotalRangeHours] = useState(0);
    const [selectedRangeDays, setSelectedRangeDays] = useState({});
    const [activePeriod, setActivePeriod] = useState(false);

    useEffect(() => {
      setCalendar(calendarHelper(value));
      calendarHelper(value).map((array) => {
        setSelectedRangeDays((prevState) => ({
          ...prevState,
          [array[0]]: false
        }));
      });
      if (endDate) {
        resetRangeDays();
      }
    }, [value]);

    useEffect(() => {
      setMonth(value.format("MMMM"));
    }, [month]);

    function isToday(day) {
      return day.isSame(new Date(), "day");
    }

    function dayStyles(day) {
      if (moment() < day) return `block`;
      for (const date of reports) {
        if (
          `${new Date(day).getFullYear()}-${correctDay(
            new Date(day).getMonth() + 1
          )}-${correctDay(new Date(day).getDate())}` === date.created_at
        ) {
          return `before`;
        }
      }
      if (day.day() === 6 || day.day() === 0) return `selected`;
      if (isToday(day)) return `today`;
      return "pass";
    }

    function correctRoute(day) {
      for (const date of reports) {
        if (
          `${new Date(day).getFullYear()}-${correctDay(
            new Date(day).getMonth() + 1
          )}-${correctDay(new Date(day).getDate())}` === date.created_at
        ) {
          if (userId) {
            return `/profile/calendar/view/${date.created_at}/${userId}`;
          }
          return `/profile/calendar/view/${
            date.created_at
          }/${localStorage.getItem("id")}`;
        }
      }

      if (userId) {
        return "#";
      }

      return "/profile/calendar/report";
    }

    const prevMonth = () => value.clone().subtract(1, "month");

    const nextMonth = () => value.clone().add(1, "month");

    function reportsByDate(endDay) {
      const requestDates =
        startDate < endDay
          ? `fromDate=${getCorrectYYMMDD(
              startDate._d
            )}&toDate=${getCorrectYYMMDD(endDay._d)}`
          : `fromDate=${getCorrectYYMMDD(endDay._d)}&toDate=${getCorrectYYMMDD(
              startDate._d
            )}`;
      apiRequest(
        `/reports/index?${requestDates}&user_id=${
          userId ? userId : localStorage.getItem("id")
        }`
      ).then((reports) => {
        let spendTime = 0;
        reports.map((report) => {
          spendTime += report.task.reduce(
            (acc, task) => acc + task.hours_spent,
            0
          );
        });
        setTotalRangeHours(Math.floor(spendTime));
      });
    }

    function rangeDays(day) {
      if (!startDate) {
        setStartDateRange(day);
      } else {
        setEndDate(day);
        reportsByDate(day);
      }
    }

    function onMouseRangeDays(day) {
      let selectRange = {};
      for (let curDay in selectedRangeDays)
        selectRange[curDay] =
          day > startDate
            ? new Date(curDay) > startDate && new Date(curDay) < day
            : new Date(curDay) < startDate && new Date(curDay) > day;

      setSelectedRangeDays(selectRange);
    }

    function resetRangeDays() {
      setStartDateRange(null);
      setEndDate(null);
      setTotalRangeHours(0);
      calendarHelper(value).map((array) => {
        setSelectedRangeDays((prevState) => ({
          ...prevState,
          [array[0]]: false
        }));
      });
    }

    const countHours = (day) => {
      let hours =
        reports
          .find((item) => moment(item.created_at).isSame(day, "date"))
          ?.task.reduce((acc, task) => acc + task.hours_spent, 0) || 0;
      return `${hours} ${hourOfNum(hours)}`;
    };

    return (
      <div className="calendar-component">
        <div className="calendar-component__header">
          <div className="calendar-component__header-info">
            <p className="calendar__hours">
              {month}&nbsp;
              <span>
                ({totalHours} {hourOfNum(totalHours)})
              </span>
            </p>
          </div>
          <div className="calendar-component__header-switcher">
            <div
              className="calendar-component__header-arrow"
              onClick={() => {
                setValueHandler(prevMonth());
                dispatch(setRequestDate(getReports(prevMonth())));
              }}
            >
              <img src={arrowLeft} alt="" />
            </div>
            <div className="calendar-component__header-box">
              <img className={"calendar__icon"} src={calendarIcon} alt="" />
              <span>{value.format("MMMM, YYYY")}</span>
            </div>
            <div
              className="calendar-component__header-arrow"
              onClick={() => {
                setValueHandler(nextMonth());
                dispatch(setRequestDate(getReports(nextMonth())));
              }}
            >
              <img src={arrowRight} alt="" />
            </div>
          </div>
        </div>

        <div className="calendar-component__rectangle">
          <img src={rectangle} alt="" />
        </div>

        <div className="calendar-component__body">
          <div>
            <p>Понедельник</p>
            <p>Вторник</p>
            <p>Среда</p>
            <p>Четверг</p>
            <p>Пятница</p>
            <p>Суббота</p>
            <p>Воскресенье</p>
          </div>

          <div className="calendar-component__form">
            {calendar.map((week) =>
              week.map((day) => (
                <button
                  onClick={() => {
                    if (startRangeDays) rangeDays(day);
                    else {
                      dispatch(setReportDate(day));
                      dispatch(setSendRequest(true));
                      dispatch(setEditReport(""));
                    }
                  }}
                  onMouseEnter={() => {
                    if (startRangeDays && startDate && !endDate)
                      onMouseRangeDays(day);
                  }}
                  key={day}
                  className={
                    startRangeDays
                      ? `select-days ${
                          String(startDate?._d) === String(day._d) ||
                          endDate === day
                            ? "selected-day"
                            : ""
                        } ${endDate ? "disable" : ""} ${
                          selectedRangeDays[day] ? "selected-day" : ""
                        }`
                      : dayStyles(day)
                  }
                  name={day.format("dddd")}
                  id="btn"
                >
                  <Link to={startRangeDays ? "#" : correctRoute(day)}>
                    <div className="form-date">{day.format("D")}</div>
                    <div className="form-box">
                      <div className="form-hours">
                        <span>{countHours(day)}</span>
                      </div>
                    </div>
                  </Link>
                </button>
              ))
            )}
          </div>
        </div>
        <div className="select-date-range">
          <span
            className="select"
            onClick={() => {
              if (startRangeDays) resetRangeDays();
              toggleRangeDays();
              setActivePeriod(!activePeriod);
            }}
          >
            {endDate
              ? startDate < endDate
                ? `${getCorrectDate(startDate)} - ${getCorrectDate(endDate)}`
                : `${getCorrectDate(endDate)} - ${getCorrectDate(startDate)}`
              : activePeriod
              ? "Выберите диапазон на календаре"
              : "Выбрать диапазон"}
          </span>

          <span>
            {totalRangeHours
              ? `${totalRangeHours} ${hourOfNum(totalRangeHours)}`
              : endDate
              ? "0 часов"
              : ""}
          </span>
          {endDate && (
            <BaseButton
              styles={"clear-days"}
              onClick={() => {
                resetRangeDays();
                setActivePeriod(false);
                toggleRangeDays();
              }}
            >
              Сбросить
            </BaseButton>
          )}
          <span className="hint">Для общего просчета - выберите диапазон</span>
        </div>
      </div>
    );
  }
);
