import { useCallback, useEffect, useMemo, useState } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';

import { type Theme } from '@material-hu/mui/index';
import Stack from '@material-hu/mui/Stack/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 UserCollapsibleAutocompleteSelector from 'src/pages/dashboard/serviceManagement/general/UserCollapsibleAutocompleteSelector';
import {
  ServiceItemTypes,
  type State,
} from 'src/pages/dashboard/serviceManagement/types';
import {
  getApprovalStateName,
  getCreationDateFilterDescription,
} from 'src/pages/dashboard/serviceManagement/utils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  historyApprovalsFilters,
  pendingApprovalsFilters,
} from '../agentWorkspace/form/form';
import {
  type HistoryApprovalsFormValues,
  type PendingApprovalsFormValues,
} from '../agentWorkspace/types';
import useInfiniteServiceItems from '../hooks/useInfiniteServiceItems';
import useInfiniteUsersAndAgents from '../hooks/useInfiniteUsersAndAgents';
import useTaskStates from '../hooks/useTaskStates';
import { createStaticOptionsQuery } from '../utils';

type Props = {
  open: boolean;
  onClose: () => void;
  onApply: () => void;
  onReset: () => void;
  isPending: boolean;
};

type ApprovalsFormValues =
  | PendingApprovalsFormValues
  | HistoryApprovalsFormValues;

const ApprovalsFiltersDrawer = ({
  open,
  onClose,
  onApply,
  onReset,
  isPending,
}: Props) => {
  const { t, i18n } = useLokaliseTranslation(['service_management', 'general']);
  const { control, handleSubmit, clearErrors, setValue } =
    useFormContext<ApprovalsFormValues>();

  const fields = isPending ? pendingApprovalsFilters : historyApprovalsFilters;
  const dateFromField = isPending
    ? pendingApprovalsFilters.createdAtFrom()
    : historyApprovalsFilters.completedAtFrom();
  const dateToField = isPending
    ? pendingApprovalsFilters.createdAtTo()
    : historyApprovalsFilters.completedAtTo();

  const { data: taskStates = [] } = useTaskStates(ServiceItemTypes.APPROVAL);

  const [
    dateRangeSelected,
    lastSevenDays,
    lastFourteenDays,
    lastThirtyDays,
    fromDate,
    toDate,
  ] = useWatch({
    control,
    name: [
      fields.dateOptions.dateRange(),
      fields.dateOptions.lastSevenDays(),
      fields.dateOptions.lastFourteenDays(),
      fields.dateOptions.lastThirtyDays(),
      dateFromField,
      dateToField,
    ],
  });

  const [expanded, setExpanded] = useState<Record<string, boolean>>({
    [pendingApprovalsFilters.parentTaskCatalogItemsIn()]: false,
    [historyApprovalsFilters.statesIn()]: false,
    [pendingApprovalsFilters.parentTaskInitiatorsIn()]: false,
    dateRange: false,
  });

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

  const autocompleteLabelProps = useMemo(
    () => ({
      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 getApprovalStateLabel = useCallback(
    (name: string) => t(`approvals.${getApprovalStateName(name)}`),
    [t],
  );

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

  // When the user toggles off the explicit date range, drop any in-flight
  // dates and validation errors so a stale value doesn't leak into apply().
  useEffect(() => {
    if (!dateRangeSelected) {
      clearErrors([dateFromField, dateToField]);
      setValue(dateFromField, null);
      setValue(dateToField, null);
    }
  }, [dateRangeSelected, clearErrors, setValue, dateFromField, dateToField]);

  return (
    <HuDrawer
      title={t('filter')}
      open={open}
      onClose={onClose}
      primaryButtonProps={{
        children: t('general:apply'),
        onClick: handleSubmit(onApply),
        fullWidth: true,
      }}
      secondaryButtonProps={{
        children: t('reset'),
        onClick: onReset,
        fullWidth: true,
      }}
    >
      <Stack sx={{ gap: 2 }}>
        <CollapsibleAutocompleteSelector
          sectionTitle={t('associated_services')}
          fieldName={fields.parentTaskCatalogItemsIn()}
          infiniteQuery={useInfiniteServiceItems}
          isExpanded={expanded[fields.parentTaskCatalogItemsIn()]}
          setExpanded={newExpanded =>
            handleExpand(fields.parentTaskCatalogItemsIn(), newExpanded)
          }
          {...autocompleteLabelProps}
        />
        {!isPending && (
          <CollapsibleAutocompleteSelector<State>
            fieldName={historyApprovalsFilters.statesIn()}
            sectionTitle={t('statuses')}
            customMapper={item => ({
              value: item.id,
              name: getApprovalStateLabel(item.name),
            })}
            infiniteQuery={taskStaticQueryOptions}
            isExpanded={expanded[historyApprovalsFilters.statesIn()]}
            setExpanded={newExpanded =>
              handleExpand(historyApprovalsFilters.statesIn(), newExpanded)
            }
            {...autocompleteLabelProps}
          />
        )}
        <UserCollapsibleAutocompleteSelector
          fieldName={fields.parentTaskInitiatorsIn()}
          sectionTitle={t('requesters')}
          infiniteQuery={useInfiniteUsersAndAgents}
          isExpanded={expanded[fields.parentTaskInitiatorsIn()]}
          setExpanded={newExpanded =>
            handleExpand(fields.parentTaskInitiatorsIn(), newExpanded)
          }
          {...autocompleteLabelProps}
        />
        <HuAccordion
          title={t(
            isPending ? 'subtasks.request_date' : 'approvals.resolution_date',
          )}
          description={getCreationDateFilterDescription({
            dateRangeValueSelected: Boolean(dateRangeSelected),
            lastSevenDays: Boolean(lastSevenDays),
            lastFourteenDays: Boolean(lastFourteenDays),
            lastThirtyDays: Boolean(lastThirtyDays),
            fromDate,
            toDate,
            language: i18n.language || 'en',
            t,
          })}
          expanded={expanded.dateRange}
          onChange={(_, newExpanded) => handleExpand('dateRange', newExpanded)}
          customDetail={
            <DatePickerWithOptions
              showDatePickers
              options={[
                {
                  name: fields.dateOptions.lastSevenDays(),
                  label: t('last_n_days', { days: 7 }),
                },
                {
                  name: fields.dateOptions.lastFourteenDays(),
                  label: t('last_n_days', { days: 14 }),
                },
                {
                  name: fields.dateOptions.lastThirtyDays(),
                  label: t('last_n_days', { days: 30 }),
                },
                {
                  name: fields.dateOptions.dateRange(),
                  label: t('choose_date_range'),
                },
              ]}
              startDatePicker={{
                name: dateFromField,
                label: t('from'),
                disabled: !dateRangeSelected,
                inputProps: { disableFuture: true },
              }}
              endDatePicker={{
                name: dateToField,
                label: t('general:until'),
                disabled: !dateRangeSelected,
                inputProps: { disableFuture: true },
              }}
            />
          }
          elevation={0}
          sx={{
            mb: 2,
            borderRadius: ({ spacing }: Theme) => spacing(1),
            backgroundColor: ({ palette }: Theme) =>
              palette.new.background.elements.grey,
            '&:before': { backgroundColor: 'transparent' },
          }}
          disableGutters
        />
      </Stack>
    </HuDrawer>
  );
};

export default ApprovalsFiltersDrawer;
