import { type FC, useEffect, useMemo, useRef, useState } from 'react';
import { useQuery } from 'react-query';

import { type AxiosResponse } from 'axios';
import { format } from 'date-fns';
import Box from '@material-hu/mui/Box';
import CircularProgress from '@material-hu/mui/CircularProgress';
import Stack from '@material-hu/mui/Stack';
import { styled } from '@material-hu/mui/styles';

import HuChips from '@material-hu/components/design-system/Chip';
import HuTabs from '@material-hu/components/design-system/Tabs';

import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import usePermissions from 'src/hooks/usePermissions';
import {
  getCelebrationsConfig,
  getUpcomingCelebrations,
} from 'src/services/upcomingCelebrations';
import {
  CelebrationType,
  type UpcomingCelebrationsResponse,
} from 'src/types/upcomingCelebrations';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { UserPermissions } from 'src/utils/permissions';
import { getDateTitle } from 'src/utils/upcomingCelebrations';

import { UpcomingCelebrationsList } from 'src/components/dashboard/upcomingCelebrations';
import { upcomingCelebrationsKeys } from 'src/components/dashboard/upcomingCelebrations/queries';

const Container = styled(Box)(({ theme }) => ({
  ' & .MuiTabs-root': {
    padding: theme.spacing(0, 2),
    '& .MuiButtonBase-root': {
      whiteSpace: 'break-spaces',
      minWidth: '80px',
    },
  },
  '& .MuiBox-root .loadingMoreRef': {
    height: '30px',
  },
  '& .MuiToggleButton-root': {
    '&:not(.Mui-selected)': {
      '&:hover': {
        backgroundColor: 'rgba(0, 0, 0, 0.12)',
      },
      backgroundColor: 'rgba(0, 0, 0, 0.08)',
    },
    border: '0px',
    borderRadius: '16px !important',
    marginRight: '8px',
    padding: '7px 10px',
    fontSize: '13px',
    lineHeight: '18px',
    height: '34px',
    textTransform: 'none',
  },
}));

const { VIEW_BIRTHDAYS, VIEW_ANNIVERSARIES } = UserPermissions;

const UpcomingCelebrationsTabs: FC = () => {
  const [filter, setFilter] = useState<CelebrationType>(CelebrationType.IDLE);
  const [toggleButtonGroupHeight, setToggleButtonGroupHeight] = useState(0);
  const toggleButtonGroupRef = useRef<HTMLDivElement | null>(null);
  const [selectedTab, setSelectedTab] = useState(0);

  const { t } = useTranslation('celebrations');
  const showGeneralError = useGeneralError();
  const { user } = useAuth();
  const { hasAll: canViewBirthdays } = usePermissions([VIEW_BIRTHDAYS]);
  const { hasAll: canViewAnniversaries } = usePermissions([VIEW_ANNIVERSARIES]);
  const { hasAll: canSeeAllCelebrations } = usePermissions([
    VIEW_ANNIVERSARIES,
    VIEW_BIRTHDAYS,
  ]);

  const celebrationsDatesQuery = useQuery(
    upcomingCelebrationsKeys.celebrationDates(false, false, filter),
    () =>
      getUpcomingCelebrations({
        celebrationType: filter,
      }),
    {
      select: (response: AxiosResponse<UpcomingCelebrationsResponse>) => [
        format(new Date(), 'yyyy-MM-dd'),
        ...response.data.upcomingCelebrationDates,
      ],
      onError: err => showGeneralError(err, t('error_get_nexts_celebrations')),
      enabled: false,
    },
  );

  const celebrationsConfigQuery = useQuery(
    upcomingCelebrationsKeys.celebrationsConfig(),
    () => getCelebrationsConfig(),
    {
      select: response => response.data,
    },
  );

  const birthdayConfig = celebrationsConfigQuery.data?.birthdayConfiguration;

  const hasSegmentBirthday =
    birthdayConfig?.segmentVisualizations &&
    birthdayConfig?.enableBirthdaySegmentation &&
    birthdayConfig?.segmentationGroup !== null;

  const isSegmmentBirthdayAvailable = hasSegmentBirthday && canViewBirthdays;

  // Set a fallback value when params change
  useEffect(() => {
    if (celebrationsConfigQuery.isLoading) {
      return;
    }

    if (canViewBirthdays) {
      if (canViewAnniversaries) {
        if (hasSegmentBirthday) {
          setFilter(CelebrationType.BIRTHDAY_SEGMENTED);
        } else {
          setFilter(CelebrationType.ALL);
        }
      } else {
        if (hasSegmentBirthday) {
          setFilter(CelebrationType.BIRTHDAY_SEGMENTED);
        } else {
          setFilter(CelebrationType.BIRTHDAY);
        }
      }
    } else {
      if (canViewAnniversaries) {
        setFilter(CelebrationType.ANNIVERSARY);
      } else {
        setFilter(CelebrationType.ALL);
      }
    }

    return () => {
      setFilter(CelebrationType.IDLE);
    };
  }, [
    hasSegmentBirthday,
    canViewBirthdays,
    canViewAnniversaries,
    celebrationsConfigQuery.isLoading,
  ]);

  useEffect(() => {
    if (!celebrationsDatesQuery.isFetching && filter !== CelebrationType.IDLE) {
      celebrationsDatesQuery.refetch();
    }
  }, [filter]);

  const tabs = useMemo(() => {
    if (!celebrationsDatesQuery?.data?.length) return [];

    const newTabs = celebrationsDatesQuery?.data?.map(date => ({
      id: date,
      title: getDateTitle(date, user || undefined),
      content: (
        <UpcomingCelebrationsList
          celebrationDate={date}
          filter={filter}
          height={`calc(384px - ${toggleButtonGroupHeight}px)`}
        />
      ),
    }));

    return newTabs?.filter(tab => !!tab && !!tab.title);
  }, [celebrationsDatesQuery, filter]);

  const shouldShowPills =
    (canSeeAllCelebrations ||
      (isSegmmentBirthdayAvailable &&
        !birthdayConfig?.hideNotSegmentedOption)) &&
    !celebrationsConfigQuery.isLoading;

  useEffect(() => {
    if (toggleButtonGroupRef.current) {
      setToggleButtonGroupHeight(toggleButtonGroupRef.current.offsetHeight);
    } else {
      setToggleButtonGroupHeight(0);
    }
  }, [shouldShowPills]);

  const isLoading =
    celebrationsDatesQuery.isLoading && celebrationsConfigQuery.isLoading;

  return (
    <Container>
      {isLoading && (
        <Stack
          sx={{
            p: 2,
            alignItems: 'center',
            justifyContent: 'center',
            height: '100%',
          }}
        >
          <CircularProgress />
        </Stack>
      )}
      {shouldShowPills && (
        <Stack
          ref={toggleButtonGroupRef}
          direction="row"
          sx={{ px: 2, flexWrap: 'wrap', gap: 1, mb: 2 }}
        >
          {isSegmmentBirthdayAvailable && (
            <HuChips
              label={t('birthdays_segmented', {
                name:
                  birthdayConfig?.customGroupName ??
                  birthdayConfig?.segmentationGroup?.name,
              })}
              isSelected={filter === CelebrationType.BIRTHDAY_SEGMENTED}
              onClick={() => setFilter(CelebrationType.BIRTHDAY_SEGMENTED)}
            />
          )}
          {canSeeAllCelebrations && (
            <HuChips
              label={t('all_celebrations')}
              isSelected={filter === CelebrationType.ALL}
              onClick={() => setFilter(CelebrationType.ALL)}
            />
          )}
          {canViewAnniversaries && (
            <HuChips
              label={t('anniversaries')}
              isSelected={filter === CelebrationType.ANNIVERSARY}
              onClick={() => setFilter(CelebrationType.ANNIVERSARY)}
            />
          )}
          {canViewBirthdays && !birthdayConfig?.hideNotSegmentedOption && (
            <HuChips
              label={t('birthdays')}
              isSelected={filter === CelebrationType.BIRTHDAY}
              onClick={() => setFilter(CelebrationType.BIRTHDAY)}
            />
          )}
        </Stack>
      )}
      {!!tabs.length && (
        <Box id="celebrations">
          <HuTabs
            tabs={tabs.map(tab => ({ label: tab.title, value: tab.id }))}
            onTabChange={(_value, index) => setSelectedTab(index)}
            defaultValue={selectedTab}
          />
          {tabs[selectedTab]?.content}
        </Box>
      )}
    </Container>
  );
};

export default UpcomingCelebrationsTabs;
