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

import { FC, useEffect, useState } from 'react';
import { css, jsx } from '@emotion/react';
import dayjs from 'dayjs';
import { Header } from './muleculos/Header';
import { FilterLine } from './muleculos/FilterLine';
import { SlotContainer } from './layout/slotContainer';
import { SACalendar } from '../../SACalendar/SACalendar';
import { Space } from './Space';
import { SpaceHorizontalView } from './SpaceHorizontalView';
import { getHours, getWeeklyEventHours } from './timeUtils';
import {
  ECalendarMode,
  ECalendarView,
  IDragOverlayComponentProps,
  IEventComponentProps,
  ISlotsEventsAndEventsWithSpaces,
} from '../../SACalendar/types';
import { newSlots, newSpaces } from './changedDb';
import { fetchData, selectedDate as defaultDate } from './helpers';
import { Slot } from '../../organisms';

const container = css`
  height: 100%;
  display: flex;
  flex-direction: column;
`;
const bodyContainer = css`
  position: relative;
  flex-grow: 1;
  display: flex;
`;

const mainContainer = css`
  position: relative;
  flex-grow: 1;
  display: flex;
`;

const columnContainer = css`
  flex-grow: 1;
  display: flex;
  flex-direction: column;
`;

const eventComponentStyles = css`
  height: 100%;
  background: #edf4fc;
  border-left: 3px solid #4a90e2;
  padding-left: 5px;
  border-radius: 2px;
`;

const EventComponent: FC<IEventComponentProps> = ({ event }) => {
  return (
    <div css={eventComponentStyles}>
      {event?.id}
      <label>{event?.reservation?.name}</label>
      <div>{getHours(event?.startDate, event?.endDate)}</div>
      <div>{event?.startDate.slice(0, 10)}</div>
    </div>
  );
};

const eventWeeklyComponentStyles = css`
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 16px;
  height: 100%;
  background: #edf4fc;
  border-left: 3px solid #4a90e2;
  padding: 0 4px;
  border-radius: 2px;

  font-family: Montserrat;
  font-style: normal;
  font-weight: 600;
  font-size: 10px;
  line-height: 12.19px;

  label {
    max-width: 48%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: inherit;
  }
  span {
    max-width: 49%;
    white-space: nowrap;
    font-weight: 400;
  }
`;

const EventWeeklyComponent: FC<IEventComponentProps> = ({ event }) => {
  return (
    <div css={eventWeeklyComponentStyles}>
      <label>{event?.reservation?.name}</label>
      <span>{getWeeklyEventHours(event?.startDate, event?.endDate)}</span>
    </div>
  );
};

const DragOverlayEventWeeklyComponent: FC<IDragOverlayComponentProps> = ({
  event,
}) => {
  return (
    <div css={eventWeeklyComponentStyles} style={{ background: '#fff4fc' }}>
      <label>{event?.reservation?.name}</label>
      <span>{getWeeklyEventHours(event?.startDate, event?.endDate)}</span>
    </div>
  );
};

const dragOverlayComponentStyles = css`
  height: 100%;
  background: #fff4fc;
  border-left: 3px solid #4a90e2;
  padding-left: 5px;
  border-radius: 2px;
`;

const DragOverlayComponent: FC<IDragOverlayComponentProps> = ({
  event,
  hours,
}) => {
  return (
    <div css={dragOverlayComponentStyles}>
      {event?.id}
      <label>{event?.reservation?.name}</label>
      <div>{hours}</div>
      <div>{event?.startDate.slice(0, 10)}</div>
    </div>
  );
};

export const Calendar = ({
  isRightWindow,
  setRightWindow,
  isLeftWindow,
  setLeftWindow,
  widthChangeTrigger,
  ...props
}) => {
  const [sp, setSp] = useState([]);
  const [sl, setSl] = useState({});

  const [selectedDate, setSelectedDate] = useState(defaultDate);

  const handleNewBooking = () => {
    setLeftWindow(!isLeftWindow);
  };

  const handleSearch = () => {
    setRightWindow(!isRightWindow);
  };

  const handleChange = (data: any): boolean | void => {
    console.log('SACalendar onChange:', data);
    if (data?.type === 'SLOT_DROP') {
      const answer = window.confirm('Do you confirm the changes?');
      return answer;
    }
  };

  const [mode, setMode] = useState(ECalendarMode.DAILY);
  const [view, setView] = useState(ECalendarView.VERTICAL);

  const [infinite, setInfinite] = useState(false);
  const [partial, setPartial] = useState(false);

  useEffect(() => {
    if (mode === ECalendarMode.MONTHLY) {
      setView(ECalendarView.VERTICAL);
    }
  }, [view, mode]);

  useEffect(() => {
    setSp(newSpaces);

    if (props.api) {
      fetchData(mode, selectedDate).then((data) => setSl(data));
    } else setSl(newSlots);
  }, [mode, selectedDate]);

  const horizontal =
    view === ECalendarView.HORIZONTAL && mode !== ECalendarMode.MONTHLY;
  const weeklyComponents =
    mode == ECalendarMode.WEEKLY || mode == ECalendarMode.MONTHLY;

  const eventComponent = weeklyComponents ? EventWeeklyComponent : Slot;
  const dragOverlayComponent = weeklyComponents
    ? DragOverlayEventWeeklyComponent
    : Slot;
  const spaceComponent = horizontal ? SpaceHorizontalView : Space;

  const [startTime, setStartTime] = useState<string | undefined>();
  const [endTime, setEndTime] = useState<string | undefined>();
  const [resourceId, setResourceId] = useState<string | undefined>();

  const [scrollTo, setScrollTo] = useState<any>();

  const handleScrollToClick = () =>
    setScrollTo({ startTime, endTime, resourceId });

  const [hourVertical, setHourVertical] = useState<number | undefined>(63);
  const [hourHorizontal, setHourHorizontal] = useState<number | undefined>(82);
  const [hourSize, setHourSize] = useState<any>();

  const handleSizeClick = () =>
    setHourSize({
      vertical: hourVertical,
      horizontal: hourHorizontal,
    });

  return (
    <div css={container}>
      <Header handleNewBooking={handleNewBooking} handleSearch={handleSearch} />
      <div css={bodyContainer}>
        <div css={mainContainer}>
          <div css={columnContainer}>
            {props.scrollTo === true && (
              <div
                css={{
                  padding: '20px 60px',
                  display: 'flex',
                  alignItems: 'center',
                  flexWrap: 'wrap',
                  gap: 10,
                  span: {
                    fontSize: '1.5em',
                  },
                }}
              >
                <span>Start time</span>
                <input
                  type="time"
                  value={startTime || ''}
                  onChange={(e) => setStartTime(e.target.value)}
                />
                <button onClick={() => setStartTime(undefined)}>X</button>
                <span>End time</span>
                <input
                  type="time"
                  value={endTime || ''}
                  onChange={(e) => setEndTime(e.target.value)}
                />
                <button onClick={() => setEndTime(undefined)}>X</button>
                <span>Resource ID</span>
                <select
                  value={resourceId || ''}
                  onChange={(e) => setResourceId(e.target.value)}
                >
                  <option key="-" value="">
                    -
                  </option>
                  {sp.map((item: any) => (
                    <option key={item.id} value={item.id}>
                      {`${item.name} (ID: ${item.id})`}
                    </option>
                  ))}
                </select>
                <button onClick={() => setResourceId(undefined)}>X</button>
                <button onClick={handleScrollToClick}>Scroll To</button>
                <div css={{ width: '100%' }} />
                <span>Hour vertical</span>
                <input
                  type="number"
                  value={hourVertical || 0}
                  onChange={(e) => setHourVertical(Number(e.target.value))}
                  css={{ width: 50 }}
                />
                <button onClick={() => setHourVertical(undefined)}>X</button>
                <span>Hour horizontal</span>
                <input
                  type="number"
                  value={hourHorizontal || 0}
                  onChange={(e) => setHourHorizontal(Number(e.target.value))}
                  css={{ width: 50 }}
                />
                <button onClick={() => setHourHorizontal(undefined)}>X</button>
                <button onClick={handleSizeClick}>Set sizes</button>
              </div>
            )}
            <FilterLine
              mode={mode}
              setMode={setMode}
              view={view}
              setView={setView}
              setDate={setSelectedDate}
              infinite={infinite}
              setInfinite={setInfinite}
              partial={partial}
              setPartial={setPartial}
            />
            <SACalendar
              spaces={sp}
              widthChangeTrigger={widthChangeTrigger}
              slots={sl as ISlotsEventsAndEventsWithSpaces}
              EventComponent={eventComponent}
              DragOverlayComponent={dragOverlayComponent}
              onChange={handleChange}
              ResourceGroupHeader={spaceComponent}
              options={{
                date: selectedDate,
                dragAndDrop: props.dnd || false,
                infiniteScrolling: infinite,
                partialRendering: partial,
                resize: true,
                mode,
                view,
                // dndStepLength: 10,
                hourSize,
                addNewSlotButton: {
                  duration: 40,
                  step: 20,
                },
                scrollTo,
              }}
              resourceId={933}
            />
          </div>
          <SlotContainer
            isRightWindow={isRightWindow}
            setRightWindow={setRightWindow}
          />
        </div>
      </div>
    </div>
  );
};
