import React, { useEffect, useMemo } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';

import Grid from '@mui/material/Grid';
import MenuItem from '@mui/material/MenuItem';

import { Field } from 'src/components/hook-form';
import { useParams } from 'react-router';
import {
  KD_TRANSAKSI,
  KD_TRANSAKSI_TEXT,
  DETAIL_TRANSAKSI_TEXT,
  DETAIL_TRANSAKSI,
  DOKUMEN_TRANSAKSI_TEXT,
  DOKUMEN_TRANSAKSI,
  KODE_DOKUMEN,
  KODE_DOKUMEN_TEXT,
} from '../../constant';
import dayjs from 'dayjs';
import useGetIdTambahan from '../../hooks/useGetIdTambahan';

interface DokumenTransaksiProps {
  dlmData?: any;
  isLoading?: boolean;
  isRetur?: boolean;
}

const DokumenTransaksi: React.FC<DokumenTransaksiProps> = ({ dlmData, isRetur }) => {
  const { type } = useParams<{ id?: string; type?: 'ubah' | 'pengganti' | 'new' | 'retur' }>();
  const { control, setValue, getValues, formState } = useFormContext<any>();

  const isPengganti = type === 'pengganti';

  const now = useMemo(() => new Date(), []);
  const startOfMonth = dayjs(new Date(now.getFullYear(), now.getMonth() - 1, 1));

  console.log(dlmData);

  const { mutate: getIdTambahan } = useGetIdTambahan();

  // Watch kdTransaksi & detailTransaksi
  const kdTransaksi = useWatch({
    control,
    name: 'kdTransaksi',
  });
  const detailTransaksi = useWatch({ control, name: 'detailTransaksi' }) ?? 'TD.00301';

  const tanggalDokumen = useWatch({
    control,
    name: 'tanggalDokumen',
  });

  const tanggalRetur = useWatch({
    control,
    name: 'tanggalRetur',
  });

  // Ambil semua key dari DETAIL_TRANSAKSI_TEXT
  const allDetailKeys = Object.keys(
    DETAIL_TRANSAKSI_TEXT
  ) as (keyof typeof DETAIL_TRANSAKSI_TEXT)[];

  const DETAIL_BY_KD_TRANSAKSI: Record<string, (keyof typeof DETAIL_TRANSAKSI_TEXT)[]> = {
    IMPORT: [DETAIL_TRANSAKSI.IMPOR_BERWUJUD, DETAIL_TRANSAKSI.IMPOR_TIDAK_BERWUJUD],

    PURCHASE: [
      DETAIL_TRANSAKSI.PENYERAHAN_NON_PEMUNGUT,
      DETAIL_TRANSAKSI.PENYERAHAN_PEMUNGUT_PEMERINTAH,
      DETAIL_TRANSAKSI.PENYERAHAN_PEMUNGUT_NON_PEMERINTAH,
      DETAIL_TRANSAKSI.DPP_LAIN,
      DETAIL_TRANSAKSI.PERSENTASE_TERTENTU,
      DETAIL_TRANSAKSI.PENJUALAN_ASET,
      DETAIL_TRANSAKSI.TARIF_TIDAK_NORMAL,
    ],

    UNCREDIT: allDetailKeys.slice(0, 10),
  };

  const detailTransaksiOptions = DETAIL_BY_KD_TRANSAKSI[kdTransaksi] ?? allDetailKeys;

  // transaksiOptions (fix bug: gunakan opt.value)
  const transaksiOptions = [KD_TRANSAKSI.IMPORT, KD_TRANSAKSI.PURCHASE, KD_TRANSAKSI.UNCREDIT].map(
    (key) => ({
      value: key,
      label: KD_TRANSAKSI_TEXT[key as keyof typeof KD_TRANSAKSI_TEXT],
    })
  );

  const allDokumenKeys = Object.keys(
    DOKUMEN_TRANSAKSI_TEXT
  ) as (keyof typeof DOKUMEN_TRANSAKSI_TEXT)[];

  const DOKUMEN_BY_KD_TRANSAKSI: Record<string, (keyof typeof DOKUMEN_TRANSAKSI_TEXT)[]> = {
    IMPORT: allDokumenKeys,

    PURCHASE: [DOKUMEN_TRANSAKSI.DOKUMEN_TERTENTU],

    UNCREDIT: [
      DOKUMEN_TRANSAKSI.PEMBERITAHUAN_IMPOR_BAYAR,
      DOKUMEN_TRANSAKSI.PEMBAYARAN,
      DOKUMEN_TRANSAKSI.DOKUMEN_TERTENTU,
      DOKUMEN_TRANSAKSI.PEMBERITAHUAN_IMPOR,
    ],
  };

  const dokumenTransaksiOptions = DOKUMEN_BY_KD_TRANSAKSI[kdTransaksi] ?? allDokumenKeys;

  const dokumenOptions = dokumenTransaksiOptions.map((key) => ({
    value: key,
    label: DOKUMEN_TRANSAKSI_TEXT[key],
  }));

  // mapping dari detailTransaksi -> kode dokumen export
  const kodeDokumenForExport = useMemo(() => {
    if (detailTransaksi === DETAIL_TRANSAKSI.EKSPOR_TIDAK_BERWUJUD) {
      return KODE_DOKUMEN.EBKPTB;
    }
    if (detailTransaksi === DETAIL_TRANSAKSI.EKSPOR_JASA) {
      return KODE_DOKUMEN.EJKP;
    }
    return undefined;
  }, [detailTransaksi]);

  // tentukan tampil / tidaknya field
  const showNomorDokumen =
    kdTransaksi !== 'EXPORT' || detailTransaksi === DETAIL_TRANSAKSI.EKSPOR_BERWUJUD;

  const showKodeDokumen =
    kdTransaksi === 'EXPORT' && detailTransaksi !== DETAIL_TRANSAKSI.EKSPOR_BERWUJUD;

  useEffect(() => {
    if (
      detailTransaksi === DETAIL_TRANSAKSI.PPN_TIDAK_DIPUNGUT ||
      detailTransaksi === DETAIL_TRANSAKSI.PPN_DIBEBASKAN
    ) {
      const kodeAwal = detailTransaksi.replace('TD.', '');

      getIdTambahan({
        kode_awal: kodeAwal,
      });
    }
  }, [detailTransaksi, getIdTambahan]);

  useEffect(() => {
    if (!isPengganti) return;
    if (!dlmData) return;
    if (kdTransaksi === KD_TRANSAKSI.EXPORT) return;

    if (!isFieldDirty('nomorDokumenDiganti')) {
      const current = getValues('nomorDokumenDiganti');

      if (!current && dlmData.nomordokumen) {
        setValue('nomorDokumenDiganti', dlmData.nomordokumen, {
          shouldDirty: false,
          shouldValidate: false,
        });
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isPengganti, dlmData, kdTransaksi]);

  // auto-set defaults (tanpa menimpa user edits)
  useEffect(() => {
    // nomorDokumen: jika harus tampil dan belum diisi oleh user, keep existing or set empty
    if (showNomorDokumen) {
      if (!isFieldDirty('nomorDokumen')) {
        const cur = getValues('nomorDokumen');
        if (!cur) {
          setValue('nomorDokumen', '', { shouldDirty: false, shouldValidate: false });
        }
      }
      // non-show: clear kodeDokumen if not dirty
      if (!showKodeDokumen && !isFieldDirty('kodeDokumen')) {
        setValue('kodeDokumen', '', { shouldDirty: false, shouldValidate: false });
      }
    }

    // kodeDokumen: jika harus tampil, set default kode berdasarkan detailTransaksi (jika user belum edit)
    if (showKodeDokumen && kodeDokumenForExport) {
      if (!isFieldDirty('kodeDokumen')) {
        const cur = getValues('kodeDokumen');
        if (!cur || String(cur) !== String(kodeDokumenForExport)) {
          setValue('kodeDokumen', kodeDokumenForExport, {
            shouldDirty: false,
            shouldValidate: false,
          });
        }
      }
      // jika kita pindah ke showKodeDokumen dan nomorDokumen masih ada & belum dirty -> kosongkan
      if (!isFieldDirty('nomorDokumen') && getValues('nomorDokumen')) {
        setValue('nomorDokumen', '', { shouldDirty: false, shouldValidate: false });
      }
    } else {
      // jika kodeDokumen tidak tampil, pastikan kita tidak menahan nilai lama (jika belum diubah user)
      if (!isFieldDirty('kodeDokumen')) {
        setValue('kodeDokumen', '', { shouldDirty: false, shouldValidate: false });
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [kdTransaksi, detailTransaksi, kodeDokumenForExport]);

  const isFieldDirty = (key: string) => {
    try {
      return Boolean(formState?.dirtyFields?.[key]);
    } catch {
      return false;
    }
  };

  useEffect(() => {
    if (detailTransaksiOptions?.length > 0) {
      const current = getValues('detailTransaksi');

      const isCurrentValid = detailTransaksiOptions.some((opt) => String(opt) === String(current));

      if (!isCurrentValid) {
        setValue('detailTransaksi', detailTransaksiOptions[0], {
          shouldDirty: false,
          shouldValidate: false,
        });
      }
    }

    /**
     * ============================
     * DOKUMEN TRANSAKSI
     * ============================
     * Pola sama seperti detailTransaksi
     */
    if (dokumenTransaksiOptions?.length > 0) {
      const currentDoc = getValues('dokumenTransaksi');

      const isCurrentValid = dokumenTransaksiOptions.some(
        (opt) => String(opt) === String(currentDoc)
      );

      if (!isCurrentValid) {
        setValue('dokumenTransaksi', dokumenTransaksiOptions[0], {
          shouldDirty: false,
          shouldValidate: false,
        });
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    kdTransaksi,
    // eslint-disable-next-line react-hooks/exhaustive-deps
    JSON.stringify(detailTransaksiOptions),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    JSON.stringify(dokumenTransaksiOptions),
  ]);

  const minTanggalDiganti = useMemo(() => {
    if (!dlmData?.tanggaldokumen) return undefined;
    return dayjs(dlmData.tanggaldokumen);
  }, [dlmData]);

  useEffect(() => {
    if (!isRetur) return;
    if (!dlmData?.nomordokumen) return;

    const current = getValues('tanggalRetur');

    // hanya set saat pertama load (belum ada nilai)
    if (!current) {
      setValue('tanggalRetur', new Date(), {
        shouldDirty: false,
        shouldTouch: false,
        shouldValidate: false,
      });
    }

    // nomorDokumenRetur (LOCKED)
    if (!isFieldDirty('nomorDokumenRetur')) {
      setValue('nomorDokumenRetur', dlmData.nomordokumen, {
        shouldDirty: false,
        shouldTouch: false,
        shouldValidate: false,
      });
    }

    // nomorRetur (editable, tapi default)
    if (!isFieldDirty('nomorRetur')) {
      setValue('nomorRetur', `${dlmData.nomordokumen}-RET`, {
        shouldDirty: false,
        shouldTouch: false,
        shouldValidate: false,
      });
    }

    if (!isFieldDirty('kdTransaksi') && dlmData.kdtransaksi) {
      setValue('kdTransaksi', dlmData.kdtransaksi, {
        shouldDirty: false,
        shouldValidate: false,
      });
    }

    if (!isFieldDirty('detailTransaksi') && dlmData.detailtransaksi) {
      setValue('detailTransaksi', dlmData.detailtransaksi, {
        shouldDirty: false,
        shouldValidate: false,
      });
    }

    if (!isFieldDirty('dokumenTransaksi') && dlmData.dokumentransaksi) {
      setValue('dokumenTransaksi', dlmData.dokumentransaksi, {
        shouldDirty: false,
        shouldValidate: false,
      });
    }

    if (!isFieldDirty('keteranganTambahan') && dlmData.keterangantambahan) {
      setValue('keteranganTambahan', dlmData.keterangantambahan, {
        shouldDirty: false,
        shouldValidate: false,
      });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isRetur, dlmData]);

  useEffect(() => {
    if (!isRetur) return;

    const today = dayjs();

    if (!isFieldDirty('masaPajak')) {
      setValue('masaPajak', today.format('MM'), {
        shouldDirty: false,
        shouldValidate: false,
      });
    }

    if (!isFieldDirty('tahunPajak')) {
      setValue('tahunPajak', today.format('YYYY'), {
        shouldDirty: false,
        shouldValidate: false,
      });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isRetur]);

  const minDateRetur = useMemo(() => {
    if (!dlmData?.tanggaldokumen) return undefined;
    return dayjs(dlmData.tanggaldokumen);
  }, [dlmData]);

  return (
    <Grid container spacing={2}>
      {isRetur ? (
        <>
          <Grid size={{ md: 6 }}>
            <Field.Text
              name="nomorDokumenRetur"
              label="Nomor Dokumen Diretur"
              disabled
              sx={{ '& .MuiInputBase-root.Mui-disabled': { backgroundColor: '#f6f6f6' } }}
            />
          </Grid>
          <Grid size={{ md: 6 }}>
            <Field.Text name="nomorRetur" label="Nomor Retur" />
          </Grid>
        </>
      ) : null}

      <Grid size={{ md: 6 }}>
        <Field.DatePicker
          label={isRetur ? 'Tanggal Retur' : 'Tanggal Dokumen'}
          name={isRetur ? 'tanggalRetur' : 'tanggalDokumen'}
          format="DD/MM/YYYY"
          // value={
          //   (isRetur ? getValues('tanggalRetur') : tanggalDokumen)
          //     ? dayjs(isRetur ? getValues('tanggalRetur') : tanggalDokumen)
          //     : null
          // }
          value={
            isRetur
              ? tanggalRetur
                ? dayjs(tanggalRetur)
                : null
              : tanggalDokumen
                ? dayjs(tanggalDokumen)
                : null
          }
          onChange={(val) => {
            const fieldName = isRetur ? 'tanggalRetur' : 'tanggalDokumen';

            if (!val) {
              setValue(fieldName, null);

              if (!isRetur) {
                setValue('masaPajak', '');
                setValue('tahunPajak', '');
              }
              return;
            }

            const date = val.toDate();

            setValue(fieldName, date, {
              shouldDirty: true,
            });

            // hanya NON-retur yang set masa & tahun pajak
            if (!isRetur) {
              setValue('masaPajak', val.format('MM'), {
                shouldDirty: true,
              });

              setValue('tahunPajak', val.format('YYYY'), {
                shouldDirty: true,
              });
            }
          }}
          slotProps={{ textField: { helperText: '' } }}
          minDate={isRetur ? minDateRetur : isPengganti ? minTanggalDiganti : startOfMonth}
          maxDate={dayjs()}
        />
      </Grid>

      {isPengganti ? (
        <Grid size={{ md: 6 }}>
          <Field.DatePicker
            label="Tanggal Dokumen Diganti"
            name="tanggalDokumenDiganti"
            format="DD/MM/YYYY"
            value={tanggalDokumen ? dayjs(tanggalDokumen) : null}
            onChange={(val) => {
              if (!val) {
                setValue('tanggalDokumen', null);
                setValue('masaPajak', '');
                setValue('tahunPajak', '');
                return;
              }

              const date = val.toDate();

              setValue('tanggalDokumen', date, {
                shouldDirty: true,
              });

              setValue('masaPajak', val.format('MM'), {
                shouldDirty: true,
              });

              setValue('tahunPajak', val.format('YYYY'), {
                shouldDirty: true,
              });
            }}
            slotProps={{ textField: { helperText: '' } }}
            minDate={startOfMonth}
            maxDate={dayjs()}
            disabled
          />
        </Grid>
      ) : null}

      <Grid size={isPengganti ? { md: 6 } : { md: 3 }}>
        <Field.Text
          name="tahunPajak"
          label="Tahun Pajak"
          type="years"
          disabled
          sx={{ '& .MuiInputBase-root.Mui-disabled': { backgroundColor: '#f6f6f6' } }}
        />
      </Grid>

      <Grid size={isPengganti ? { md: 6 } : { md: 3 }}>
        <Field.Text
          name="masaPajak"
          label="Masa Pajak"
          // type="month"
          disabled
          sx={{ '& .MuiInputBase-root.Mui-disabled': { backgroundColor: '#f6f6f6' } }}
        />
      </Grid>

      <Grid size={{ md: 6 }}>
        <Field.Select
          name="kdTransaksi"
          helperText=""
          label="Kode Transaksi"
          disabled={isPengganti || isRetur}
          sx={{ '& .MuiInputBase-root.Mui-disabled': { backgroundColor: '#f6f6f6' } }}
        >
          {transaksiOptions.map((opt: any) => (
            <MenuItem key={opt.value} value={opt.value}>
              {opt.label}
            </MenuItem>
          ))}
        </Field.Select>
      </Grid>

      <Grid size={{ md: 6 }}>
        <Field.Select
          name="detailTransaksi"
          helperText=""
          label="Detail Transaksi"
          disabled={isPengganti || isRetur}
          sx={{ '& .MuiInputBase-root.Mui-disabled': { backgroundColor: '#f6f6f6' } }}
        >
          {detailTransaksiOptions.map((key, index) => (
            <MenuItem key={key} value={key}>
              {`${String(index + 1).padStart(2, '0')}: ${DETAIL_TRANSAKSI_TEXT[key]}`}
            </MenuItem>
          ))}
        </Field.Select>
      </Grid>

      <Grid size={{ md: 6 }}>
        <Field.Select
          name="dokumenTransaksi"
          helperText=""
          label="Dokumen Transaksi"
          disabled={isRetur}
          sx={{ '& .MuiInputBase-root.Mui-disabled': { backgroundColor: '#f6f6f6' } }}
        >
          {dokumenOptions.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
        </Field.Select>
      </Grid>

      {!isRetur &&
        (showNomorDokumen ? (
          <Grid size={{ xs: 6 }}>
            <Field.Text name="nomorDokumen" label="Nomor Dokumen" />
          </Grid>
        ) : (
          // tampilkan kodeDokumen select hanya saat diperlukan (EXPORT & bukan ekspor berwujud)
          <Grid size={{ md: 6 }}>
            <Field.Select name="kodeDokumen" helperText="" label="Kode Dokumen">
              {kodeDokumenForExport ? (
                <MenuItem key={kodeDokumenForExport} value={kodeDokumenForExport}>
                  {KODE_DOKUMEN_TEXT[kodeDokumenForExport as keyof typeof KODE_DOKUMEN_TEXT]}
                </MenuItem>
              ) : (
                <MenuItem value="" disabled>
                  <em>Pilih kode dokumen</em>
                </MenuItem>
              )}
            </Field.Select>
          </Grid>
        ))}

      {isPengganti && kdTransaksi !== KD_TRANSAKSI.EXPORT ? (
        <Grid size={{ xs: 6 }}>
          <Field.Text name="nomorDokumenDiganti" label="Nomor Dokumen Diganti" disabled />
        </Grid>
      ) : null}

      {/* {(detailTransaksi === DETAIL_TRANSAKSI.PPN_TIDAK_DIPUNGUT ||
        detailTransaksi === DETAIL_TRANSAKSI.PPN_DIBEBASKAN) && (
        <Grid size={{ md: 6 }}>
          <Field.Select
            name="keteranganTambahan"
            label="Keterangan Tambahan"
            disabled={isLoadingIdTambahan || isRetur}
            sx={{ '& .MuiInputBase-root.Mui-disabled': { backgroundColor: '#f6f6f6' } }}
          >
            {isLoadingIdTambahan ? (
              <MenuItem disabled>Loading...</MenuItem>
            ) : (
              keteranganTambahanOptions.map((item, index) => (
                <MenuItem key={item.kode} value={item.kode}>
                  {`${item.deskripsi}`}
                </MenuItem>
              ))
            )}
          </Field.Select>
        </Grid>
      )} */}

      {/* {!isRetur && (
        <Grid size={{ xs: 12 }}>
          <Box sx={{ display: 'flex', gap: 2, mb: 3 }}>
            <Box
              sx={{
                borderRadius: '18px',
                border:
                  jumlahKeterangan >= maxKeterangan ? '1px solid #eee' : '1px solid #2e7d3280',
                color: jumlahKeterangan >= maxKeterangan ? '#eee' : '#2e7d3280',
                p: '0px 10px',
              }}
            >
              <Button disabled={jumlahKeterangan >= maxKeterangan} onClick={handleTambah}>
                Tambah Keterangan
              </Button>
            </Box>

            <Box
              sx={{
                borderRadius: '18px',
                border: jumlahKeterangan === 0 ? '1px solid #eee' : '1px solid #f44336',
                color: jumlahKeterangan === 0 ? '#eee' : '#f44336',
                p: '0px 10px',
              }}
            >
              <Button disabled={jumlahKeterangan === 0} onClick={handleHapus}>
                Hapus Keterangan
              </Button>
            </Box>
          </Box>

          <Box>
            {Array.from({ length: jumlahKeterangan }).map((_, i) => (
              <Grid size={{ xs: 12 }} key={`keterangan${i + 1}`} sx={{ mb: 2 }}>
                <Field.Text name={`keterangan${i + 1}`} label={`Keterangan Tambahan ${i + 1}`} />
              </Grid>
            ))}
          </Box>
        </Grid>
      )} */}

      {/* {showReferensi && (
        <Grid size={{ xs: 6 }} sx={{ mt: -2.5 }}>
          <Field.Text name="referensi" label="Referensi" />
        </Grid>
      )} */}
    </Grid>
  );
};

export default DokumenTransaksi;
