import { FC, useState, Fragment, useEffect } from 'react';
import { Helmet } from 'react-helmet-async';
import { useQuery } from 'react-query';

import Box from '@material-hu/mui/Box';
import CircularProgress from '@material-hu/mui/CircularProgress';
import Container from '@material-hu/mui/Container';
import Grid from '@material-hu/mui/Grid';
import Typography from '@material-hu/mui/Typography';

import { useAuth } from 'src/contexts/JWTContext';
import { useMobileLayout } from 'src/hooks/useMobileLayout';
import { useMobileToken } from 'src/hooks/useMobileToken';
import { getEventsBySite } from 'src/services/nemakEvents';
import { getUserSegmentation } from 'src/services/users';
import {
  getUserSide,
  sortEventsArray,
  filterByDate,
  filterByCapacity,
} from 'src/utils/events';
import { formatTitle } from 'src/utils/helmetUtils';

import { userKeys } from 'src/components/dashboard/users/queries';

import EventCard from './components/EventCard';
import EventsEmpty from './components/EventsEmpty';
import EventsHeader from './components/EventsHeader';
import FiltersDialog from './components/FiltersDialog';
import { useTranslation } from './components/i18n';
import { eventsKeys } from './components/queries';

const Events: FC = () => {
  const { t } = useTranslation();
  const { user } = useAuth();

  const [searchInput, setSearchInput] = useState('');
  const [filteredEvents, setFilteredEvents] = useState(null);
  const [sortedEvents, setSortedEvents] = useState([]);
  const [openFilterDialog, setOpenFilterDialog] = useState(false);

  const [orderBy, setOrderBy] = useState('name');
  const [order, setOrder] = useState('ASC');
  const [startDateValue, setStartDateValue] = useState(null);
  const [endDateValue, setEndDateValue] = useState(null);
  const [minCapacity, setMinCapacity] = useState(null);
  const [maxCapacity, setMaxCapacity] = useState(null);

  useMobileToken();
  useMobileLayout();

  const { isLoading: isLoadingSegmentationData, data: segmentationData } =
    useQuery(userKeys.segmentation(user.id), () =>
      getUserSegmentation(user.id),
    );

  let userSite = null;

  if (segmentationData) {
    userSite = getUserSide(segmentationData.data);
  }

  const { data, isLoading } = useQuery(
    eventsKeys.site(userSite),
    () => getEventsBySite(userSite),
    {
      enabled: !!userSite,
    },
  );

  useEffect(() => {
    if (data && Array.isArray(data.data)) {
      const lowerCaseSearch = searchInput?.toLowerCase();
      const filtered = data.data.filter(event =>
        event.Name.toLowerCase().includes(lowerCaseSearch),
      );
      setFilteredEvents(filtered);
    } else {
      setFilteredEvents([]);
    }
  }, [data, searchInput]);

  useEffect(() => {
    if (!filteredEvents) return;

    let sorted = sortEventsArray(filteredEvents, orderBy, order);
    sorted = filterByDate(sorted, startDateValue, endDateValue);
    sorted = filterByCapacity(sorted, minCapacity, maxCapacity);

    setSortedEvents(sorted);
  }, [
    filteredEvents,
    orderBy,
    order,
    minCapacity,
    maxCapacity,
    startDateValue,
    endDateValue,
  ]);

  const handleSearchInputChange = searchValue => setSearchInput(searchValue);

  const hasApplyFilter =
    startDateValue !== null ||
    endDateValue !== null ||
    minCapacity !== '' ||
    maxCapacity !== '';

  const onApplyFilters = filtersData => {
    setOrderBy(filtersData.orderBy);
    setOrder(filtersData.order);
    setMinCapacity(filtersData.minCapacity);
    setMaxCapacity(filtersData.maxCapacity);
    setStartDateValue(filtersData.startDate);
    setEndDateValue(filtersData.endDate);
  };

  return (
    <>
      <Helmet>
        <title>{formatTitle(t('EVENTS'))}</title>
      </Helmet>
      <Box
        sx={{
          backgroundColor: 'background.default',
          minHeight: '100%',
          pt: 2,
          pb: 8,
        }}
      >
        <Container maxWidth="lg">
          {isLoading && (
            <Box
              sx={{
                display: 'flex',
                width: '100%',
                justifyContent: 'center',
                mt: 2,
              }}
            >
              <CircularProgress />
            </Box>
          )}
          {!isLoading && data?.data.StatusCode === '0' && (
            <EventsEmpty message={t('NO_EVENTS_LOADED')} />
          )}
          {!isLoadingSegmentationData && !userSite && (
            <EventsEmpty
              message={t('NO_EVENTS_LOADED')}
              isUserSite
            />
          )}
          {!isLoading && data?.data.StatusCode !== '0' && data && (
            <Box sx={{ mt: 2 }}>
              <Box
                sx={{
                  display: 'flex',
                  justifyContent: 'space-between',
                  mb: 4,
                  alignItems: 'center',
                }}
              >
                <Typography
                  color="textPrimary"
                  variant="h5"
                  component="h1"
                >
                  {t('EVENTS')}
                </Typography>
                <EventsHeader
                  onSearchInputChange={handleSearchInputChange}
                  onOpenFilterDialog={() => setOpenFilterDialog(true)}
                />
              </Box>
              <Grid
                container
                spacing={3}
              >
                {sortedEvents?.map((event, i) => (
                  <Fragment key={i}>
                    <Grid
                      item
                      key={event.id}
                      lg={4}
                      md={6}
                      xs={12}
                    >
                      <EventCard {...event} />
                    </Grid>
                  </Fragment>
                ))}
                {sortedEvents?.length === 0 &&
                  (searchInput !== '' || hasApplyFilter) && (
                    <EventsEmpty message={t('NO_EVENTS_FOUND')} />
                  )}
              </Grid>
              {openFilterDialog && (
                <FiltersDialog
                  open={openFilterDialog}
                  onClose={() => setOpenFilterDialog(false)}
                  orderBy={orderBy}
                  order={order}
                  startDateValue={startDateValue}
                  endDateValue={endDateValue}
                  minCapacity={minCapacity}
                  maxCapacity={maxCapacity}
                  onApplyFilters={onApplyFilters}
                />
              )}
            </Box>
          )}
        </Container>
      </Box>
    </>
  );
};

export default Events;
