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 type { TValidateFakturPMRequest } from '../../types/types';
import useConfirmationWaitingFakturPM from 'src/sections/faktur/fakturPm/hooks/useConfirmationWaitingFakturPM';

// type ConfirmationVariant = 'CANCEL' | 'PENGGANTI';

interface ModalConfirmationWaitingFakturProps {
  dataSelected?: GridRowSelectionModel;
  setSelectionModel?: React.Dispatch<React.SetStateAction<GridRowSelectionModel | undefined>>;
  tableApiRef?: React.MutableRefObject<any>;
  isOpenDialogCancel: boolean;
  setIsOpenDialogCancel: (v: boolean) => void;
  successMessage?: string;
  onConfirmCancel?: () => Promise<void> | void;
  variant: 'CANCEL' | 'PENGGANTI';
}

/** normalize berbagai bentuk selection menjadi array id */
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') {
    if (sel.ids instanceof Set) return Array.from(sel.ids) as (string | number)[];
    // kalau berbentuk map/object {'1': true, '2': true}
    const maybeIds = Object.keys(sel).filter((k) => k !== 'type' && k !== 'size');
    if (maybeIds.length > 0) {
      return maybeIds.map((k) => {
        const n = Number(k);
        return Number.isNaN(n) ? k : n;
      });
    }
  }
  return [];
};

const ModalConfirmationWaitingFaktur: React.FC<ModalConfirmationWaitingFakturProps> = ({
  dataSelected,
  setSelectionModel,
  tableApiRef,
  isOpenDialogCancel,
  setIsOpenDialogCancel,
  successMessage = 'Proses berhasil',
  onConfirmCancel,
  variant,
}) => {
  const queryClient = useQueryClient();

  const {
    numberOfData,
    setNumberOfData,
    numberOfDataFail,
    numberOfDataProcessed,
    numberOfDataSuccess,
    processSuccess,
    processFail,
    resetToDefault,
    status,
  } = useDialogProgressBar();

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

  // gunakan hook mutation; pemanggil modal bisa inject onSuccess/onError jika ingin
  const { mutateAsync } = useConfirmationWaitingFakturPM({
    onSuccess: () => {
      processSuccess();
    },
    onError: () => {
      processFail();
    },
  });

  const MODAL_CONFIG = {
    CANCEL: {
      title: 'Apakah Anda yakin akan melakukan pembatalan?',
      description: '',
      actionTitle: 'Batalkan',
      successMessage: 'Faktur berhasil dibatalkan',
    },
    PENGGANTI: {
      title: 'Apakah Anda yakin akan melakukan pengganti?',
      description: '',
      actionTitle: 'Konfirmasi',
      successMessage: 'Faktur berhasil dikonfirmasi',
    },
  } as const;

  const cfg = MODAL_CONFIG[variant];

  const normalizeNomorFaktur = (val?: string | null) => {
    if (!val) return 'INV#';
    return val.startsWith('INV#') ? val : `INV#${val}`;
  };

  const doRequests = async (ids: (string | number)[]) =>
    Promise.allSettled(
      ids.map(async (id) => {
        let nomorFaktur = 'INV#';

        // ambil row dulu
        try {
          const row = tableApiRef?.current?.getRow?.(id);

          if (row?.nomorfaktur) {
            nomorFaktur = normalizeNomorFaktur(String(row.nomorfaktur));
          }
        } catch {
          // ignore
        }

        const payload: TValidateFakturPMRequest = {
          id: Number(id),
          nomorFaktur,
        };

        return mutateAsync(payload);
      })
    );

  const clearSelection = () => {
    // clear grid selection via apiRef if available
    try {
      tableApiRef?.current?.setRowSelectionModel?.([]);
    } catch {
      // ignore if API differs
    }
    setSelectionModel?.(undefined);
  };

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

  const onSubmit = async () => {
    try {
      const ids = normalizeSelection(dataSelected);
      if (!ids.length) {
        enqueueSnackbar('Tidak ada data terpilih', { variant: 'warning' });
        return;
      }

      setNumberOfData(ids.length);
      setIsOpenDialogProgressBar(true);

      const settled = await doRequests(ids);

      // count results
      const successCount = settled.filter((r) => r.status === 'fulfilled').length;
      const failCount = settled.length - successCount;

      // show feedback
      if (successCount > 0) {
        enqueueSnackbar(successMessage, { variant: 'success' });
      }
      if (failCount > 0) {
        enqueueSnackbar(`${failCount} item gagal diproses`, { variant: 'error' });
      }

      await onConfirmCancel?.();

      // close + reset
      handleCloseModal();
      clearSelection();

      // invalidasi queries (sesuaikan queryKey dengan kebutuhan)
      queryClient.invalidateQueries({ queryKey: ['unifikasi', 'dn'] });
    } catch (err: any) {
      enqueueSnackbar(err?.message || 'Proses gagal', { variant: 'error' });
    } finally {
      setIsOpenDialogProgressBar(false);
    }
  };

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

  return (
    <>
      <DialogConfirm
        fullWidth
        maxWidth="sm"
        title={cfg.title}
        description=""
        actionTitle="Ya"
        isOpen={isOpenDialogCancel}
        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 ModalConfirmationWaitingFaktur;
