/** @jsxRuntime classic */
/** @jsx jsx */

import { FC, useMemo, useState, useEffect } from 'react';
import { jsx, useTheme } from '@emotion/react';
import { Droppable } from '../Droppable';
import { Draggable } from './Draggable';
import { IDayToDropProps, ISlot } from '../../types';
import { useMiddlewareContext } from '../../hooks/useMiddlewareContext';
import {
  collisionGroupContainer,
  moreItemsButton,
  moreModal,
  weekDayToDropContainer,
} from '../styles';
import { calculateModalPosition } from '../../utils';
import { BnClose } from '../../../icons/BnClose';
import { AddNewSlotButtons } from './AddNewSlotButtons';

export const DayToDrop: FC<IDayToDropProps> = ({
  id,
  EventComponent,
  withoutChildren,
  hiddenEvents,
  onAddNewSlotClick,
}) => {
  const {
    partialRanges,
    options,
    getPartialEvents,
    getEventsGroups,
    isResizing,
    eventsToSpaces,
  } = useMiddlewareContext();
  const { partialRendering } = options;
  const colors = useTheme();

  const [hover, setHover] = useState(false);

  const eventsGroups = useMemo(() => {
    const events = hiddenEvents
      ? []
      : ((Array.isArray(eventsToSpaces?.[id])
          ? partialRendering
            ? getPartialEvents(
                eventsToSpaces[id],
                partialRanges.vertical.from,
                partialRanges.vertical.to
              )
            : eventsToSpaces[id]
          : []) as ISlot[]);

    return getEventsGroups(events);
  }, [
    eventsToSpaces,
    id,
    partialRanges.vertical.from,
    partialRanges.vertical.to,
    partialRendering,
    hiddenEvents,
  ]);

  const eventsFullGroups = useMemo(() => {
    const events = hiddenEvents
      ? []
      : ((Array.isArray(eventsToSpaces?.[id])
          ? eventsToSpaces[id]
          : []) as ISlot[]);

    return getEventsGroups(events);
  }, [eventsToSpaces, id, hiddenEvents]);

  const [modals, setModals] = useState<boolean[]>([]);

  useEffect(() => {
    setModals(Array(eventsGroups.length).fill(false));
  }, [eventsGroups]);

  const handleToggleModal = (index: number) => {
    let newModals = modals.slice();
    newModals[index] = !newModals[index];
    setModals(newModals);
  };

  const MAX_COUNT = 4;

  return (
    <div
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      css={weekDayToDropContainer(colors, withoutChildren)}
    >
      <Droppable id={id}>
        {eventsGroups.map((group, index) => {
          const withModal = (group.groups?.length || 0) > MAX_COUNT;

          if (Array.isArray(group.groups)) {
            const moreItemsCount = withModal
              ? group.groups
                  .slice(3)
                  .reduce((acc, events) => acc + events.length, 0)
              : 0;

            const element = document.querySelector(`#group-${index}`);
            const box = element as HTMLElement;
            const container = box?.parentElement;
            const boxW = container?.parentElement?.parentElement;
            const containerW = boxW?.parentElement;

            return (
              <div
                id={`group-${index}`}
                key={index}
                css={collisionGroupContainer(group.top, group.height)}
              >
                {group.groups?.map((groupItems, index) => {
                  return (
                    <div key={index}>
                      {groupItems.map((event) => (
                        <Draggable
                          parentId={id}
                          state={event}
                          key={event.id}
                          id={event.id}
                          groupTop={group.top}
                          groupCount={
                            withModal ? MAX_COUNT : group.groups?.length
                          }
                          groupIndex={index}
                        >
                          <EventComponent event={event} />
                        </Draggable>
                      ))}
                    </div>
                  );
                })}
                {withModal && (
                  <button
                    css={moreItemsButton(colors)}
                    onClick={() => handleToggleModal(index)}
                  >
                    <div>+{moreItemsCount}</div>
                    <div>{'more'}</div>
                  </button>
                )}
                {withModal && modals[index] && (
                  <div
                    css={moreModal(
                      colors,
                      calculateModalPosition(box, container, boxW, containerW)
                    )}
                  >
                    <div className="more-modal-header">
                      <div onClick={() => handleToggleModal(index)}>
                        <BnClose />
                      </div>
                    </div>
                    <div className="events-list">
                      {group.items.map((event) => (
                        <div key={event.id} css={{ margin: 2, height: '50px' }}>
                          <EventComponent event={event} />
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            );
          } else if (group.item) {
            return (
              <Draggable
                parentId={id}
                state={group.item}
                key={group.item.id}
                id={group.item.id}
              >
                <EventComponent event={group.item} />
              </Draggable>
            );
          } else {
            return null;
          }
        })}
        {hover && !isResizing && (
          <AddNewSlotButtons
            parentId={id}
            events={JSON.stringify(eventsFullGroups)}
            onClick={onAddNewSlotClick}
          />
        )}
      </Droppable>
    </div>
  );
};
