import { useMemo, useState } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { useMutation } from 'react-query';

import { useModal } from '@material-hu/hooks/useModal';
import { Stack } from '@material-hu/mui/index';
import Typography from '@material-hu/mui/Typography';

import HuDialog from '@material-hu/components/design-system/Dialog';
import HuInputClassic from '@material-hu/components/design-system/Inputs/Classic/index';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import * as documentsService from 'src/services/documentsService';
import { formatBulkParams } from 'src/services/documentsService';
import {
  type BulkDeleteParams,
  type DocumentItem,
  type FilterOptions,
} from 'src/types/documents';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { LogEvents, logEvent } from 'src/utils/logging';

import { invalidateFilesQuery } from '../queries';
import { formatBulkDeleteEvent } from '../utils';

type Props = {
  totalCount: number;
  filters: FilterOptions;
  isFilterView: boolean;
};

const bulkFormFields = {
  deleteAll: 'deleteAll',
  documentIds: 'documentIds',
  excludeDocumentIds: 'excludeDocumentIds',
} as const;

type BulkFormValues = {
  [bulkFormFields.deleteAll]: boolean;
  [bulkFormFields.documentIds]: number[];
  [bulkFormFields.excludeDocumentIds]: number[];
};

export const useBulkDelete = (props: Props) => {
  const { totalCount, filters, isFilterView } = props;
  const { t } = useLokaliseTranslation([
    'documents',
    'general',
    'service_management',
  ]);
  const { enqueueSnackbar } = useHuSnackbar();
  const deleteValue = t('general:delete').toUpperCase();

  const form = useForm<BulkFormValues>({
    defaultValues: {
      [bulkFormFields.deleteAll]: false,
      [bulkFormFields.documentIds]: [],
      [bulkFormFields.excludeDocumentIds]: [],
    },
  });

  const [deleteAll, documentIds, excludeDocumentIds] = useWatch({
    control: form.control,
    name: [
      bulkFormFields.deleteAll,
      bulkFormFields.documentIds,
      bulkFormFields.excludeDocumentIds,
    ],
  });

  const bulkDeleteMutation = useMutation(
    (formattedValues: BulkDeleteParams) => {
      return documentsService.deleteDocumentsBulk(formattedValues);
    },
    {
      onSuccess: (_, formattedValues) => {
        logEvent(
          LogEvents.DOCUMENT_MASSIVE_DELETE,
          formatBulkDeleteEvent(formattedValues),
        );

        invalidateFilesQuery();
        form.reset();
        enqueueSnackbar({
          title: t('success_bulk_delete', {
            count: deleteCount,
          }),
          variant: 'success',
        });
      },
      onError: () => {
        enqueueSnackbar({
          title: t('error_bulk_delete'),
          variant: 'error',
        });
      },
    },
  );

  const handleDelete = () => {
    const formattedValues = formatBulkParams(
      { deleteAll, documentIds, excludeDocumentIds, ...filters },
      isFilterView,
    );

    bulkDeleteMutation.mutate(formattedValues);
  };

  const allDocumentsAreExcluded = useMemo(() => {
    return excludeDocumentIds.length === totalCount;
  }, [excludeDocumentIds.length, totalCount]);

  const showDeleteToolBar =
    (documentIds.length > 0 || deleteAll) && !allDocumentsAreExcluded;

  const deleteCount = useMemo(() => {
    if (deleteAll) {
      return totalCount - excludeDocumentIds.length;
    }
    return documentIds.length;
  }, [deleteAll, documentIds.length, totalCount, excludeDocumentIds]);

  const isIndeterminate = useMemo(() => {
    return (
      (!!documentIds.length || (deleteAll && !!excludeDocumentIds.length)) &&
      !allDocumentsAreExcluded
    );
  }, [
    documentIds.length,
    deleteAll,
    excludeDocumentIds.length,
    allDocumentsAreExcluded,
  ]);

  const checked = useMemo(() => {
    return (documentIds.length > 0 || deleteAll) && !allDocumentsAreExcluded;
  }, [documentIds.length, deleteAll, allDocumentsAreExcluded]);

  const handleSelectAll = () => {
    if (documentIds.length) {
      form.setValue(bulkFormFields.documentIds, []);
      return;
    }
    form.setValue(bulkFormFields.deleteAll, !deleteAll);
    form.setValue(bulkFormFields.excludeDocumentIds, []);
  };

  const handleSelect = (item: DocumentItem) => {
    if (deleteAll) {
      if (excludeDocumentIds.includes(item.id)) {
        form.setValue(
          bulkFormFields.excludeDocumentIds,
          excludeDocumentIds.filter(id => id !== item.id),
        );
      } else {
        form.setValue(bulkFormFields.excludeDocumentIds, [
          ...excludeDocumentIds,
          item.id,
        ]);
      }
    } else {
      if (documentIds.includes(item.id)) {
        form.setValue(
          bulkFormFields.documentIds,
          documentIds.filter(id => id !== item.id),
        );
      } else {
        form.setValue(bulkFormFields.documentIds, [...documentIds, item.id]);
      }
    }
  };

  const isItemSelected = (item: DocumentItem) => {
    return (
      documentIds.includes(item.id) ||
      (deleteAll && !excludeDocumentIds.includes(item.id))
    );
  };

  const handleBulkDelete = () => {
    bulkDeleteModal.closeModal();
    bulkDeleteConfirmationModal.showModal();
  };

  const handleBulkDeleteConfirmation = () => {
    handleDelete();
    bulkDeleteConfirmationModal.closeModal();
  };

  const handleCloseBulkDeleteConfirmation = () => {
    bulkDeleteConfirmationModal.closeModal();
  };

  const bulkDeleteConfirmationModal = useModal(() => {
    const [deleteInput, setDeleteInput] = useState('');

    return (
      <HuDialog
        title={t('delete_bulk_confirmation', { count: deleteCount })}
        body={
          <Stack sx={{ gap: 1 }}>
            <Typography
              sx={{ fontWeight: 'fontWeightRegular' }}
              variant="globalS"
            >
              {t('delete_documents_description.start')}
              <Typography
                sx={{ fontWeight: 'fontWeightSemiBold' }}
                variant="globalS"
              >
                {' '}
                {t('delete_documents_description.middle', {
                  count: deleteCount,
                })}{' '}
              </Typography>
              <Typography
                sx={{ fontWeight: 'fontWeightRegular' }}
                variant="globalS"
              >
                {t('delete_documents_description.end')}
              </Typography>
            </Typography>

            <HuInputClassic
              label={t(
                'service_management:delete_service_item_confirmation_input_label',
                {
                  delete: deleteValue,
                },
              )}
              value={deleteInput}
              onChange={setDeleteInput}
              hasCounter={false}
              autoFocus
            />
          </Stack>
        }
        primaryButtonProps={{
          children: t('delete'),
          onClick: handleBulkDeleteConfirmation,
          disabled: deleteInput !== deleteValue,
          color: 'primary',
          loading: bulkDeleteMutation.isLoading,
        }}
        secondaryButtonProps={{
          children: t('cancel'),
          onClick: handleCloseBulkDeleteConfirmation,
          color: 'secondary',
        }}
        onClose={handleCloseBulkDeleteConfirmation}
      />
    );
  });

  const bulkDeleteModal = useModal(() => {
    return (
      <HuDialog
        title={t('delete_bulk_confirmation', { count: deleteCount })}
        body={
          <Stack sx={{ gap: 1 }}>
            <Typography
              sx={{ fontWeight: 'fontWeightRegular' }}
              variant="globalS"
            >
              {t('delete_documents_description.start')}
              <Typography
                sx={{ fontWeight: 'fontWeightSemiBold' }}
                variant="globalS"
              >
                {' '}
                {t('delete_documents_description.middle', {
                  count: deleteCount,
                })}{' '}
              </Typography>
              <Typography
                sx={{ fontWeight: 'fontWeightRegular' }}
                variant="globalS"
              >
                {t('delete_documents_description.end')}
              </Typography>
            </Typography>
          </Stack>
        }
        primaryButtonProps={{
          children: t('delete'),
          onClick: handleBulkDelete,
          color: 'primary',
          loading: bulkDeleteMutation.isLoading,
        }}
        secondaryButtonProps={{
          children: t('cancel'),
          onClick: bulkDeleteModal.closeModal,
          color: 'secondary',
        }}
        onClose={bulkDeleteModal.closeModal}
      />
    );
  });

  return {
    bulkDeleteModal,
    bulkDeleteConfirmationModal,
    deleteCount,
    showDeleteToolBar,
    isIndeterminate,
    checked,
    handleSelectAll,
    handleSelect,
    isItemSelected,
  };
};
