import React, { useEffect, useState } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { enqueueSnackbar } from 'notistack';
import DialogProgressBar from 'src/shared/components/dialog/DialogProgressBar';
import useDialogProgressBar from 'src/shared/hooks/useDialogProgressBar';
import DialogConfirm from 'src/shared/components/dialog/DialogConfirm';
import type { GridRowSelectionModel } from '@mui/x-data-grid-premium';
import useDeleteDn from '../../hooks/useDeleteDn';

interface ModalDeleteDnProps {
  dataSelected?: GridRowSelectionModel;
  setSelectionModel?: React.Dispatch<React.SetStateAction<GridRowSelectionModel | undefined>>;
  tableApiRef?: React.MutableRefObject<any>;
  isOpenDialogDelete: boolean;
  setIsOpenDialogDelete: (v: boolean) => void;
  successMessage?: string;
  onConfirmDelete?: () => Promise<void> | void;
}

/**
 * Normalize various possible shapes of grid selection model into array of ids.
 * Handles:
 *  - array of ids: [1, 2, 'a']
 *  - Set-of-ids: new Set([1,2])
 *  - object like { ids: Set(...), type: 'include' }
 *  - fallback: tries to extract keys if it's an object map
 */
const normalizeSelection = (sel?: any): (string | number)[] => {
  if (!sel) return [];
  if (Array.isArray(sel)) return sel as (string | number)[];
  if (sel instanceof Set) return Array.from(sel) as (string | number)[];
  if (typeof sel === 'object') {
    // common shape from newer MUI: { ids: Set(...), type: 'include' }
    if (sel.ids instanceof Set) return Array.from(sel.ids) as (string | number)[];
    // maybe it's a map-like object { '1': true, '2': true }
    const maybeIds = Object.keys(sel).filter((k) => k !== 'type' && k !== 'size');
    if (maybeIds.length > 0) {
      // try to convert numeric-like keys to number where applicable
      return maybeIds.map((k) => {
        const n = Number(k);
        return Number.isNaN(n) ? k : n;
      });
    }
  }
  return [];
};

const ModalDeleteDn: React.FC<ModalDeleteDnProps> = ({
  dataSelected,
  setSelectionModel,
  tableApiRef,
  isOpenDialogDelete,
  setIsOpenDialogDelete,
  successMessage = 'Data berhasil dihapus',
  onConfirmDelete,
}) => {
  const queryClient = useQueryClient();

  // custom hooks for progress state
  const {
    numberOfData,
    setNumberOfData,
    numberOfDataFail,
    numberOfDataProcessed,
    numberOfDataSuccess,
    processSuccess,
    processFail,
    resetToDefault,
    status,
  } = useDialogProgressBar();

  const [isOpenDialogProgressBar, setIsOpenDialogProgressBar] = useState(false);

  // React Query mutation for delete
  const { mutateAsync } = useDeleteDn({
    onSuccess: () => processSuccess(),
    onError: () => processFail(),
  });

  // fungsi multiple delete -- gunakan normalized array of ids
  const handleMultipleDelete = async () => {
    const ids = normalizeSelection(dataSelected);
    return Promise.allSettled(ids.map(async (id) => mutateAsync({ id: String(id) })));
  };

  const clearSelection = () => {
    // clear grid selection via apiRef if available
    tableApiRef?.current?.setRowSelectionModel?.([]);
    // also clear local state if setter provided
    // set to undefined to follow the native hook type (or to empty array cast)
    setSelectionModel?.(undefined);
  };

  const handleCloseModal = () => {
    setIsOpenDialogDelete(false);
    resetToDefault();
  };

  const onSubmit = async () => {
    try {
      setIsOpenDialogProgressBar(true);
      await handleMultipleDelete();
      enqueueSnackbar(successMessage, { variant: 'success' });

      await onConfirmDelete?.();

      handleCloseModal();
      clearSelection();
    } catch (error: any) {
      enqueueSnackbar(error?.message || 'Gagal menghapus data', { variant: 'error' });
    } finally {
      // sesuaikan queryKey jika perlu; tetap panggil invalidasi
      queryClient.invalidateQueries({ queryKey: ['unifikasi', 'dn'] });
    }
  };

  useEffect(() => {
    setNumberOfData(normalizeSelection(dataSelected).length);
  }, [isOpenDialogDelete, dataSelected, setNumberOfData]);

  return (
    <>
      <DialogConfirm
        fullWidth
        maxWidth="xs"
        title="Apakah Anda yakin akan menghapus data ini?"
        description="Data yang sudah dihapus tidak dapat dikembalikan."
        actionTitle="Hapus"
        isOpen={isOpenDialogDelete}
        isLoadingBtnSubmit={false}
        handleClose={handleCloseModal}
        handleSubmit={onSubmit}
      />

      <DialogProgressBar
        isOpen={isOpenDialogProgressBar}
        handleClose={() => {
          handleCloseModal();
          setIsOpenDialogProgressBar(false);
        }}
        numberOfData={numberOfData}
        numberOfDataProcessed={numberOfDataProcessed}
        numberOfDataFail={numberOfDataFail}
        numberOfDataSuccess={numberOfDataSuccess}
        status={status}
      />
    </>
  );
};

export default ModalDeleteDn;
