import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import {
  type ApprovableStatus,
  TimeTrackingCategorizedHourStatus,
} from 'src/types/timeTracking';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { useBulkReviewCategorizedHoursMutation } from '../../hooks/useBulkReviewCategorizedHoursMutation';
import {
  type BulkReviewCategorizedHoursParams,
  type CategorizedHoursListFilters,
} from '../../services';

type BulkReviewSelection = {
  allRows: boolean;
  selectedIds: Set<string>;
  excludedIds: Set<string>;
};

type BuildBulkReviewBodyArgs = {
  state: ApprovableStatus;
  comment?: string;
  selection: BulkReviewSelection;
  filters: CategorizedHoursListFilters;
};

export const buildBulkReviewBody = ({
  state,
  comment,
  selection,
  filters,
}: BuildBulkReviewBodyArgs): BulkReviewCategorizedHoursParams => {
  const shared = { state, ...(comment ? { comment } : {}) };
  if (selection.allRows) {
    return {
      ...shared,
      allRows: true,
      filters,
      ...(selection.excludedIds.size > 0
        ? { excludeCategorizedHourIds: [...selection.excludedIds] }
        : {}),
    };
  }
  return { ...shared, categorizedHourIds: [...selection.selectedIds] };
};

type UseBulkReviewSubmitArgs = {
  selection: BulkReviewSelection;
  filters: CategorizedHoursListFilters;
  onSuccess?: () => void;
};

type SubmitArgs = {
  state: ApprovableStatus;
  comment?: string;
};

export const useBulkReviewSubmit = ({
  selection,
  filters,
  onSuccess,
}: UseBulkReviewSubmitArgs) => {
  const { t } = useLokaliseTranslation(['approval_requests']);
  const { enqueueSnackbar } = useHuSnackbar();
  const mutation = useBulkReviewCategorizedHoursMutation();

  const submit = ({ state, comment }: SubmitArgs) => {
    const body = buildBulkReviewBody({ state, comment, selection, filters });

    mutation.mutate(body, {
      onSuccess: response => {
        const skippedCount = response.data?.skippedCount ?? 0;
        const isApprove = state === TimeTrackingCategorizedHourStatus.APPROVED;
        enqueueSnackbar({
          title: t(
            isApprove
              ? 'approval_requests:bulk_actions.requests_approval_success'
              : 'approval_requests:bulk_actions.requests_rejection_success',
          ),
          ...(skippedCount > 0
            ? {
                description: t(
                  'approval_requests:bulk_actions.success_skipped_description',
                  { count: skippedCount },
                ),
              }
            : {}),
          variant: 'success',
        });
        onSuccess?.();
      },
      onError: err => {
        const data = err?.response?.data;
        if (data?.code === 'TIME_TRACKING_BULK_REVIEW_TOO_MANY') {
          enqueueSnackbar({
            title: t('approval_requests:bulk_actions.error_too_many_title', {
              // BE returns the active cap on this error; fall back only if the
              // payload omits it so the user still sees a usable message.
              limit: data.limit ?? 1000,
            }),
            description: t(
              'approval_requests:bulk_actions.error_too_many_description',
            ),
            variant: 'error',
          });
          return;
        }
        enqueueSnackbar({
          title: t('approval_requests:bulk_actions.error_generic_title'),
          description: t(
            'approval_requests:bulk_actions.error_generic_description',
          ),
          variant: 'error',
        });
      },
    });
  };

  return { submit, isLoading: mutation.isLoading };
};
