import React, { Dispatch, SetStateAction, useCallback } from 'react';
import type { SyntheticEvent } from 'react';
import dayjs from 'dayjs';
import type { Dayjs } from 'dayjs';

import Typography from '@mui/material/Typography';

import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import Box from '@mui/material/Box';
import clsx from 'clsx';
import { textToDateDMY } from '../helpers';
import { configListRange, oneQuarter } from './helpers';
import createClasses from './styles';

export interface DateRangeProps {
  startDate?: Date | null;
  endDate?: Date | null;
  setStartDate: Dispatch<SetStateAction<Date | null>>;
  setEndDate: Dispatch<SetStateAction<Date | null>>;
  setSelectDate: Dispatch<SetStateAction<Date | undefined>>;
}

const DateRange = (props: DateRangeProps) => {
  const { setStartDate, setEndDate, startDate, endDate, setSelectDate } = props;

  const styles = createClasses();

  const handleChoosePeriod = useCallback(
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    //@ts-ignore
    (e: SyntheticEvent<HTMLDivElement> | string, modeText?: boolean) => {
      let mode;
      if (typeof e !== 'string' && e.currentTarget && e.currentTarget.id) {
        mode = e.currentTarget.id;
      } else {
        mode = e;
      }
      let curStartDate: string | Dayjs;
      let curEndDate: string | Dayjs;
      const periodDates = oneQuarter(new Date());
      switch (mode) {
        case 'days':
          curStartDate = dayjs().subtract(6, 'days');
          curEndDate = dayjs();
          if (modeText) {
            return {
              label: `${dayjs(curStartDate).format('DD/MM')} - ${dayjs(curEndDate).format(
                'DD/MM'
              )}`,
              date: `${dayjs(curStartDate).format('DD/MM/YYYY')} - ${dayjs(curEndDate).format(
                'DD/MM/YYYY'
              )}`
            };
          }
          setStartDate(new Date(curStartDate.toString()));
          setEndDate(new Date(curEndDate.toString()));
          setSelectDate(new Date(curStartDate.toString()));
          break;
        case 'month':
          curStartDate = dayjs().subtract(1, 'month');
          curEndDate = dayjs();
          if (modeText) {
            return {
              label: `${dayjs(curStartDate).format('DD/MM')} - ${dayjs(curEndDate).format(
                'DD/MM'
              )}`,
              date: `${dayjs(curStartDate).format('DD/MM/YYYY')} - ${dayjs(curEndDate).format(
                'DD/MM/YYYY'
              )}`
            };
          }
          setStartDate(new Date(curStartDate.toString()));
          setEndDate(new Date(curEndDate.toString()));
          setSelectDate(new Date(curStartDate.toString()));

          break;
        case 'quarter':
          if (modeText) {
            return {
              label: `${dayjs(periodDates.start, 'MM/DD/YYYY').format('DD/MM')} - ${dayjs(
                periodDates.end,
                'MM/DD/YYYY'
              ).format('DD/MM')}`,
              date: `${dayjs(periodDates.start, 'MM/DD/YYYY').format('DD/MM/YYYY')} - ${dayjs(
                periodDates.end,
                'MM/DD/YYYY'
              ).format('DD/MM/YYYY')}`
            };
          }
          setStartDate(new Date(periodDates.start));
          setEndDate(new Date(periodDates.end));
          setSelectDate(new Date(periodDates.start));

          break;
        case 'year':
          curStartDate = dayjs().subtract(1, 'year');
          curEndDate = dayjs();
          if (modeText) {
            return {
              label: `${dayjs(curStartDate).format('MMM YY')} - ${dayjs(curEndDate).format(
                'MMM YY'
              )}`,
              date: `${dayjs(curStartDate).format('DD/MM/YYYY')} - ${dayjs(curEndDate).format(
                'DD/MM/YYYY'
              )}`
            };
          }
          setStartDate(new Date(curStartDate.toString()));
          setEndDate(new Date(curEndDate.toString()));
          setSelectDate(new Date(curStartDate.toString()));

          break;
        default:
      }
    },
    [setEndDate, setSelectDate, setStartDate]
  );

  const isChecked = useCallback(
    (id: string) => {
      if (
        startDate &&
        `${handleChoosePeriod(id, true)?.date}` === textToDateDMY(startDate, endDate)
      ) {
        return true;
      }
      return false;
    },
    [endDate, handleChoosePeriod, startDate]
  );

  return (
    <Box component="section">
      <Typography className={styles.title}>Date Range</Typography>
      <List disablePadding className={styles.list}>
        {configListRange.map(item => (
          <ListItem
            button
            data-testid={item.id}
            key={item.id}
            className={clsx(styles.listItem, isChecked(item.id) && styles.listItemSelected)}
            onKeyDown={handleChoosePeriod}
            onClick={handleChoosePeriod}
            id={item.id}
          >
            <Typography className={styles.listItemText}>{item.name}</Typography>
            <Typography className={styles.listItemText}>
              {handleChoosePeriod(item.id, true)?.label}
            </Typography>
          </ListItem>
        ))}
      </List>
    </Box>
  );
};

DateRange.defaultProps = {
  startDate: '',
  endDate: ''
};

export default DateRange;
