import { type FC, useMemo, useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { type UseInfiniteQueryOptions } from 'react-query';

import { type AxiosResponse } from 'axios';
import Stack from '@material-hu/mui/Stack';

import CollapsibleAutocompleteSelector from '@material-hu/components/composed-components/CollapsibleAutocompleteSelector';
import DatePickerWithOptions from '@material-hu/components/composed-components/DatePickerWithOptions';
import HuAccordion from '@material-hu/components/design-system/Accordion';
import HuDrawer from '@material-hu/components/design-system/Drawer';

import { useAuth } from 'src/contexts/JWTContext';
import UserCollapsibleAutocompleteSelector from 'src/pages/dashboard/serviceManagement/general/UserCollapsibleAutocompleteSelector';
import {
  type OxxoCollaboratorType,
  ServiceItemTypes,
  type State,
} from 'src/pages/dashboard/serviceManagement/types';
import {
  getCreationDateFilterDescription,
  getStateName,
} from 'src/pages/dashboard/serviceManagement/utils';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { type PaginatedResponse } from 'src/utils/pagination';

import {
  OXXO_COLLABORATOR_TYPE_IDS,
  OXXO_SEGMENTATION_OPTIONS,
} from '../../constants';
import useInfiniteServiceItems from '../../hooks/useInfiniteServiceItems';
import useInfiniteUsersAndAgents from '../../hooks/useInfiniteUsersAndAgents';
import useTaskStates from '../../hooks/useTaskStates';
import { createStaticOptionsQuery } from '../../utils';
import { filterFields } from '../form/form';

type InfiniteQueryParams = { limit: number; name: string };
type InfiniteQueryHookOptions = UseInfiniteQueryOptions<
  AxiosResponse<PaginatedResponse<unknown>>
>;

// Stable module-scope hook: binds `applyCandidateAgentRule: true` without
// recreating per render, keeping CollapsibleAutocompleteSelector's internal
// hook call site consistent.
const useInfiniteServiceItemsWithCandidateRule = (
  params: InfiniteQueryParams,
  options: InfiniteQueryHookOptions,
) =>
  useInfiniteServiceItems(
    { ...params, applyCandidateAgentRule: true },
    options,
  );

type Props = {
  open: boolean;
  onClose: () => void;
  onReset: () => void;
  onApply: (values: any) => void;
  onBack?: () => void;
  showBackButton?: boolean;
  resetDisabled?: boolean;
};

const DEFAULT_EXPANDED = {
  serviceItemsIn: false,
  statesIn: false,
  initiatorsIn: false,
  collaboratorTypesIn: false,
  creationDate: false,
};

const FiltersDrawer: FC<Props> = ({
  open,
  onClose,
  onReset,
  onApply,
  showBackButton = false,
  resetDisabled = false,
}) => {
  const { t, i18n } = useLokaliseTranslation(['service_management', 'general']);
  const { instance } = useAuth();

  const [expanded, setExpanded] =
    useState<Record<keyof typeof DEFAULT_EXPANDED, boolean>>(DEFAULT_EXPANDED);

  const handleExpand = (field: keyof typeof expanded, newExpanded: boolean) => {
    setExpanded(prev => ({ ...prev, [field]: newExpanded }));
  };

  const {
    watch,
    formState: { errors },
  } = useFormContext();

  const { data: taskStates = [] } = useTaskStates(ServiceItemTypes.INCIDENT, {
    refetchOnMount: false,
    refetchOnWindowFocus: false,
  });

  const taskStaticQueryOptions = useMemo(
    () =>
      createStaticOptionsQuery(taskStates, {
        getSearchText: item => t(getStateName(item.name)),
      }),
    [taskStates, t],
  );

  const oxxoStaticQueryOptions = useMemo(
    () => createStaticOptionsQuery(OXXO_SEGMENTATION_OPTIONS.items),
    [],
  );

  const autocompleteLabelProps = useMemo(() => {
    return {
      selectAllLabel: t('select_all'),
      noResultsLabel: t('empty_results'),
      lackingOptionsMessage: t('empty_results'),
      formatAndMore: (count: number) => t('and_n_items_more', { count }),
      virtualized: true,
      maxHeight: 300,
    };
  }, [t]);

  const isOxxo = OXXO_COLLABORATOR_TYPE_IDS.includes(instance?.id!);

  const applyFiltersDisabled = Object.keys(errors || {})?.length > 0;

  return (
    <HuDrawer
      anchor="right"
      open={open}
      onClose={onClose}
      title={t('filter_by')}
      hasBackButton={showBackButton}
      primaryButtonProps={{
        onClick: onApply,
        children: t('apply'),
        fullWidth: true,
        disabled: applyFiltersDisabled,
      }}
      secondaryButtonProps={{
        onClick: onReset,
        children: t('clean_filters'),
        fullWidth: true,
        disabled: resetDisabled,
      }}
    >
      <Stack sx={{ gap: 2 }}>
        <CollapsibleAutocompleteSelector
          sectionTitle={t('request_types')}
          fieldName={filterFields.serviceItemsIn()}
          infiniteQuery={useInfiniteServiceItemsWithCandidateRule as any}
          isExpanded={expanded.serviceItemsIn}
          setExpanded={newExpanded =>
            handleExpand('serviceItemsIn', newExpanded)
          }
          {...autocompleteLabelProps}
        />
        <CollapsibleAutocompleteSelector<State>
          fieldName={filterFields.statesIn()}
          sectionTitle={t('statuses')}
          customMapper={item => ({
            value: item.id,
            name: t(getStateName(item.name)),
          })}
          infiniteQuery={taskStaticQueryOptions}
          isExpanded={expanded.statesIn}
          setExpanded={newExpanded => handleExpand('statesIn', newExpanded)}
          {...autocompleteLabelProps}
        />
        <UserCollapsibleAutocompleteSelector
          fieldName={filterFields.initiatorsIn()}
          sectionTitle={t('requesters')}
          infiniteQuery={useInfiniteUsersAndAgents}
          isExpanded={expanded.initiatorsIn}
          setExpanded={newExpanded => handleExpand('initiatorsIn', newExpanded)}
          {...autocompleteLabelProps}
        />
        {isOxxo && (
          <CollapsibleAutocompleteSelector<OxxoCollaboratorType>
            fieldName={filterFields.initiatorCollaboratorTypesIn()}
            sectionTitle={t('collaborator_type')}
            isExpanded={expanded.collaboratorTypesIn}
            setExpanded={newExpanded =>
              handleExpand('collaboratorTypesIn', newExpanded)
            }
            infiniteQuery={oxxoStaticQueryOptions as any}
            customMapper={item => ({ value: item.id, name: item.title })}
            getItemId={item => item.id}
            {...autocompleteLabelProps}
          />
        )}
        <HuAccordion
          title={t('creation_date')}
          description={getCreationDateFilterDescription({
            dateRangeValueSelected: true,
            lastSevenDays: false,
            lastFourteenDays: false,
            lastThirtyDays: false,
            fromDate: watch(filterFields.creationDateFrom()),
            toDate: watch(filterFields.creationDateTo()),
            language: i18n.language || 'en',
            t,
          })}
          expanded={expanded.creationDate}
          onChange={(_, newExpanded) => {
            handleExpand('creationDate', newExpanded);
          }}
          elevation={0}
          sx={{
            borderRadius: ({ spacing }) => spacing(1),
            mb: 2,
            backgroundColor: ({ palette }) =>
              palette.new.background.elements.grey,
            '&:before': {
              backgroundColor: 'transparent',
            },
          }}
          disableGutters
          customDetail={
            <DatePickerWithOptions
              showDatePickers
              options={[]}
              startDatePicker={{
                name: filterFields.creationDateFrom(),
                label: t('from'),
                inputProps: { disableFuture: true },
              }}
              endDatePicker={{
                name: filterFields.creationDateTo(),
                label: t('general:until'),
                inputProps: { disableFuture: true },
              }}
            />
          }
        />
      </Stack>
    </HuDrawer>
  );
};

export default FiltersDrawer;
