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 { TGetListDataKOPNr } 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: TGetListDataKOPNr[];
  isFormPrefilled?: boolean;
};

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

  const selectedKode = watch('kodeObjekPajak');
  const fgFasilitas = watch('fgFasilitas');
  const penghasilanBruto = watch('penghasilanBruto');
  const tarifWatched = watch('tarif');
  const normaPenghasilanNetoWatched = watch('normaPenghasilanNeto');

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

  // ---- state & refs
  const [isPrefillDone, setIsPrefillDone] = useState(!isFormPrefilled);
  // initialCapturedRef sekarang menyimpan lebih banyak field termasuk bruto/norma
  const initialCapturedRef = useRef<null | {
    kd?: any;
    fg?: any;
    tarif?: any;
    noDok?: any;
    bruto?: any;
    norma?: any;
    pph?: any;
  }>(null);

  const hasUserInteractedRef = useRef(false);
  const prevKdRef = useRef<string | undefined>(undefined);
  const prevFgRef = useRef<string | undefined>(undefined);

  // --- kode objek pajak terpilih
  const kodeObjekPajakSelected = useMemo(
    () => kodeObjectPajak.find((item) => item.kode === selectedKode),
    [kodeObjectPajak, selectedKode]
  );

  // --- helper: preserve decimal vs integer
  const setValuePreserve = (field: string, val: any) => {
    const safeVal = val != null && val !== '' ? String(val) : '';
    setValue(field, safeVal, { shouldValidate: true, shouldDirty: true });
  };

  const setValueInteger = (field: string, val: any) => {
    const safeVal = val != null && val !== '' ? String(Math.round(Number(val))) : '';
    setValue(field, safeVal, { shouldValidate: true, shouldDirty: true });
  };

  // --- Prefill detection
  useEffect(() => {
    if (!isFormPrefilled) {
      setIsPrefillDone(true);
      return;
    }

    if (isFormPrefilled && kodeLoaded && !initialCapturedRef.current) {
      initialCapturedRef.current = {
        kd: getValues('kodeObjekPajak'),
        fg: getValues('fgFasilitas'),
        tarif: getValues('tarif'),
        noDok: getValues('noDokLainnya'),
        bruto: getValues('penghasilanBruto'),
        norma: getValues('normaPenghasilanNeto'),
        pph: getValues('pphDipotong'),
      };
      setIsPrefillDone(true);
    }
  }, [isFormPrefilled, kodeLoaded, getValues]);

  // --- detect user interactions for kode & fasilitas (existing logic)
  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]);

  // --- NEW: detect if user changed bruto / tarif / norma / noDok compared to initial prefill
  useEffect(() => {
    if (!initialCapturedRef.current) return;

    const init = initialCapturedRef.current;
    const curBruto = getValues('penghasilanBruto');
    const curTarif = getValues('tarif');
    const curNorma = getValues('normaPenghasilanNeto');
    const curNoDok = getValues('noDokLainnya');

    const changed =
      String(init.bruto ?? '') !== String(curBruto ?? '') ||
      String(init.tarif ?? '') !== String(curTarif ?? '') ||
      String(init.norma ?? '') !== String(curNorma ?? '') ||
      String(init.noDok ?? '') !== String(curNoDok ?? '');

    if (changed) {
      hasUserInteractedRef.current = true;
    }
    // only depend on watched values to trigger
  }, [penghasilanBruto, tarifWatched, normaPenghasilanNetoWatched, getValues]);

  // --- Perhitungan otomatis pph dipotong (27-100-06 pakai norma)
  useEffect(() => {
    if (!isPrefillDone) return;

    // hindari overwrite data prefilled sebelum user benar2 ubah (tetapi allow jika user sudah berinteraksi)
    if (isFormPrefilled && !hasUserInteractedRef.current) return;

    const fg = getValues('fgFasilitas');
    const bruto = Number(getValues('penghasilanBruto') || 0);
    const tarif = Number(getValues('tarif') || 0);
    const kode = getValues('kodeObjekPajak');
    const normaPenghasilanNeto = Number(getValues('normaPenghasilanNeto') || 0);

    let pph = 0;

    if (fg && !TARIF_0.includes(fg)) {
      if (kode === '27-100-06') {
        const norma = normaPenghasilanNeto || 0;
        pph = (bruto * (norma / 100) * tarif) / 100;
      } else {
        pph = (bruto * tarif) / 100;
      }
    }

    const currentPph = Number(getValues('pphDipotong') || 0);
    if (currentPph !== pph) {
      setValueInteger('pphDipotong', pph);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    penghasilanBruto,
    tarifWatched,
    fgFasilitas,
    normaPenghasilanNetoWatched,
    getValues,
    setValue,
    isPrefillDone,
    isFormPrefilled,
  ]);

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

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

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

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

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

    if (currentTarif !== kodeTarif) {
      setValuePreserve('tarif', kodeTarif); // ✅ keep decimals
    }
    // 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) {
      setValuePreserve('tarif', 0);
      setValue('noDokLainnya', '', { shouldValidate: true });
      return;
    }

    if (fgFasilitas === FG_FASILITAS_DN.SKD_WPLN) {
      return; // biarkan user isi sendiri
    }

    if (String(currentTarif) !== String(kodeTarif)) {
      setValuePreserve('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 TGetListDataKOPNr] ===
          1
      );
  }, [kodeObjekPajakSelected]);

  // --- Update normaPenghasilanNeto dari norma netto
  useEffect(() => {
    if (!kodeObjekPajakSelected) return;

    if (kodeObjekPajakSelected.kode === '27-100-06') {
      if (!getValues('normaPenghasilanNeto')) {
        setValuePreserve('normaPenghasilanNeto', '5');
      }
      return;
    }

    const normaNetto = kodeObjekPajakSelected?.normanetto ?? '';
    const currentnormaPenghasilanNeto = getValues('normaPenghasilanNeto');
    if (String(currentnormaPenghasilanNeto) !== String(normaNetto)) {
      setValuePreserve('normaPenghasilanNeto', normaNetto);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [kodeObjekPajakSelected, getValues, setValue]);

  return (
    <Grid container rowSpacing={2} columnSpacing={2}>
      <Grid sx={{ mt: 3 }} size={{ md: 6 }}>
        <Field.Select name="kodeObjekPajak" 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: 6 }}>
        <RHFNumeric
          name="penghasilanBruto"
          label="Jumlah Penghasilan Bruto (Rp)"
          allowNegativeValue={false}
          allowDecimalValue={false}
        />
      </Grid>

      <Grid size={{ md: 6 }}>
        {selectedKode === '27-100-06' ? (
          <Field.Select name="normaPenghasilanNeto" label="Perkiraan Penghasilan Netto (%)">
            <MenuItem value="5">5%</MenuItem>
            <MenuItem value="10">10%</MenuItem>
            <MenuItem value="25">25%</MenuItem>
          </Field.Select>
        ) : (
          <RHFNumeric
            name="normaPenghasilanNeto"
            label="Perkiraan Penghasilan Netto (%)"
            allowNegativeValue={false}
            allowDecimalValue={false}
            readOnly
          />
        )}
      </Grid>

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

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

export default PphDipotong;
