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 type { GridRowSelectionModel } from '@mui/x-data-grid-premium';
import DialogUmum from 'src/shared/components/dialog/DialogUmum';
import Stack from '@mui/material/Stack';
import { FormProvider, useForm } from 'react-hook-form';
import Button from '@mui/material/Button';
import useUploadPMPrepop from '../../hooks/useUploadPMPrepop';
import Box from '@mui/material/Box';
import Alert from '@mui/material/Alert';
import Typography from '@mui/material/Typography';
import Grid from '@mui/material/Grid';
import { Field } from 'src/components/hook-form';
import dayjs from 'dayjs';
import type { TKonfirmasiFakturMasukan, TUploadFakturPMRequest } from '../../types/types';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';

interface ModalUploadFakturProps {
  dataSelected?: GridRowSelectionModel;
  setSelectionModel?: React.Dispatch<React.SetStateAction<GridRowSelectionModel | undefined>>;
  tableApiRef?: React.MutableRefObject<any>;
  isOpenDialogUpload: boolean;
  setIsOpenDialogUpload: (v: boolean) => void;
  successMessage?: string;
  onConfirmUpload?: () => Promise<void> | void;
  singleUploadPayload?: any;
  statusPengkreditan?: 'CREDITED' | 'UNCREDITED' | 'INVALID';
}

/**
 * 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 ModalUploadCreditedPM: React.FC<ModalUploadFakturProps> = ({
  dataSelected,
  setSelectionModel,
  tableApiRef,
  isOpenDialogUpload,
  setIsOpenDialogUpload,
  successMessage = 'Data berhasil diupload',
  onConfirmUpload,
  singleUploadPayload,
  statusPengkreditan,
}) => {
  const queryClient = useQueryClient();

  const schema = z.object({
    masaTahunPajak: z.string().min(1, 'Masa tahun pajak wajib diisi'), // karena DatePicker output string
  });

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

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

  const { mutateAsync, isPending } = useUploadPMPrepop({
    onSuccess: () => processSuccess(),
    onError: () => processFail(),
  });

  const idss = normalizeSelection(dataSelected); // helper kamu sudah ada
  const firstId = idss[0];

  const firstRow = tableApiRef?.current ? tableApiRef.current.getRow(String(firstId)) : undefined;

  const masaTahunPajakNormal = dayjs(
    `${firstRow?.tahunpajak ?? firstRow?.tahunPajak ?? ''}-${
      firstRow?.masapajak ?? firstRow?.masaPajak ?? ''
    }-01`
  ).startOf('month');

  const methods = useForm({
    resolver: zodResolver(schema),
    defaultValues: {
      masaTahunPajak: masaTahunPajakNormal.format('YYYY-MM-DD'),
    },
  });

  // helper to transform a single row-like payload into TUploadFakturPMRequest
  // eslint-disable-next-line @typescript-eslint/no-shadow
  function transformSingleToPayload(single: any, status: 'CREDITED' | 'UNCREDITED' | 'INVALID') {
    // if it's already the correct shape, return as-is
    if ((single as TUploadFakturPMRequest)?.konfirmasiFakturMasukan) {
      return single as TUploadFakturPMRequest;
    }

    // assume `single` is a row object (from grid) or minimal data
    const row = single ?? {};
    const konfirmasi: TKonfirmasiFakturMasukan = {
      konfirmasiPengkreditan: status,
      nomorFaktur: row?.nomorfaktur ?? row?.nomorFaktur ?? '',
      masaKredit: String(row?.masakreditpajak ?? row?.masapajak ?? ''),
      tahunKredit: String(row?.tahunkreditpajak ?? row?.tahunpajak ?? ''),
      npwpPembeli: row?.npwppembeli ?? row?.npwppembeli ?? '',
      npwpPenjual: row?.npwppenjual ?? row?.npwppenjual ?? '',
    };

    return {
      fgPermintaan: 2,
      konfirmasiFakturMasukan: konfirmasi,
    } as TUploadFakturPMRequest;
  }

  const handleMultipleUpload = async () => {
    // eslint-disable-next-line @typescript-eslint/no-shadow
    const status = statusPengkreditan ?? 'CREDITED'; // fallback

    if (singleUploadPayload) {
      setNumberOfData(1);

      // ensure singleUploadPayload has correct shape or transform it
      const payload = (singleUploadPayload as TUploadFakturPMRequest)?.konfirmasiFakturMasukan
        ? (singleUploadPayload as TUploadFakturPMRequest)
        : transformSingleToPayload(singleUploadPayload, status);

      return Promise.allSettled([mutateAsync(payload)]);
    }

    const ids = normalizeSelection(dataSelected);
    setNumberOfData(ids.length);

    const promises = ids.map((id) => {
      const row = tableApiRef?.current?.getRow(String(id));

      // mapping row fields ke tipe API — sesuaikan nama field dengan row kamu
      const konfirmasi: TKonfirmasiFakturMasukan = {
        konfirmasiPengkreditan: status,
        nomorFaktur: row?.nomorfaktur ?? row?.nomorFaktur ?? '',
        masaKredit: String(row?.masakreditpajak ?? row?.masapajak ?? ''),
        tahunKredit: String(row?.tahunkreditpajak ?? row?.tahunpajak ?? ''),
        npwpPembeli: row?.npwppembeli ?? row?.npwppembeli ?? '',
        npwpPenjual: row?.npwppenjual ?? row?.npwppenjual ?? '',
      };

      const payload: TUploadFakturPMRequest = {
        fgPermintaan: 2, // atur sesuai business rule
        konfirmasiFakturMasukan: konfirmasi,
      };

      return mutateAsync(payload);
    });

    return Promise.allSettled(promises);
  };

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

  const onSubmit = async () => {
    try {
      setIsOpenDialogProgressBar(true);

      await handleMultipleUpload();

      enqueueSnackbar(successMessage, { variant: 'success' });
      await onConfirmUpload?.();

      // ❌ jangan tutup modal dulu
      // ❌ jangan reset progress dulu
      // biarkan progress bar animasi naik ke 100%
    } catch (error: any) {
      enqueueSnackbar(error?.message || 'Gagal upload data', { variant: 'error' });
    } finally {
      queryClient.invalidateQueries({ queryKey: ['unifikasi', 'nr'] });
    }
  };

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

  return (
    <>
      <FormProvider {...methods}>
        <DialogUmum
          isOpen={isOpenDialogUpload}
          onClose={handleCloseModal}
          title="Apakah Anda yakin ingin mengubah data menjadi Credit?"
          maxWidth="sm"
        >
          <Stack>
            <Box>
              <Alert
                sx={{
                  border: 1,
                  borderColor: 'red',
                  borderBottomLeftRadius: 0,
                  borderBottomRightRadius: 0,
                  alignItems: 'center',
                  marginTop: '25px',
                }}
                icon={
                  <Box component="img" src="/assets/lampRekap.svg" sx={{ width: 40, height: 40 }} />
                }
                severity="warning"
              >
                <Typography variant="body2" color="initial">
                  Masa pengkreditan pajak dapat dilakukan dalam masa yang berbeda, dengan batas
                  maksimal 3 bulan.
                </Typography>
              </Alert>
            </Box>
            <Box bgcolor="whitesmoke" paddingX={2} paddingY="20px">
              <Grid size={{ md: 12 }}>
                <Field.DatePicker
                  name="masaTahunPajak"
                  label="Masa Pajak"
                  slotProps={{ textField: { helperText: '' } }}
                  views={['year', 'month']} // urutan views tampil sesuai array
                  openTo="month" // buka langsung ke bulan
                  format="MM/YYYY" // untuk menampilkan di input
                  minDate={dayjs(masaTahunPajakNormal)}
                  maxDate={dayjs(masaTahunPajakNormal).add(3, 'month')}
                />
              </Grid>
            </Box>

            <Stack direction="row" justifyContent="flex-end" spacing={1} mt={3}>
              <Button
                type="button"
                onClick={handleCloseModal}
                variant="contained"
                sx={{ background: '#143B88' }}
              >
                Tidak
              </Button>
              <Button
                type="button"
                onClick={onSubmit}
                loading={isPending}
                variant="contained"
                sx={{ background: '#143B88' }}
              >
                Save
              </Button>
            </Stack>
          </Stack>
        </DialogUmum>
      </FormProvider>

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

export default ModalUploadCreditedPM;
