import { zodResolver } from '@hookform/resolvers/zod';
import { LoadingButton } from '@mui/lab';
import Grid from '@mui/material/Grid';
import { useState, useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { CustomBreadcrumbs } from 'src/components/custom-breadcrumbs';
import { DashboardContent } from 'src/layouts/dashboard';
import { paths } from 'src/routes/paths';
import HeadingRekam from 'src/shared/components/HeadingRekam';
import z from 'zod';
import Identitas from '../components/rekamDn/Identitas';
import Divider from '@mui/material/Divider';
import FormSkeleton from 'src/shared/skeletons/FormSkeleton';
import PphDipotong from '../components/rekamDn/PphDipotong';
import useGetKodeObjekPajak from '../hooks/useGetKodeObjekPajak';
import DokumenReferensi from '../components/rekamDn/DokumenReferensi';
import Agreement from 'src/shared/components/agreement/Agreement';
import Stack from '@mui/material/Stack';
import PanduanDnRekam from '../components/rekamDn/PanduanDnRekam';
import useSaveDn from '../hooks/useSaveDn';
import { enqueueSnackbar } from 'notistack';
import { useNavigate, useParams } from 'react-router';
import useUpload from '../hooks/useUpload';
import { useGetDnById } from '../hooks/useGetDn';
import ModalUploadDn from '../components/dialog/ModalUploadDn';

const bpuSchema = z
  .object({
    tglPemotongan: z.string().nonempty('Tanggal Pemotongan harus diisi'),
    thnPajak: z.string().nonempty('Tahun Pajak harus diisi'),
    msPajak: z.string().nonempty('Masa Pajak harus diisi'),
    idDipotong: z
      .string()
      .nonempty('NPWP harus diisi')
      .regex(/^\d{16}$/, 'NPWP harus 16 digit'),
    nitku: z
      .string()
      .nonempty('NITKU harus diisi')
      .regex(/^\d{22}$/, 'NITKU harus 22 digit'),
    namaDipotong: z.string().nonempty('Nama harus diisi'),
    email: z.string().email({ message: 'Email tidak valid' }).optional().or(z.literal('')),
    keterangan1: z.string().optional(),
    keterangan2: z.string().optional(),
    keterangan3: z.string().optional(),
    keterangan4: z.string().optional(),
    keterangan5: z.string().optional(),
    kdObjPjk: z.string().nonempty('Kode Objek Pajak harus diisi'),
    fgFasilitas: z.string().nonempty('Fasilitas harus diisi'),
    noDokLainnya: z.string().optional(),
    jmlBruto: z.string().nonempty('Jumlah Penghasilan Bruto harus diisi'),
    tarif: z.union([z.string().nonempty('Tarif harus diisi'), z.number()]),
    pphDipotong: z.string().nonempty('PPh Yang Dipotong/Dipungut harus diisi'),
    namaDok: z.string().nonempty('Nama Dokumen harus diisi'),
    nomorDok: z.string().nonempty('Nomor Dokumen harus diisi'),
    tglDok: z.string().nonempty('Tanggal Dokumen harus diisi'),
    idTku: z.string().nonempty('Cabang harus diisi'),
  })
  .superRefine((data, ctx) => {
    // Field dianggap DISABLED kalau fgFasilitas kosong ('') atau '9'
    const isDisabled = ['', '9'].includes(data.fgFasilitas);

    // Jika tidak disabled, berarti aktif → wajib isi
    if (!isDisabled && (!data.noDokLainnya || data.noDokLainnya.trim() === '')) {
      ctx.addIssue({
        path: ['noDokLainnya'],
        code: 'custom',
        message: 'No Dokumen Lainnya harus diisi',
      });
    }
  });

const DnRekamView = () => {
  const { id, type } = useParams<{ id?: string; type?: 'ubah' | 'pengganti' | 'new' }>();

  const [isOpenPanduan, setIsOpenPanduan] = useState<boolean>(false);
  const [isCheckedAgreement, setIsCheckedAgreement] = useState<boolean>(false);
  const [isFormPrefilled, setIsFormPrefilled] = useState<boolean>(false);
  const [formInitialized, setFormInitialized] = useState<boolean>(false);
  const [isUploadModalOpen, setIsUploadModalOpen] = useState<boolean>(false);

  const isEdit = type === 'ubah';
  const isPengganti = type === 'pengganti';

  const { data: existingDn, isLoading: isLoadingDn } = useGetDnById(id!, {
    enabled: !!id && (isEdit || isPengganti),
  });

  const { data: kodeObjekPajak, isLoading: isLoadingKop } = useGetKodeObjekPajak();
  const navigate = useNavigate();

  type BpuFormData = z.infer<typeof bpuSchema>;

  const saveDn = useSaveDn({
    onSuccess: () => enqueueSnackbar('Data berhasil disimpan', { variant: 'success' }),
  });

  const uploadDn = useUpload();

  const handleOpenPanduan = () => setIsOpenPanduan(!isOpenPanduan);

  const defaultValues: BpuFormData = {
    tglPemotongan: '',
    thnPajak: '',
    msPajak: '',
    idDipotong: '',
    nitku: '',
    namaDipotong: '',
    email: '',
    keterangan1: '',
    keterangan2: '',
    keterangan3: '',
    keterangan4: '',
    keterangan5: '',
    kdObjPjk: '',
    fgFasilitas: '',
    noDokLainnya: '',
    jmlBruto: '',
    tarif: '',
    pphDipotong: '',
    namaDok: '',
    nomorDok: '',
    tglDok: '',
    idTku: '',
  };

  const methods = useForm<BpuFormData>({
    mode: 'all',
    resolver: zodResolver(bpuSchema),
    defaultValues,
  });

  const { reset, handleSubmit } = methods;

  useEffect(() => {
    if (isEdit || isPengganti) {
      if (existingDn && !isLoadingKop) {
        // 🧩 Normalisasi nilai numeric ke string sebelum reset
        const normalized = {
          ...existingDn,
          jmlBruto:
            existingDn.jmlBruto !== null && existingDn.jmlBruto !== undefined
              ? String(existingDn.jmlBruto)
              : '',
          tarif:
            existingDn.tarif !== null && existingDn.tarif !== undefined
              ? String(existingDn.tarif)
              : '',
          pphDipotong:
            existingDn.pphDipotong !== null && existingDn.pphDipotong !== undefined
              ? String(existingDn.pphDipotong)
              : '',
        };

        reset(normalized);
        setIsFormPrefilled(true);
        setFormInitialized(true);
      }
    } else {
      setIsFormPrefilled(false);
      setFormInitialized(true);
    }
  }, [existingDn, isLoadingKop, isEdit, isPengganti, reset]);

  const buildPayload = (values: BpuFormData) => {
    if (isEdit) {
      return {
        ...values,
        id,
        isPengganti: false,
      };
    }

    if (isPengganti) {
      return {
        ...values,
        id,
        isPengganti: true,
        idBupot: existingDn?.idBupot,
        noBupot: existingDn?.noBupot,
        revNo: existingDn?.revNo ?? 0,
      };
    }

    return {
      ...values,
      isPengganti: false,
    };
  };

  const onSubmit = async (values: BpuFormData) => {
    try {
      const payload = buildPayload(values);

      await saveDn.mutateAsync(payload);

      enqueueSnackbar(
        isEdit
          ? 'Data berhasil diperbarui'
          : isPengganti
            ? 'Data pengganti berhasil disimpan'
            : 'Data berhasil disimpan',
        { variant: 'success' }
      );

      navigate('/unifikasi/dn');
    } catch (error: any) {
      enqueueSnackbar(error.message || 'Gagal menyimpan data', { variant: 'error' });
      console.error('❌ SaveDn error:', error);
    }
  };

  const handleSaveAndUpload = async (values: BpuFormData) => {
    try {
      const payload = buildPayload(values);
      const res: any = await saveDn.mutateAsync(payload);

      const savedId = res?.[0]?.id;
      if (!savedId) throw new Error('ID dokumen tidak ditemukan dari hasil save');

      await uploadDn.mutateAsync({ id: savedId });

      enqueueSnackbar('Data berhasil disimpan dan diupload', { variant: 'success' });
      navigate('/unifikasi/dn');
    } catch (error: any) {
      enqueueSnackbar(error.message || 'Gagal save & upload data', { variant: 'error' });
      console.error('❌ Upload error:', error);
    }
  };

  if (isLoadingDn || isLoadingKop || !formInitialized) {
    return (
      <DashboardContent>
        <CustomBreadcrumbs
          heading={
            isEdit
              ? 'Ubah Bupot Unifikasi'
              : isPengganti
                ? 'Bupot Pengganti'
                : 'Tambah Bupot Unifikasi'
          }
          links={[
            { name: 'Dashboard', href: paths.dashboard.root },
            { name: 'e-Bupot Unifikasi', href: paths.unifikasi.dn },
            { name: isEdit ? 'Ubah' : isPengganti ? 'Pengganti' : 'Tambah' },
          ]}
        />

        <HeadingRekam
          label={
            isEdit
              ? 'Ubah Data Bukti Pemotongan/Pemungutan PPh Unifikasi'
              : isPengganti
                ? 'Rekam Bukti Pengganti PPh Unifikasi'
                : 'Rekam Data Bukti Pemotongan/Pemungutan PPh Unifikasi'
          }
        />
        <FormSkeleton numberOfRows={8} />
      </DashboardContent>
    );
  }

  return (
    <DashboardContent>
      <CustomBreadcrumbs
        heading={
          isEdit
            ? 'Ubah Bupot Unifikasi'
            : isPengganti
              ? 'Bupot Pengganti'
              : 'Tambah Bupot Unifikasi'
        }
        links={[
          { name: 'Dashboard', href: paths.dashboard.root },
          { name: 'e-Bupot Unifikasi', href: paths.unifikasi.dn },
          { name: isEdit ? 'Ubah' : isPengganti ? 'Pengganti' : 'Tambah' },
        ]}
      />

      <HeadingRekam
        label={
          isEdit
            ? 'Ubah Data Bukti Pemotongan/Pemungutan PPh Unifikasi'
            : isPengganti
              ? 'Rekam Bukti Pengganti PPh Unifikasi'
              : 'Rekam Data Bukti Pemotongan/Pemungutan PPh Unifikasi'
        }
      />

      <Grid container columnSpacing={2}>
        <Grid size={{ xs: isOpenPanduan ? 8 : 11 }}>
          <FormProvider {...methods}>
            <form onSubmit={handleSubmit(onSubmit)}>
              <Identitas isPengganti={isPengganti} existingDn={existingDn} />
              <Divider />
              <PphDipotong
                kodeObjectPajak={kodeObjekPajak?.data ?? []}
                isFormPrefilled={isFormPrefilled}
              />
              <DokumenReferensi />
              <Divider />
              <Grid size={12}>
                <Agreement
                  isCheckedAgreement={isCheckedAgreement}
                  setIsCheckedAgreement={setIsCheckedAgreement}
                  text="Dengan ini saya menyatakan bahwa Bukti Pemotongan/Pemungutan Unifikasi telah saya isi dengan benar secara elektronik sesuai dengan"
                />
              </Grid>
              <Stack direction="row" gap={2} justifyContent="end" marginTop={2}>
                <LoadingButton
                  type="submit"
                  loading={saveDn.isPending}
                  disabled={!isCheckedAgreement}
                  variant="outlined"
                  sx={{ color: '#143B88' }}
                >
                  Save as Draft
                </LoadingButton>
                <LoadingButton
                  type="button"
                  disabled={!isCheckedAgreement}
                  //   onClick={() => methods.handleSubmit(handleSaveAndUpload)()}
                  onClick={() => setIsUploadModalOpen(true)}
                  loading={uploadDn.isPending}
                  variant="contained"
                  sx={{ background: '#143B88' }}
                >
                  Save and Upload
                </LoadingButton>
              </Stack>
            </form>
          </FormProvider>
        </Grid>
        <Grid size={{ xs: isOpenPanduan ? 4 : 1 }}>
          <PanduanDnRekam handleOpen={handleOpenPanduan} isOpen={isOpenPanduan} />
        </Grid>
      </Grid>

      {isUploadModalOpen && (
        <ModalUploadDn
          isOpenDialogUpload={isUploadModalOpen}
          setIsOpenDialogUpload={setIsUploadModalOpen}
          onConfirmUpload={() => methods.handleSubmit(handleSaveAndUpload)()}
          singleUploadPayload={methods.getValues()}
        />
      )}
    </DashboardContent>
  );
};

export default DnRekamView;
