import React, { useEffect, useRef } from 'react';
import { useForm, FormProvider, useWatch, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';

import DialogUmum from 'src/shared/components/dialog/DialogUmum';
import DialogContent from '@mui/material/DialogContent';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';

import Grid from '@mui/material/Grid';
import { RHFNumeric } from 'src/components/hook-form/rhf-numeric';
import FormLabel from '@mui/material/FormLabel';
import RadioGroup from '@mui/material/RadioGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import Radio from '@mui/material/Radio';
import Divider from '@mui/material/Divider';
import { Field, RHFCheckbox } from 'src/components/hook-form';
import MenuItem from '@mui/material/MenuItem';
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import { BarangJasaSchema, TBarangJasaSchema } from '../../schemas/detailBarangSchema';
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import { TGoods, TGoodsResult, TSatuanResult, TServiceResult, TServices } from '../../types/types';

interface ModalDetailTransaksiBarangProps {
  payload?: {
    goods?: TGoodsResult;
    services?: TServiceResult;
    satuan?: TSatuanResult;
  };
  isOpen: boolean;
  onClose: () => void;
  detailTransaksi?: string;
  onSave?: (obj: any) => void;
  defaultValues?: TBarangJasaSchema | null;
}

const DEFAULT_FORM: TBarangJasaSchema = {
  type: 'GOODS',
  kdBrgJasa: '',
  namaBrgJasa: '',
  satuanBrgJasa: '',
  jmlBrgJasa: '0',
  hargaSatuan: '0',
  totalHarga: '0',
  diskon: '0',
  fgPmk: '',
  dpp: '0',
  tarifPpn: '12',
  dppLain: '0',
  ppn: '0',
  tarifPpnbm: '0',
  ppnbm: '0',

  // retur fields (initial)
  returJmlBrgJasa: '0',
  totalHargaRetur: '0',
  returDiskon: '0',
  returDpp: '0',
  returDppLain: '0',
  returPpn: '0',
  returPpnbm: '0',
};

const toString = (v: any, fallback = '0') => (v === undefined || v === null ? fallback : String(v));

const normalizeDefaultValues = (src?: any): TBarangJasaSchema => ({
  type: String(src?.type ?? src?.brgJasa ?? 'GOODS'),
  kdBrgJasa: src?.kdBrgJasa ?? src?.kode ?? '',
  namaBrgJasa: src?.namaBrgJasa ?? src?.nama ?? '',
  satuanBrgJasa: src?.satuanBrgJasa ?? src?.satuan ?? '',
  jmlBrgJasa: toString(src?.jmlBrgJasa ?? src?.jumlah ?? '0'),
  hargaSatuan: toString(src?.hargaSatuan ?? src?.harga ?? '0'),
  totalHarga: toString(src?.totalHarga ?? src?.total ?? '0'),
  diskon: toString(src?.diskon ?? '0'),
  fgPmk: src?.fgPmk ?? '',
  dpp: toString(src?.dpp ?? '0'),
  tarifPpn: toString(src?.tarifPpn ?? '12'),
  dppLain: toString(src?.dppLain ?? '0'),
  ppn: toString(src?.ppn ?? '0'),
  tarifPpnbm: toString(src?.tarifPpnbm ?? '0'),
  ppnbm: toString(src?.ppnbm ?? '0'),

  returJmlBrgJasa: toString(src?.returJmlBrgJasa ?? '0'),
  totalHargaRetur: toString(src?.totalHargaRetur ?? '0'),
  returDiskon: toString(src?.returDiskon ?? '0'),
  returDpp: toString(src?.returDpp ?? '0'),
  returDppLain: toString(src?.returDppLain ?? '0'),
  returPpn: toString(src?.returPpn ?? '0'),
  returPpnbm: toString(src?.returPpnbm ?? '0'),
});

const safeNumber = (v?: string | number | null) => {
  const n = Number(v ?? 0);
  return Number.isFinite(n) ? n : 0;
};

// helper to format numeric string with 2 decimals (remove if not desired)
const fmt = (n: number) =>
  // if integer, keep as integer string; else toFixed(2)
  Number.isInteger(n) ? String(n) : n.toFixed(2);
const ModalDetailTransaksiBarang: React.FC<ModalDetailTransaksiBarangProps> = ({
  payload,
  isOpen,
  onClose,
  detailTransaksi = '',
  onSave,
  defaultValues = null,
}) => {
  // const [alertInfo, setAlertInfo] = useState(true);

  const methods = useForm<TBarangJasaSchema>({
    mode: 'all',
    resolver: zodResolver(BarangJasaSchema),
    defaultValues: DEFAULT_FORM,
  });

  const { control, setValue, getValues, reset, handleSubmit } = methods;

  const type = useWatch({ control, name: 'type' });
  const kdBrgJasa = useWatch({ control, name: 'kdBrgJasa' });
  const jmlBrgJasa = useWatch({ control, name: 'jmlBrgJasa' });
  const hargaSatuan = useWatch({ control, name: 'hargaSatuan' });
  const diskon = useWatch({ control, name: 'diskon' });
  const fgPmk = useWatch({ control, name: 'fgPmk' });
  const tarifPpnbm = useWatch({ control, name: 'tarifPpnbm' });

  // retur watches
  const returJmlBrgJasa = useWatch({ control, name: 'returJmlBrgJasa' });
  // const returDiskon = useWatch({ control, name: 'returDiskon' });
  // const returDpp = useWatch({ control, name: 'returDpp' });
  // const returDppLain = useWatch({ control, name: 'returDppLain' });
  // const returPpn = useWatch({ control, name: 'returPpn' });
  // const returPpnbm = useWatch({ control, name: 'returPpnbm' });
  const ppnTotal = useWatch({ control, name: 'ppn' });
  const ppnbmTotal = useWatch({ control, name: 'ppnbm' });

  // LIST DATA
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const goods = payload?.goods ?? [];
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const services = payload?.services ?? [];
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const satuan = payload?.satuan ?? [];

  const isPayloadReady =
    Boolean(payload) && (goods.length > 0 || services.length > 0) && satuan.length > 0;
  //-------------------------------------
  // Modal buka → tentukan ADD atau EDIT
  //-------------------------------------
  useEffect(() => {
    if (!isOpen) return;

    if (defaultValues) {
      reset(normalizeDefaultValues(defaultValues)); // EDIT
    } else {
      reset(DEFAULT_FORM); // ADD
    }
    // reset manual auto-calculated trackers
    lastAutoRef.current = {
      totalHargaRetur: undefined,
      returDpp: undefined,
      returDppLain: undefined,
      returPpn: undefined,
      returPpnbm: undefined,
    };
  }, [isOpen, defaultValues, reset]);

  //-------------------------------------
  // OPTIONS LIST
  //-------------------------------------
  type ItemKode = TGoods | TServices;
  const kodeList: ItemKode[] = React.useMemo(
    () => (type === 'GOODS' ? goods : services),
    [goods, services, type]
  );

  const filteredSatuan = React.useMemo(
    () =>
      satuan.filter((item: any) => {
        const num = Number(String(item.code).split('.')[1]);
        if (type === 'GOODS') return (num >= 1 && num <= 22) || (num >= 33 && num <= 39);
        if (type === 'SERVICES') return num >= 23 && num <= 33;
        return true;
      }),
    [satuan, type]
  );

  //-------------------------------------
  // AUTO FILL namaBrgJasa
  //-------------------------------------
  useEffect(() => {
    if (!kdBrgJasa) return;
    const selected = kodeList.find((it) => String(it.code) === String(kdBrgJasa));
    if (selected) {
      const nama = (selected as any).bahasa ?? '';
      setValue('namaBrgJasa', nama);
    }
  }, [kdBrgJasa, kodeList, setValue]);

  //-------------------------------------
  // AUTO TOTAL HARGA (original)
  //-------------------------------------
  useEffect(() => {
    const jumlah = Number(jmlBrgJasa || 0);
    const harga = Number(hargaSatuan || 0);
    setValue('totalHarga', String(jumlah * harga));
  }, [jmlBrgJasa, hargaSatuan, setValue]);

  //-------------------------------------
  // AUTO DPP (original)
  //-------------------------------------
  useEffect(() => {
    const jumlah = Number(jmlBrgJasa || 0);
    const harga = Number(hargaSatuan || 0);
    const disc = Number(diskon || 0);
    setValue('dpp', String(jumlah * harga - disc));
  }, [jmlBrgJasa, hargaSatuan, diskon, setValue]);

  //-------------------------------------
  // TARIF PPN FIX 12%
  //-------------------------------------
  useEffect(() => {
    setValue('tarifPpn', '12');
  }, [setValue]);

  //-------------------------------------
  // CLAMP TARIF PPnBM
  //-------------------------------------
  useEffect(() => {
    const raw = Number(tarifPpnbm || 0);
    const clamp = Math.max(0, Math.min(100, Math.round(raw)));
    setValue('tarifPpnbm', String(clamp));
  }, [tarifPpnbm, setValue]);

  //-------------------------------------
  // HITUNG DPP LAIN & PPN (original)
  //-------------------------------------
  useEffect(() => {
    const dpp = Number(getValues('dpp') || 0);
    const tarifPpnbmNum = Number(getValues('tarifPpnbm') || 0);

    let dppLain = dpp;
    if (detailTransaksi !== 'TD.00301') {
      if (fgPmk === '0') dppLain = (dpp * 11) / 12;
      if (fgPmk === '1') dppLain = dpp;
    }

    const ppn = (dppLain * 12) / 100;
    const ppnbm = (dppLain * tarifPpnbmNum) / 100;

    setValue('dppLain', String(dppLain));
    setValue('ppn', String(ppn));
    setValue('ppnbm', String(ppnbm));
  }, [fgPmk, detailTransaksi, jmlBrgJasa, hargaSatuan, diskon, tarifPpnbm, getValues, setValue]);

  // ------------------------------------
  // DERIVED RETUR FIELDS LOGIC
  // - clamp returJmlBrgJasa <= jmlBrgJasa
  // - auto-calc totalHargaRetur, returDpp, returDppLain, returPpn, returPpnbm
  // - DO NOT overwrite user-edited values (use lastAutoRef compare)
  // ------------------------------------
  const lastAutoRef = useRef<{
    totalHargaRetur?: string | undefined;
    returDpp?: string | undefined;
    returDppLain?: string | undefined;
    returPpn?: string | undefined;
    returPpnbm?: string | undefined;
  }>({
    totalHargaRetur: undefined,
    returDpp: undefined,
    returDppLain: undefined,
    returPpn: undefined,
    returPpnbm: undefined,
  });

  useEffect(() => {
    // base numbers
    const jmlNum = safeNumber(jmlBrgJasa);
    const hargaNum = safeNumber(hargaSatuan);
    const returNumRaw = safeNumber(returJmlBrgJasa);
    const returNum = Math.max(0, returNumRaw);

    // clamp retur to available quantity
    const clampedRetur = Math.min(returNum, jmlNum);
    if (clampedRetur !== returNum) {
      // update returJmlBrgJasa to clamped value (string)
      setValue('returJmlBrgJasa', String(clampedRetur));
    }

    // recompute using clamped value
    const usedRetur = clampedRetur;

    // computed values
    const totalHargaReturCalc = usedRetur * hargaNum;
    const returDppCalc = usedRetur * hargaNum; // as requested
    const returDppLainCalc = usedRetur * hargaNum; // same base (adjustable)
    // prorata for PPN / PPnBM: use total ppn/ppnbm stored in form and prorate by (retur / jml)
    const ppnTotalNum = safeNumber(ppnTotal);
    const ppnbmTotalNum = safeNumber(ppnbmTotal);

    const returPpnCalc = jmlNum > 0 ? (usedRetur / jmlNum) * ppnTotalNum : 0;
    const returPpnbmCalc = jmlNum > 0 ? (usedRetur / jmlNum) * ppnbmTotalNum : 0;

    // helper to decide whether to overwrite a field:
    const maybeSet = (fieldName: keyof typeof lastAutoRef.current, computedValueNum: number) => {
      const computedStr = fmt(computedValueNum);
      const current = String(getValues(fieldName) ?? '');
      const lastAuto = lastAutoRef.current[fieldName];

      // If current equals last auto value OR current is empty/zero -> update.
      // If current differs (user edited), do not overwrite.
      const currentNum = safeNumber(current);
      const lastAutoNum = safeNumber(lastAuto);

      const isCurrentEqualLastAuto = String(currentNum) === String(lastAutoNum);
      const isCurrentEmptyOrZero = current === '' || currentNum === 0;

      if (isCurrentEqualLastAuto || isCurrentEmptyOrZero) {
        setValue(fieldName, computedStr);
        lastAutoRef.current[fieldName] = computedStr;
      } else {
        // do not overwrite; but still update lastAutoRef to current computed for future equality check
        lastAutoRef.current[fieldName] = computedStr;
      }
    };

    // totalHargaRetur
    maybeSet('totalHargaRetur', totalHargaReturCalc);

    // returDpp & returDppLain
    maybeSet('returDpp', returDppCalc);
    maybeSet('returDppLain', returDppLainCalc);

    // returPpn & returPpnbm
    maybeSet('returPpn', returPpnCalc);
    maybeSet('returPpnbm', returPpnbmCalc);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    returJmlBrgJasa,
    jmlBrgJasa,
    hargaSatuan,
    ppnTotal,
    ppnbmTotal,
    // include getValues & setValue stable from methods
  ]);

  //-------------------------------------
  // SAVE
  //-------------------------------------
  const onSubmit = (data: TBarangJasaSchema) => {
    const entry = {
      ...data,
      brgJasa: data.type,
      jmlBrgJasa: Number(data.jmlBrgJasa),
      hargaSatuan: Number(data.hargaSatuan),
      totalHarga: Number(data.totalHarga),
      diskon: Number(data.diskon),
      dpp: Number(data.dpp),
      dppLain: Number(data.dppLain),
      tarifPpn: Number(data.tarifPpn),
      tarifPpnbm: Number(data.tarifPpnbm),
      ppn: Number(data.ppn),
      ppnbm: Number(data.ppnbm),

      // retur fields proper numeric types
      returJmlBrgJasa: Number(data.returJmlBrgJasa),
      totalHargaRetur: Number(data.totalHargaRetur),
      returDiskon: Number(data.returDiskon),
      returDpp: Number(data.returDpp),
      returDppLain: Number(data.returDppLain),
      returPpn: Number(data.returPpn),
      returPpnbm: Number(data.returPpnbm),

      cekDppLain: data.fgPmk === '0' || data.fgPmk === '1',
    };

    onSave?.(entry);

    // setelah save → kembali ke ADD
    reset(DEFAULT_FORM);
  };

  //-------------------------------------
  // CLOSE
  //-------------------------------------
  const handleClose = () => {
    reset(DEFAULT_FORM);
    onClose();
  };

  //-------------------------------------
  // RENDER
  //-------------------------------------
  return (
    <DialogUmum
      titleSx={{ mb: 2 }}
      maxWidth="md"
      isOpen={isOpen}
      onClose={handleClose}
      title="Detail Penyerahan Barang/Jasa"
    >
      <FormProvider {...methods}>
        <DialogContent classes={{ root: 'p-16 sm:p-24' }}>
          <Grid container spacing={2} sx={{ mb: 3 }}>
            {/* Type Radio */}
            <Grid size={{ md: 4 }}>
              <Controller
                name="type"
                control={control}
                render={({ field }) => (
                  <>
                    <FormLabel sx={{ mb: 1, fontWeight: 600 }}>Type</FormLabel>
                    <RadioGroup row {...field}>
                      <FormControlLabel value="GOODS" control={<Radio />} label="Barang" disabled />
                      <FormControlLabel
                        value="SERVICES"
                        control={<Radio />}
                        label="Jasa"
                        disabled
                      />
                    </RadioGroup>
                  </>
                )}
              />
            </Grid>

            <Grid size={{ md: 8 }} sx={{ display: 'flex', alignItems: 'end' }}>
              <Field.Select name="kdBrgJasa" label="Kode Barang/Jasa" disabled>
                {!isPayloadReady && goods.length === 0 && services.length === 0 ? (
                  <MenuItem disabled>Loading...</MenuItem>
                ) : kodeList.length > 0 ? (
                  kodeList.map((item, idx) => (
                    <MenuItem key={idx} value={(item as any).code}>
                      {`${(item as any).code} - ${(item as any).bahasa}`}
                    </MenuItem>
                  ))
                ) : (
                  <MenuItem disabled value="">
                    Tidak ada data
                  </MenuItem>
                )}
              </Field.Select>
            </Grid>

            <Grid size={{ md: 6 }}>
              <Field.Text name="namaBrgJasa" label="Nama Barang/Jasa" disabled />
            </Grid>

            <Grid size={{ md: 6 }}>
              <Field.Select name="satuanBrgJasa" label="Satuan Barang/Jasa" disabled>
                {!isPayloadReady && !satuan.length ? (
                  <MenuItem disabled>Loading...</MenuItem>
                ) : filteredSatuan.length > 0 ? (
                  filteredSatuan.map((item, idx) => (
                    <MenuItem key={idx} value={(item as any).code}>
                      {`${(item as any).code} - ${(item as any).description}`}
                    </MenuItem>
                  ))
                ) : (
                  <MenuItem disabled value="">
                    Tidak ada data
                  </MenuItem>
                )}
              </Field.Select>
            </Grid>

            {/* Nilai Barang */}
            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="jmlBrgJasa"
                label="Jumlah Barang/Jasa"
                allowDecimalValue
                decimalScale={2}
                readOnly
              />
            </Grid>

            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="hargaSatuan"
                label="Harga Satuan (Rp)"
                allowDecimalValue
                decimalScale={2}
                readOnly
              />
            </Grid>

            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="totalHarga"
                label="Harga Total (Rp)"
                allowDecimalValue
                decimalScale={2}
                readOnly
              />
            </Grid>

            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="diskon"
                label="Diskon (Rp)"
                allowDecimalValue
                decimalScale={2}
                readOnly
              />
            </Grid>

            {/* Divider */}
            <Grid size={{ md: 12 }} sx={{ mt: 3 }}>
              <Divider sx={{ fontWeight: 'bold', fontSize: '1rem', mb: 2 }} textAlign="left">
                PPN & PPnBM
              </Divider>
            </Grid>

            <Grid size={{ md: 6 }}>
              <RHFNumeric name="dpp" label="DPP (Rp)" allowDecimalValue decimalScale={2} readOnly />
            </Grid>

            <Grid size={{ md: 2 }}>
              <RHFCheckbox name="fgDppLain" label="DPP Nilai Lain" disabled />
            </Grid>

            <Grid size={{ md: 4 }}>
              <RHFNumeric
                name="dppLain"
                label="DPP Nilai Lain (Rp)"
                allowDecimalValue
                decimalScale={2}
                readOnly={detailTransaksi === 'TD.00301' || fgPmk !== '1'}
              />
            </Grid>

            <Grid size={{ md: 6 }}>
              <RHFNumeric name="tarifPpn" label="Tarif PPN %" allowDecimalValue={false} readOnly />
            </Grid>

            <Grid size={{ md: 6 }}>
              <RHFNumeric name="ppn" label="PPN (Rp)" allowDecimalValue decimalScale={2} readOnly />
            </Grid>

            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="tarifPpnbm"
                label="Tarif PPnBM %"
                allowDecimalValue={false}
                readOnly
              />
            </Grid>

            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="ppnbm"
                label="PPnBM (Rp)"
                allowDecimalValue
                decimalScale={2}
                readOnly
              />
            </Grid>

            <Grid size={{ md: 12 }} sx={{ mt: 3 }}>
              <Divider sx={{ fontWeight: 'bold', fontSize: '1rem', mb: 2 }} textAlign="left">
                Retur PPN & PPnBM
              </Divider>
            </Grid>

            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="returJmlBrgJasa"
                label="Retur Jumlah Barang/Jasa"
                allowDecimalValue
                decimalScale={2}
              />
            </Grid>
            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="hargaSatuan"
                label="Harga Satuan (Rp)"
                allowDecimalValue
                decimalScale={2}
                readOnly
              />
            </Grid>
            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="totalHargaRetur"
                label="Harga Total Retur (Rp)"
                allowDecimalValue
                decimalScale={2}
                readOnly
              />
            </Grid>
            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="returDiskon"
                label="Retur Diskon (Rp)"
                allowDecimalValue
                decimalScale={2}
              />
            </Grid>
            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="returDpp"
                label="Retur DPP (Rp)"
                allowDecimalValue
                decimalScale={2}
              />
            </Grid>
            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="returDppLain"
                label="Retur DPP Nilai Lain (Rp)"
                allowDecimalValue
                decimalScale={2}
              />
            </Grid>
            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="returPpn"
                label="Return PPN (Rp)"
                allowDecimalValue
                decimalScale={2}
              />
            </Grid>
            <Grid size={{ md: 6 }}>
              <RHFNumeric
                name="returPpnbm"
                label="Retur PPnBM (Rp)"
                allowDecimalValue
                decimalScale={2}
              />
            </Grid>
          </Grid>

          <Box sx={{ width: '100%', display: 'flex', justifyContent: 'right' }}>
            <Button
              type="button"
              onClick={handleSubmit(onSubmit)}
              variant="contained"
              sx={{ background: '#143B88' }}
            >
              Simpan
            </Button>
          </Box>
        </DialogContent>
      </FormProvider>
    </DialogUmum>
  );
};

export default ModalDetailTransaksiBarang;
