import Divider from '@mui/material/Divider';
import Grid from '@mui/material/Grid';
import MenuItem from '@mui/material/MenuItem';
import { useEffect, useMemo, useRef, useState } from 'react';
import { Field } from 'src/components/hook-form';
import type { TGetListDataKOPDigunggung } from '../../types/types';
import { useFormContext } from 'react-hook-form';
import {
  FG_FASILITAS_DN,
  FG_FASILITAS_MASTER_KEY,
  FG_FASILITAS_TEXT,
  TARIF_0,
} from '../../constant';
import { RHFNumeric } from 'src/components/hook-form/rhf-numeric';

type PPHDipotongProps = {
  kodeObjectPajak: TGetListDataKOPDigunggung[];
  isFormPrefilled?: boolean; // true kalau mode edit
};

const PphDipotong = ({ kodeObjectPajak, isFormPrefilled = false }: PPHDipotongProps) => {
  const { watch, setValue, getValues } = useFormContext<Record<string, any>>();

  const selectedKode = watch('kdObjPjk');
  const fgFasilitas = watch('fgFasilitas');
  const dpp = watch('dpp');
  const tarifWatched = watch('tarif');

  const kodeLoaded = Array.isArray(kodeObjectPajak) && kodeObjectPajak.length > 0;

  // ---- state & refs to control timing & user-interaction
  const [isPrefillDone, setIsPrefillDone] = useState(!isFormPrefilled);
  const initialCapturedRef = useRef<null | { kd?: any; fg?: any; tarif?: any; noDok?: any }>(null);
  const hasUserInteractedRef = useRef(false);
  const prevKdRef = useRef<string | undefined>(undefined);
  const prevFgRef = useRef<string | undefined>(undefined);

  // kode object pajak selected
  const kodeObjekPajakSelected = useMemo(
    () => kodeObjectPajak.find((item) => item.kode === selectedKode),
    [kodeObjectPajak, selectedKode]
  );

  // 🧩 Utility: pastikan field numeric disimpan sebagai string
  const setValueString = (field: string, val: any) => {
    setValue(field, val != null ? String(val) : '', { shouldValidate: true });
  };

  // 1) Wait for both: parent says prefilled AND kodeObjectPajak data available
  useEffect(() => {
    if (!isFormPrefilled) {
      // create mode => ready immediately
      setIsPrefillDone(true);
      return;
    }

    // edit mode -> wait until kode data available (so we can decide default tariff correctly)
    if (isFormPrefilled && kodeLoaded && !initialCapturedRef.current) {
      // capture initial values once (so we can detect user interaction later)
      initialCapturedRef.current = {
        kd: getValues('kdObjPjk'),
        fg: getValues('fgFasilitas'),
        tarif: getValues('tarif'),
        noDok: getValues('noDokLainnya'),
      };
      // mark prefill done
      setIsPrefillDone(true);
    }
  }, [isFormPrefilled, kodeLoaded, getValues]);

  // 2) detect user interactions: if kd or fg changes from previous value -> mark interacted
  useEffect(() => {
    if (prevKdRef.current !== undefined && prevKdRef.current !== selectedKode) {
      hasUserInteractedRef.current = true;
    }
    prevKdRef.current = selectedKode;
  }, [selectedKode]);

  useEffect(() => {
    if (prevFgRef.current !== undefined && prevFgRef.current !== fgFasilitas) {
      hasUserInteractedRef.current = true;
    }
    prevFgRef.current = fgFasilitas;
  }, [fgFasilitas]);

  // also mark user interaction if tarif or noDok changes (user typed)
  useEffect(() => {
    if (!initialCapturedRef.current) return;
    const initial = initialCapturedRef.current;
    const curTarif = getValues('tarif');
    const curNoDok = getValues('noDokLainnya');

    if (
      (initial.tarif !== undefined && String(initial.tarif) !== String(curTarif)) ||
      (initial.noDok !== undefined && String(initial.noDok) !== String(curNoDok))
    ) {
      hasUserInteractedRef.current = true;
    }
  }, [tarifWatched, getValues]);

  // === Perhitungan otomatis pph dipotong
  useEffect(() => {
    const fg = getValues('fgFasilitas');
    const bruto = Number(getValues('dpp') || 0);
    const tarif = Number(getValues('tarif') || 0);

    const pph = !fg ? 0 : TARIF_0.includes(fg) ? 0 : (bruto * tarif) / 100;
    const currentPph = Number(getValues('pphDipotong') || 0);

    if (currentPph !== pph) {
      setValueString('pphDipotong', pph);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dpp, tarifWatched, fgFasilitas, getValues, setValue]);

  // === Jalankan perhitungan awal setelah prefill selesai
  useEffect(() => {
    if (!isPrefillDone) return;
    const fg = getValues('fgFasilitas');
    const bruto = Number(getValues('dpp') || 0);
    const tarif = Number(getValues('tarif') || 0);
    const initialPph = !fg ? 0 : TARIF_0.includes(fg) ? 0 : (bruto * tarif) / 100;
    setValueString('pphDipotong', initialPph);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isPrefillDone, getValues]);

  // === Update tarif ketika kode objek pajak berubah
  useEffect(() => {
    if (!isPrefillDone) return;
    if (!selectedKode || !kodeObjekPajakSelected) return;

    const kodeTarif = Number(kodeObjekPajakSelected.tarif) || 0;
    const currentTarif = getValues('tarif');

    const prevKd = prevKdRef.current;
    const kdChangedByUser = prevKd !== undefined && prevKd !== selectedKode;

    if (isFormPrefilled && !hasUserInteractedRef.current && !kdChangedByUser) {
      return;
    }

    if (String(currentTarif) !== String(kodeTarif)) {
      setValueString('tarif', kodeTarif);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedKode, kodeObjekPajakSelected, isPrefillDone, isFormPrefilled, getValues]);

  // === Reaksi terhadap perubahan fasilitas
  useEffect(() => {
    if (!isPrefillDone) return;

    const currentTarif = getValues('tarif');
    const currentNoDok = getValues('noDokLainnya');
    const kodeTarif = Number(kodeObjekPajakSelected?.tarif) || 0;

    const prevFg = prevFgRef.current;
    const fgChangedByUser = prevFg !== undefined && prevFg !== fgFasilitas;

    if (isFormPrefilled && !hasUserInteractedRef.current && !fgChangedByUser) {
      return;
    }

    if (fgFasilitas === FG_FASILITAS_DN.FASILITAS_LAINNYA) {
      setValueString('tarif', 0);
      setValue('noDokLainnya', '', { shouldValidate: true });
      return;
    }

    if (String(currentTarif) !== String(kodeTarif)) {
      setValueString('tarif', kodeTarif);
    }
    if (currentNoDok !== '') {
      setValue('noDokLainnya', '', { shouldValidate: true });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [fgFasilitas, kodeObjekPajakSelected, isPrefillDone, isFormPrefilled, getValues]);

  // === Filter opsi fasilitas
  const fasilitasOptions = useMemo(() => {
    if (!kodeObjekPajakSelected) return [];
    return Object.values(FG_FASILITAS_DN)
      .map((v) => ({ value: v, label: FG_FASILITAS_TEXT[v] }))
      .filter(
        (opt) =>
          kodeObjekPajakSelected[
            FG_FASILITAS_MASTER_KEY[opt.value] as keyof TGetListDataKOPDigunggung
          ] === 1
      );
  }, [kodeObjekPajakSelected]);

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

    // Ambil data dari objek yang dipilih
    const { pasal, statuspph, kap, kjs } = kodeObjekPajakSelected;

    // Isi ke form agar ikut terkirim di payload
    setValue('pasalPph', pasal ?? '', { shouldValidate: true });
    setValue('statusPph', statuspph ?? '', { shouldValidate: true });
    setValue('kap', Number(kap) || 0, { shouldValidate: true });
    setValue('kjs', Number(kjs) || 0, { shouldValidate: true });
  }, [kodeObjekPajakSelected, setValue]);

  return (
    <Grid container rowSpacing={2} columnSpacing={2}>
      <Grid sx={{ mt: 3 }} size={{ md: 6 }}>
        <Field.Select name="kdObjPjk" label="Kode Objek Pajak">
          {kodeObjectPajak.map((item) => (
            <MenuItem key={item.kode} value={item.kode}>
              {`(${item.kode}) ${item.nama}`}
            </MenuItem>
          ))}
        </Field.Select>
      </Grid>

      <Grid size={{ md: 12 }}>
        <Divider sx={{ fontWeight: 'bold' }} textAlign="left">
          Fasilitas Pajak Penghasilan
        </Divider>
      </Grid>

      <Grid size={{ md: 6 }}>
        <Field.Select name="fgFasilitas" label="Fasilitas">
          {fasilitasOptions.length === 0 ? (
            <MenuItem disabled value="">
              No options
            </MenuItem>
          ) : (
            fasilitasOptions.map((opt) => (
              <MenuItem key={opt.value} value={opt.value}>
                {opt.label}
              </MenuItem>
            ))
          )}
        </Field.Select>
      </Grid>

      <Grid size={{ md: 6 }}>
        <Field.Text
          name="noDokLainnya"
          label="Nomor Dokumen Lainnya"
          disabled={['9', ''].includes(fgFasilitas)}
          sx={{ '& .MuiInputBase-root.Mui-disabled': { backgroundColor: '#f6f6f6' } }}
        />
      </Grid>

      <Grid size={{ md: 4 }}>
        <RHFNumeric
          name="dpp"
          label="Jumlah Penghasilan Bruto (Rp)"
          allowNegativeValue={false}
          allowDecimalValue={false}
        />
      </Grid>

      <Grid size={{ md: 4 }}>
        <RHFNumeric
          name="tarif"
          label="Tarif (%)"
          allowDecimalValue
          maxValue={100}
          readOnly={fgFasilitas !== FG_FASILITAS_DN.FASILITAS_LAINNYA}
          disabled={fgFasilitas !== FG_FASILITAS_DN.FASILITAS_LAINNYA}
        />
      </Grid>

      <Grid size={{ md: 4 }}>
        <RHFNumeric
          name="pphDipotong"
          label="PPh Yang Dipotong/Dipungut"
          allowNegativeValue={false}
          allowDecimalValue={false}
          readOnly
        />
      </Grid>
    </Grid>
  );
};

export default PphDipotong;
