import { type ReactNode, useCallback, useState } from 'react';
import { useQuery } from 'react-query';

import { useDebounce as useDebounceHU } from '@material-hu/hooks/useDebounce';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import HuDropdown from '@material-hu/components/design-system/Dropdown';
import HuSearch from '@material-hu/components/design-system/Inputs/Search';
import HuListItem from '@material-hu/components/design-system/List/components/ListItem';
import HuSkeleton from '@material-hu/components/design-system/Skeleton';

import useGeneralError from 'src/hooks/useGeneralError';
import { getShiftRegions, type ShiftRegion } from 'src/services/shifts';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { useShiftsSelectionActions } from '../contexts/ShiftsSelectionContext';
import { shiftsKeys } from '../queries';

type Site = { id: number; name: string };

type Props = {
  selectedSite: Site | null;
  setSelectedSite: (site: Site | null) => void;
  filtersComponent: ReactNode;
  onSiteFilterChange?: (site: Site | null) => void;
};

const TableFilters = ({
  selectedSite,
  setSelectedSite,
  filtersComponent,
  onSiteFilterChange,
}: Props) => {
  const { t } = useLokaliseTranslation([
    'general',
    'regions_sites',
    'time_off',
    'work_schedules',
  ]);
  const [openSitesDropdown, setOpenSitesDropdown] = useState(false);
  const [regionSearch, setRegionSearch] = useState('');
  const debouncedRegionSearch = useDebounceHU(regionSearch);
  const showGeneralError = useGeneralError();
  const closeOverlayCleanup = useCallback(() => {
    setOpenSitesDropdown(false);
    setRegionSearch('');
  }, []);
  useShiftsSelectionActions({ closeOverlayCleanup });

  const { data: regionsData, isLoading: isLoadingRegions } = useQuery(
    shiftsKeys.regions({ search: debouncedRegionSearch || undefined }),
    ({ signal }) =>
      getShiftRegions(
        {
          page: 1,
          limit: 300,
          search: debouncedRegionSearch || undefined,
        },
        signal,
      ),
    {
      onError: err => {
        showGeneralError(err, t('work_schedules:regions_error'));
      },
      staleTime: 1000 * 60 * 2,
    },
  );

  const sortedRegions = regionsData?.data.items
    .slice()
    .sort((a, b) => a.title.localeCompare(b.title))
    .map(group => ({
      ...group,
      sites: group.sites
        .slice()
        .sort((s1, s2) => s1.name.localeCompare(s2.name)),
    }));

  const handleSiteSelection = (site: ShiftRegion['sites'][number]) => {
    setSelectedSite(site);
    setOpenSitesDropdown(false);
    onSiteFilterChange?.(site);
  };

  const cleanDropdownFilter = () => {
    setSelectedSite(null);
    setRegionSearch('');
    setOpenSitesDropdown(false);
    onSiteFilterChange?.(null);
  };

  const showLoading = isLoadingRegions;

  return (
    <Stack sx={{ alignItems: 'stretch', flexDirection: 'row', gap: 1 }}>
      <HuDropdown
        open={openSitesDropdown}
        onClose={() => {
          setOpenSitesDropdown(false);
          setRegionSearch('');
        }}
        onOpen={() => {
          setOpenSitesDropdown(true);
        }}
        label={selectedSite ? selectedSite.name : t('regions_sites:sites')}
        buttonProps={{
          sx: { height: 40 },
        }}
      >
        <Stack sx={{ width: 312, maxHeight: 424 }}>
          <HuSearch
            value={regionSearch}
            onChange={setRegionSearch}
            placeholder={t('general:search')}
            aria-label={t('general:search')}
            fullWidth
            sx={{ p: 2, height: 88 }}
          />
          {showLoading && (
            <Stack sx={{ px: 2, gap: 2, mb: 3 }}>
              <HuSkeleton height={32} />
              <HuSkeleton height={32} />
              <HuSkeleton height={32} />
              <HuSkeleton height={32} />
            </Stack>
          )}
          {!showLoading && (
            <>
              <Stack sx={{ flex: 1, overflowY: 'auto', height: 268 }}>
                {sortedRegions &&
                  sortedRegions?.length > 0 &&
                  sortedRegions.map(group => {
                    if (!group.sites.length) return null;
                    return (
                      <Stack key={group.id}>
                        <Typography
                          variant="globalXS"
                          fontWeight="fontWeightSemiBold"
                          sx={{
                            p: 2,
                            mb: 1,
                            height: 36,
                            '.MuiTypography-root': {
                              color: ({ palette }) =>
                                palette.new.text.neutral.default,
                            },
                          }}
                        >
                          {group.title}
                        </Typography>
                        {group.sites.map(item => (
                          <HuListItem
                            key={item.id}
                            text={{ title: item.name }}
                            onClick={() => {
                              handleSiteSelection(item);
                            }}
                            selected={selectedSite?.id === item.id}
                            sx={{
                              '.MuiTypography-root': {
                                fontWeight: 400,
                              },
                            }}
                          />
                        ))}
                      </Stack>
                    );
                  })}
                {sortedRegions && sortedRegions?.length === 0 && (
                  <Typography
                    variant={'globalS'}
                    sx={{ px: 2, pb: 3, pt: 1 }}
                  >
                    {t('time_off:no_results')}
                  </Typography>
                )}
              </Stack>
            </>
          )}
          <Stack
            sx={{
              borderTop: ({ palette }) =>
                `1px solid ${palette.new.border.neutral.default}`,
              flexDirection: 'row',
              gap: 2,
              p: 2,
            }}
          >
            <Button
              variant="tertiary"
              onClick={cleanDropdownFilter}
              fullWidth
            >
              {t('general:clean')}
            </Button>
          </Stack>
        </Stack>
      </HuDropdown>
      {filtersComponent}
    </Stack>
  );
};

export default TableFilters;
