import React, { useEffect, useMemo, useState } 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 Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import useGetIdTambahan from '../../hooks/useGetIdTambahan';

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

const DokumenTransaksi: React.FC<DokumenTransaksiProps> = ({ dlkData, isRetur }) => {
  const maxKeterangan = 5;
  const [jumlahKeterangan, setJumlahKeterangan] = useState(0);

  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(dlkData);

  const {
    mutate: getIdTambahan,
    data: idTambahanResponse,
    isPending: isLoadingIdTambahan,
  } = useGetIdTambahan();

  const keteranganTambahanOptions = idTambahanResponse?.data ?? [];

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

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

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

  const detailTransaksiOptions =
    kdTransaksi === 'EXPORT'
      ? [
          DETAIL_TRANSAKSI.EKSPOR_BERWUJUD,
          DETAIL_TRANSAKSI.EKSPOR_TIDAK_BERWUJUD,
          DETAIL_TRANSAKSI.EKSPOR_JASA,
        ]
      : allDetailKeys.slice(0, 10); // ambil 10 pertama (index 0 s/d 9)

  const showReferensi =
    kdTransaksi === KD_TRANSAKSI.EXPORT &&
    [DETAIL_TRANSAKSI.EKSPOR_TIDAK_BERWUJUD, DETAIL_TRANSAKSI.EKSPOR_JASA].includes(
      detailTransaksi
    );

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

  const baseDokumenKeys = (
    Object.keys(DOKUMEN_TRANSAKSI_TEXT) as (keyof typeof DOKUMEN_TRANSAKSI_TEXT)[]
  ).slice(0, 3);

  const dokumenTransaksiOptions = useMemo(() => {
    // 🔹 BUKAN EXPORT → selalu array 0–2
    if (kdTransaksi !== 'EXPORT') {
      return baseDokumenKeys;
    }

    // 🔹 EXPORT → tergantung detailTransaksi
    if (detailTransaksi === DETAIL_TRANSAKSI.EKSPOR_BERWUJUD) {
      return [DOKUMEN_TRANSAKSI.PEMBERITAHUAN_EKSPOR_BARANG];
    }

    return [DOKUMEN_TRANSAKSI.PEMBERITAHUAN_EKSPOR_JASA];
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [kdTransaksi, detailTransaksi]);

  // 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 (!dlkData) return;
    if (kdTransaksi === KD_TRANSAKSI.EXPORT) return;

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

      if (!current && dlkData.nomordokumen) {
        setValue('nomorDokumenDiganti', dlkData.nomordokumen, {
          shouldDirty: false,
          shouldValidate: false,
        });
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isPengganti, dlkData, 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 handleTambah = () => {
    if (jumlahKeterangan < 5) {
      const next = jumlahKeterangan + 1;
      setJumlahKeterangan(next);

      // 🔥 INI WAJIB
      setValue(`keterangan${next}`, '', {
        shouldDirty: false,
        shouldTouch: false,
      });
    }
  };

  const handleHapus = () => {
    if (jumlahKeterangan > 0) {
      setValue(`keterangan${jumlahKeterangan}`, '');
      setJumlahKeterangan(jumlahKeterangan - 1);
    }
  };

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

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

    // hitung jumlah keterangan yang terisi
    let count = 0;

    for (let i = 1; i <= maxKeterangan; i++) {
      const val = dlkData[`keterangan${i}`];

      if (val !== null && val !== undefined && String(val).trim() !== '') {
        count = i;

        // inject ke RHF
        setValue(`keterangan${i}`, val, {
          shouldDirty: false,
          shouldTouch: false,
          shouldValidate: false,
        });
      }
    }

    if (count > 0) {
      setJumlahKeterangan(count);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dlkData]);

  useEffect(() => {
    if (!isRetur) return;
    if (!dlkData?.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', dlkData.nomordokumen, {
        shouldDirty: false,
        shouldTouch: false,
        shouldValidate: false,
      });
    }

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

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

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

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

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

  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 (!dlkData?.tanggaldokumen) return undefined;
    return dayjs(dlkData.tanggaldokumen);
  }, [dlkData]);

  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="Tanggal Dokumen"
          name="tanggalDokumen"
          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={isPengganti ? minTanggalDiganti : startOfMonth}
          maxDate={dayjs()}
        />
      </Grid> */}

      <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
          }
          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' } }}
        >
          {dokumenTransaksiOptions.map((key, index) => (
            <MenuItem key={key} value={key}>
              {`${DOKUMEN_TRANSAKSI_TEXT[key]}`}
            </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;
