/** @jsxRuntime classic */
/** @jsx jsx */
import { useTheme } from '@emotion/react';
import { css, jsx } from '@emotion/react';
import dayjs from 'dayjs';
import React, { Dispatch, SetStateAction, useEffect, useState } from 'react';
import { BnIcon, Toggle } from '../../components';
import { WeekDay } from '../../components/DateInput/comp/Date';
import { useTypography } from '../../hooks/useTypography';

import { ResourceObj } from '../../types/entities/resources';
import { ResourcesToProduct } from '../../types/entities/resources-to-products';
import { Icons } from '../../types/theme';
import { DayCheck } from './dateCheck';
import { DayCheckBox } from './dayCheckbox';
import { dateContainerCss, emptySlot } from './style';

const strDayToNum = {
  Mon: 2,
  Tue: 3,
  Wed: 4,
  Thu: 5,
  Fri: 6,
  Sat: 7,
  Sun: 8,
};

const DayOfWeek = (day: number) => {
  switch (day) {
    case 2:
      return 'Mon';
    case 3:
      return 'Tue';
    case 4:
      return 'Wed';
    case 5:
      return 'Thu';
    case 6:
      return 'Fri';
    case 7:
      return 'Sat';
    case 8:
      return 'Sun';
    default:
      return '';
  }
};

interface IDateOption {
  title: string;
  subTitle: string;
}

interface IEventDetail {
  id: number;
  date: string;
  dayOfWeek: number;
}

interface IDateAddon {
  label: string;
  options: IDateOption[];
  events: ResourcesToProduct;
  selected: number[];
  setSelected: Dispatch<SetStateAction<number[]>>;
  clearTrigger: boolean;
}
interface IMax {
  index: number;
  value: number;
}

export const DateAddon = ({
  label,
  options,
  events,
  selected: selectedEvents,
  setSelected: setSelectedEvents,
  clearTrigger,
}: IDateAddon) => {
  const [filterDays, setFilterDays] = useState<string[]>([]);
  const [isSelectAll, setSelectAll] = useState<boolean>(false);
  const colors = useTheme();
  const { typography } = useTypography();
  const [monthMatrix, setMonth] = useState<IEventDetail[][]>([]);
  const [relevantDays, setRelevantDays] = useState<number[]>([]);
  const [max, setMax] = useState<IMax | null>();
  // const [selectedEvents, setSelectedEvents] = useState<number[]>([]);

  const selectAll = () => {
    setSelectedEvents(events.resources.map((re) => re.id));
  };

  useEffect(() => {
    if (isSelectAll) {
      selectAll();
    } else {
      setSelectedEvents([]);
    }
  }, [isSelectAll]); // eslint-disable-line react-hooks/exhaustive-deps

  const handleChange = (val: string) => {
    if (filterDays.includes(val)) {
      setFilterDays(filterDays.filter((x) => x !== val));
    } else {
      setFilterDays([...filterDays, val]);
    }
  };

  useEffect(() => {
    setFilterDays([]);
    setSelectAll(false);
  }, [clearTrigger]);

  useEffect(() => {
    const array = [...events.resources];
    if (events?.resources?.length !== 0) {
      const fullMonth = [];
      const month = [];
      let week: number[] = [];
      let fullWeek: IEventDetail[] = [];
      let maxDays: IMax = { index: 0, value: 0 };
      array
        .sort((a, b) => {
          return (
            dayjs((a as ResourceObj).startDate).valueOf() -
            dayjs((b as ResourceObj).startDate).valueOf()
          );
        })
        .forEach((resource) => {
          const day: WeekDay = (dayjs(
            (resource as ResourceObj).startDateString
          ).format('ddd') as unknown) as WeekDay;

          const dayOfWeek = strDayToNum[String(day)];
          if (week?.length !== 0 && dayOfWeek <= week[week?.length - 1]) {
            month.push(week);
            if (maxDays.value <= week?.length) {
              maxDays = {
                index: month?.length - 1,
                value: week?.length,
              };
            }
            week = [];
            week.push(dayOfWeek);

            fullMonth.push(fullWeek);
            fullWeek = [];
            fullWeek.push({
              id: resource.id,
              date: (resource as ResourceObj).startDateString,
              dayOfWeek: dayOfWeek,
            });
          } else {
            week.push(dayOfWeek);
            fullWeek.push({
              id: resource.id,
              date: (resource as ResourceObj).startDateString,
              dayOfWeek: dayOfWeek,
            });
          }
        });
      if (week?.length !== 0) {
        month.push(week);
      }
      if (fullWeek?.length !== 0) {
        fullMonth.push(fullWeek);
      }

      setMax(maxDays);
      setRelevantDays(month[maxDays.index]);
      setMonth(fullMonth);
    }
  }, [events]); // eslint-disable-line react-hooks/exhaustive-deps

  const handleChoose = (val: number) => {
    if (selectedEvents.includes(val)) {
      setSelectedEvents(selectedEvents.filter((event) => event !== val));
    } else {
      setSelectedEvents([...selectedEvents, val]);
    }
  };

  useEffect(() => {
    if (filterDays?.length !== 0) {
      const arr: number[] = [];
      monthMatrix.forEach((week) => {
        week.forEach((d) => {
          if (filterDays.includes(DayOfWeek(d.dayOfWeek))) {
            arr.push(d.id);
          }
        });
      });
      setSelectedEvents(arr);
    } else {
      setSelectedEvents([]);
    }
  }, [filterDays]); // eslint-disable-line react-hooks/exhaustive-deps

  const renderEmptySlots = (week: IEventDetail[], isTinyView: boolean) => {
    const arr = [];
    if (max) {
      if (relevantDays[0] !== week[0].dayOfWeek) {
        for (let i = 0; i < (max as IMax).value - week.length; i++) {
          arr.push(<div css={emptySlot(isTinyView)} />);
        }
      }
    }
    return arr;
  };

  return (
    <div css={dateContainerCss(colors, typography)}>
      <label className="title">{label}</label>
      <div>
        {options.map((scheduler, index) => {
          return (
            <div className="schedularContainer" key={index}>
              <div className="schedularHeader">
                <BnIcon icon={Icons.calendar} />
                <div>
                  <h3>{scheduler.title}</h3>
                  <h3>{scheduler.subTitle}</h3>
                </div>
              </div>
              <div className="toggleContainer">
                <Toggle
                  checked={isSelectAll}
                  setPressed={setSelectAll}
                  label="Select All"
                />
              </div>
              <div style={{ display: 'flex' }}>
                {relevantDays.map((day, j) => {
                  return (
                    <DayCheck
                      key={j}
                      value={DayOfWeek(day)}
                      isTinyView={relevantDays?.length > 5}
                      isChecked={filterDays.includes(DayOfWeek(day))}
                      handleChange={handleChange}
                    />
                  );
                })}
              </div>

              {monthMatrix.map((week, k) => {
                const isTiny = relevantDays?.length > 5;
                return (
                  <div key={k} className="daysContainer">
                    {k === 0 && renderEmptySlots(week, isTiny)}
                    {week.map((day, j) => {
                      return (
                        <DayCheckBox
                          key={j}
                          onClick={() => handleChoose(day.id)}
                          addon={day}
                          chosen={selectedEvents.includes(day.id)}
                          isTinyView={isTiny}
                        />
                      );
                    })}
                    {k !== 0 && renderEmptySlots(week, isTiny)}
                  </div>
                );
              })}
            </div>
          );
        })}
      </div>
    </div>
  );
};
