import { zodResolver } from '@hookform/resolvers/zod';
import { LoadingButton } from '@mui/lab';
import Divider from '@mui/material/Divider';
import Grid from '@mui/material/Grid';
import Stack from '@mui/material/Stack';
import { enqueueSnackbar } from 'notistack';
import { useEffect, useMemo, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useNavigate, useParams } from 'react-router';
import { useKodeNegara } from 'src/actions/master-data';
import { CustomBreadcrumbs } from 'src/components/custom-breadcrumbs';
import { DashboardContent } from 'src/layouts/dashboard';
import { paths } from 'src/routes/paths';
import Agreement from 'src/shared/components/agreement/Agreement';
import HeadingRekam from 'src/shared/components/HeadingRekam';
import FormSkeleton from 'src/shared/skeletons/FormSkeleton';
import z from 'zod';
import ModalUploadNr from '../components/dialog/ModalUpload';
import DokumenReferensi from '../components/rekamNr/DokumenReferensi';
import Identitas from '../components/rekamNr/Identitas';
import PanduanNrRekam from '../components/rekamNr/PanduanNrRekam';
import PphDipotong from '../components/rekamNr/PphDipotong';
import {
  BUPOT_REFERENSI,
  BUPOT_REFERENSI_TEXT,
  FG_FASILITAS_OPTIONS,
  FG_FASILITAS_TEXT,
  KODE_OBJEK_PAJAK,
  KODE_OBJEK_PAJAK_TEXT,
} from '../constant';
import { useGetBupot26ById } from '../hooks/useGetBupot26';
import useSave from '../hooks/useSave';
import useUpload from '../hooks/useUpload';

const bupot26Schema = z
  .object({
    tglPemotongan: z.string().nonempty('Tanggal Pemotongan harus diisi'),
    thnPajak: z.string().nonempty('Tahun Pajak harus diisi'),
    masaPajak: z.string().nonempty('Masa Pajak harus diisi'),
    idDipotong: z.string().nonempty('TIN harus diisi'),
    alamatDipotong: z.string().nonempty('Alamat harus diisi'),
    namaDipotong: z.string().nonempty('Nama harus diisi'),
    negaraDipotong: z
      .object({
        label: z.string(),
        value: z.string(),
      })
      .refine((data: any) => data.value !== '', {
        message: 'Negara harus diisi',
      }),
    tmptLahirDipotong: z.string().nonempty('Tempat Lahir harus diisi'),
    tglLahirDipotong: z.string().nonempty('Tanggal Lahir harus diisi'),
    nomorPaspor: z.string().nonempty('No Paspor harus diisi'),
    nomorKitasKitap: z.string().nonempty('No.KITAS/KITAP harus diisi'),
    kodeObjekPajak: z
      .object({
        label: z.string(),
        value: z.string(),
      })
      .refine((data: any) => data.value !== '', {
        message: 'Kode Objek Pajak harus diisi',
      }),
    fgFasilitas: z
      .object({
        label: z.string(),
        value: z.string(),
      })
      .refine((data: any) => data.value !== '', {
        message: 'Fasilitas wajib dipilih',
      }),
    noDokLainnya: z.string().optional(),
    penghasilanBruto: z.string().nonempty('Jumlah Penghasilan Bruto harus diisi'),
    normaPenghasilanNeto: z.string().nonempty('Perkiraan Penghasilan Netto (%) 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
      .object({
        label: z.string(),
        value: z.string(),
      })
      .refine((val) => val.value !== '', 'Nama Dokumen harus diisi'),
    nomorDok: z.string().nonempty('Nomor Dokumen harus diisi'),
    tglDok: z.string().nonempty('Tanggal Dokumen harus diisi'),
    metodePembayaranBendahara: z
      .object({
        value: z.string(),
        label: z.string(),
      })
      .optional(),
    nomorSP2D: z.string().optional(),
    idTku: z.string().nonempty('Cabang harus diisi'),
  })
  .superRefine((data, ctx) => {
    // Field dianggap DISABLED kalau fgFasilitas kosong ('') atau '9'
    const isDisabled = ['', '9'].includes(data.fgFasilitas.value);

    // 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',
      });
    }
  })
  .refine(
    (data) => {
      const tglPot = data.tglPemotongan;
      const tglDok = data.tglDok;
      if (tglPot >= tglDok) return true;
      return false;
    },
    {
      message: 'Tanggal Dokumen tidak boleh melebihi Tanggal Pemotongan',
      path: ['tglDok'],
    }
  )
  .refine((data) => data.metodePembayaranBendahara?.value !== 'IMPREST', {
    message: 'Nomor SP2D wajib diisi',
    path: ['nomorSP2D'],
  });

const kodeObjekPajakOptions = [
  {
    value: KODE_OBJEK_PAJAK.BUPOT_26,
    label: `${KODE_OBJEK_PAJAK.BUPOT_26} : ${KODE_OBJEK_PAJAK_TEXT[KODE_OBJEK_PAJAK.BUPOT_26]}`,
  },
];

const fgFasilitasOptions = Object.entries(FG_FASILITAS_OPTIONS)
  .filter(([_, value]) =>
    [
      FG_FASILITAS_OPTIONS.DTP,
      FG_FASILITAS_OPTIONS.SKD_WPLN,
      FG_FASILITAS_OPTIONS.FASILITAS_LAINNYA,
      FG_FASILITAS_OPTIONS.TANPA_FASILITAS,
    ].includes(value)
  )
  .map(([_, value]) => ({
    value,
    label: FG_FASILITAS_TEXT[value],
  }));

const namaDokOptions = Object.entries(BUPOT_REFERENSI).map(([key, value]) => ({
  value,
  label: BUPOT_REFERENSI_TEXT[value],
}));

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

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

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

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

  console.log("🚀 ~ Bupot26RekamView ~ data:", data);

  const { kodeNegara: country = [] } = useKodeNegara();

  const negaraDipotongOptions = useMemo(()=>country.map(val=>({value: val.kode, label: val.nama, ...val})),[country])

  const navigate = useNavigate();

  type BpuNrFormData = z.infer<typeof bupot26Schema>;

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

  const upload = useUpload();

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

  const defaultValues: BpuNrFormData = {
    tglPemotongan: '',
    thnPajak: '',
    masaPajak: '',
    idDipotong: '',
    namaDipotong: '',
    alamatDipotong: '',
    negaraDipotong: {
      value: '',
      label: '',
    },
    tmptLahirDipotong: '',
    tglLahirDipotong: '',
    nomorPaspor: '',
    nomorKitasKitap: '',
    kodeObjekPajak: kodeObjekPajakOptions[0],
    fgFasilitas: {
      value: FG_FASILITAS_OPTIONS.TANPA_FASILITAS,
      label: FG_FASILITAS_TEXT[FG_FASILITAS_OPTIONS.TANPA_FASILITAS],
    },
    noDokLainnya: '',
    penghasilanBruto: '',
    tarif: '20',
    normaPenghasilanNeto: '100',
    pphDipotong: '',
    namaDok: { value: '', label: '' },
    nomorDok: '',
    metodePembayaranBendahara: { value: '', label: '' },
    nomorSP2D: '',
    tglDok: '',
    idTku: '',
  };

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

  const { handleSubmit, reset } = methods;

  useEffect(() => {
    if (isEdit || isPengganti) {
      if (data) {
        const negaraDipotong = negaraDipotongOptions.filter(val => val.value === data.negaraDipotong)[0]
        const fgFasilitas = fgFasilitasOptions.filter(val => val.value === data.fgFasilitas)[0]
        const namaDok= namaDokOptions.filter(val=> val.value=== data.namaDok)[0]
        const kodeObjekPajak = kodeObjekPajakOptions[0]
        // 🧩 Normalisasi nilai numeric ke string sebelum reset
        const normalized = {
          ...data,
          negaraDipotong,
          fgFasilitas,
          namaDok,
          kodeObjekPajak,
          tarif:
            data.tarif !== null && data.tarif !== undefined
              ? String(data.tarif)
              : '',
          pphDipotong:
            data.pphDipotong !== null && data.pphDipotong !== undefined
              ? String(data.pphDipotong)
              : '',
          masaPajak:
            data.msPajak !== null && data.msPajak !== undefined
              ? String(data.msPajak)
              : '',
        };
        reset(normalized);
      }
    }
  }, [data, isEdit, isPengganti, reset, negaraDipotongOptions]);

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

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

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

  const onSubmit = async (values: BpuNrFormData) => {
    console.log('ini ke klik');
    try {
      const payload = buildPayload(values);

      await save.mutateAsync(payload);

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

      navigate(paths.pph21.bupot26);
    } catch (error: any) {
      enqueueSnackbar(error.message || 'Gagal menyimpan data', { variant: 'error' });
      console.error('❌ save error:', error);
    }
  };

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

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

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

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

  if (isLoadingDn|| negaraDipotongOptions.length === 0) {
    return (
      <DashboardContent>
        <CustomBreadcrumbs
          heading={
            isEdit
              ? 'Ubah Bupot Pasal 26'
              : isPengganti
                ? 'Bupot Pengganti'
                : 'Tambah Bupot Pasal 26'
          }
          links={[
            { name: 'Dashboard', href: paths.dashboard.root },
            { name: 'e-Bupot Pasal 26', href: paths.pph21.bupot26 },
            { name: isEdit ? 'Ubah' : isPengganti ? 'Pengganti' : 'Tambah' },
          ]}
        />

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

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

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

      <Grid container columnSpacing={2}>
        <Grid size={{ xs: isOpenPanduan ? 8 : 11 }}>
          <FormProvider {...methods}>
            <form onSubmit={handleSubmit(onSubmit)}>
              <Identitas isPengganti={isPengganti} existingNr={data} country={country} />
              <Divider />
              <PphDipotong
                kodeObjectPajak={kodeObjekPajakOptions}
                fgFasilitasOptions={fgFasilitasOptions}
              />
              <DokumenReferensi namaDokOptions={namaDokOptions} />
              <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="button"
                  loading={save.isPending}
                  disabled={!isCheckedAgreement}
                  variant="outlined"
                  sx={{ color: '#143B88' }}
                  onClick={() => {
                    console.log('🟢 Save as Draft clicked');
                    methods.handleSubmit(
                      async (values) => {
                        console.log('✅ Form valid, calling onSubmit...');
                        await onSubmit(values);
                      },
                      (err) => {
                        console.error('❌ Validation errors:', err);
                      }
                    )();
                  }}
                >
                  Save as Draft
                </LoadingButton>
                <LoadingButton
                  type="button"
                  disabled={!isCheckedAgreement}
                  //   onClick={() => methods.handleSubmit(handleSaveAndUpload)()}
                  onClick={() => setIsUploadModalOpen(true)}
                  loading={upload.isPending}
                  variant="contained"
                  sx={{ background: '#143B88' }}
                >
                  Save and Upload
                </LoadingButton>
              </Stack>
            </form>
          </FormProvider>
        </Grid>
        <Grid size={{ xs: isOpenPanduan ? 4 : 1 }}>
          <PanduanNrRekam handleOpen={handleOpenPanduan} isOpen={isOpenPanduan} />
        </Grid>
      </Grid>

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