import { isEmpty } from 'lodash';
import { useQuery } from '@tanstack/react-query';
import type {
  // TGetListDataTableDnResult,
  TGetListDataTableNr,
  TGetListDataTableNrResult,
} from '../types/types';
import { FG_PDF_STATUS, FG_SIGN_STATUS } from '../constant';
import queryKey from '../constant/queryKey';
import nrApi from '../utils/api';
import dayjs from 'dayjs';

export type TGetDnApiWrapped = {
  data: TGetListDataTableNrResult[];
  total: number;
  pageSize: number;
  page: number; // 1-based
};

// ---------- helpers (unchanged, kept for completeness) ----------
export const transformFgStatusToFgSignStatus = (fgStatus: any) => {
  const splittedFgStatus = fgStatus?.split('-') || [];

  if (splittedFgStatus.includes('SIGN') > 0) return FG_SIGN_STATUS.FAILED;
  if (splittedFgStatus.includes('SIGNING IN PROGRESS')) return FG_SIGN_STATUS.IN_PROGRESS;
  if (fgStatus === 'DUPLICATE') return FG_SIGN_STATUS.DUPLICATE;
  if (fgStatus === 'NOT_MATCH_STATUS') return FG_SIGN_STATUS.NOT_MATCH_STATUS;
  if (fgStatus === 'NOT_MATCH_NILAI') return FG_SIGN_STATUS.NOT_MATCH_NILAI;
  if (fgStatus === 'NOT_MATCH_IDBUPOT') return FG_SIGN_STATUS.NOT_MATCH_IDBUPOT;

  switch (splittedFgStatus[1]) {
    case 'document signed successfully':
    case 'Done':
      return FG_SIGN_STATUS.SIGNED;
    case 'SIGNING_IN_PROGRESS':
      return FG_SIGN_STATUS.IN_PROGRESS;
    case 'DUPLICATE':
      return FG_SIGN_STATUS.DUPLICATE;
    case 'NOT_MATCH_STATUS':
      return FG_SIGN_STATUS.NOT_MATCH_STATUS;
    case 'NOT_MATCH_IDBUPOT':
      return FG_SIGN_STATUS.NOT_MATCH_IDBUPOT;
    default:
      return null;
  }
};

export const getFgStatusPdf = (link: any, fgSignStatus: any) => {
  if (!link || [FG_SIGN_STATUS.IN_PROGRESS].includes(fgSignStatus))
    return FG_PDF_STATUS.TIDAK_TERSEDIA;
  if (!link.includes('https://coretaxdjp.pajak.go.id/')) return FG_PDF_STATUS.BELUM_TERBENTUK;
  return FG_PDF_STATUS.TERBENTUK;
};

export const transformSortModelToSortApiPayload = (transformedModel: any) => ({
  sortingMode: transformedModel.map((item: any) => item.field).join(','),
  sortingMethod: transformedModel.length > 0 ? transformedModel[0].sort : 'desc',
});

export const formatDateToDDMMYYYY = (dateString: string | null | undefined) => {
  if (!dateString) return '';
  const date = new Date(dateString);
  const day = String(date.getDate()).padStart(2, '0');
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const year = date.getFullYear();
  return `${day}/${month}/${year}`;
};

const normalisePropsGetNr = (params: TGetListDataTableNr) => ({
  ...params,
  nomorSP2D: params.dokumen_referensi?.[0]?.nomorSP2D || '',
  metodePembayaranBendahara: params.dokumen_referensi?.[0]?.metodePembayaranBendahara || '',
  dokReferensi: params.dokumen_referensi?.[0]?.dokReferensi || '',
  nomorDokumen: params.dokumen_referensi?.[0]?.nomorDokumen || '',
  id: params.id,
  npwpPemotong: params.npwpPemotong,
  idBupot: params.idBupot,
  internal_id: params.internal_id,
  fgStatus: params.fgStatus,
  fgSignStatus: transformFgStatusToFgSignStatus(params.fgStatus),
  fgPdf: getFgStatusPdf(params.link, transformFgStatusToFgSignStatus(params.fgStatus)),
  // fgLapor: params.fgLapor,
  revNo: params.revNo,
  thnPajak: params.tahunPajak,
  msPajak: params.masaPajak,
  kdObjPjk: params.kodeObjekPajak,
  noBupot: params.noBupot,
  idDipotong: params.userId,
  glAccount: params.glAccount,
  namaDipotong: params.nama,
  jmlBruto: params.dpp,
  pphDipotong: params.pphDipotong,
  created: params.created_by,
  fgKirimEmail: params.fgkirimemail,
  created_at: formatDateToDDMMYYYY(params.created_at),
  updated: params.updated_by,
  updated_at: formatDateToDDMMYYYY(params.updated_at),
});

export const normalizeExistingNr = (res: any) => ({
  // 🧾 Data Pajak Utama
  tglPemotongan: res.tglpemotongan ?? '',
  thnPajak: res.tahunPajak ?? '',
  msPajak: res.masaPajak ?? '',

  // 👤 Identitas Dipotong
  idDipotong: res.npwpPemotong ?? '',
  namaDipotong: res.namaDipotong ?? '',
  alamatDipotong: res.alamatDipotong ?? '',
  negaraDipotong: res.negaraDipotong ?? '',
  tmptLahirDipotong: res.tmptLahirDipotong ?? '',
  tglLahirDipotong:
    res.tglLahirDipotong && res.tglLahirDipotong.length === 8
      ? dayjs(res.tglLahirDipotong, 'DDMMYYYY').format('YYYY-MM-DD')
      : '',
  nomorPaspor: res.nomorPaspor ?? '',
  nomorKitasKitap: res.nomorKitasKitap ?? '',

  // 🧠 Informasi Tambahan
  email: res.email ?? '',
  keterangan1: res.keterangan1 ?? '',
  keterangan2: res.keterangan2 ?? '',
  keterangan3: res.keterangan3 ?? '',
  keterangan4: res.keterangan4 ?? '',
  keterangan5: res.keterangan5 ?? '',

  // 💰 Pajak dan Penghasilan
  kodeObjekPajak: res.kodeObjekPajak ?? '',
  fgFasilitas: res.sertifikatInsentifDipotong ?? '',
  noDokLainnya: res.nomorSertifikatInsentif ?? '',
  penghasilanBruto: res.penghasilanBruto ?? '',
  normaPenghasilanNeto: res.normaPenghasilanNeto ?? '',
  tarif: String(res.tarif ?? ''),
  pphDipotong: String(res.pphDipotong ?? ''),

  // 📄 Dokumen Referensi
  namaDok: res.dokumen_referensi?.[0]?.dokReferensi ?? '',
  nomorDok: res.dokumen_referensi?.[0]?.nomorDokumen ?? '',
  tglDok: res.dokumen_referensi?.[0]?.tanggal_Dokumen ?? '',

  // 🏢 Cabang / Unit
  idTku: res.idTku ?? '',

  // 🆔 Metadata tambahan
  idBupot: res.idBupot ?? '',
  noBupot: res.noBupot ?? '',
  revNo: res.revNo ?? 0,
});

const normalizeParams = (params: any) => {
  const {
    page = 0,
    pageSize = params.limit ?? 10,
    sort,
    filter,
    advanced,
    sortingMode: sortingModeParam,
    sortingMethod: sortingMethodParam,
    ...rest
  } = params;

  let sortPayload: any;
  let sortingMode = sortingModeParam || '';
  let sortingMethod = sortingMethodParam || '';

  if (sort) {
    try {
      const parsed = JSON.parse(sort);
      if (Array.isArray(parsed) && parsed.length > 0) {
        sortPayload = parsed;
        sortingMode = parsed[0]?.field ?? sortingMode;
        sortingMethod = parsed[0]?.sort ?? sortingMethod;
      }
    } catch {
      sortPayload = [];
    }
  }

  return {
    page: page + 1,
    limit: pageSize,
    advanced:
      typeof advanced === 'string' && advanced.trim() !== ''
        ? advanced
        : filter && !isEmpty(JSON.parse(filter))
          ? filter
          : undefined,
    ...(sortPayload ? { sort: sortPayload } : {}),
    sortingMode,
    sortingMethod,
    ...rest,
  };
};

export const useGetNr = ({ params }: { params: any }) => {
  const { page, limit, advanced, sortingMode, sortingMethod } = params;
  const normalized = normalizeParams(params);

  return useQuery<TGetDnApiWrapped>({
    queryKey: ['dn', page, limit, advanced, sortingMode, sortingMethod],

    queryFn: async () => {
      const res: any = await nrApi.getNr({ params: normalized });

      const rawData: any[] = Array.isArray(res?.data) ? res.data : res?.data ? [res.data] : [];

      const total = Number(res?.total ?? res?.totalRow ?? 0);

      let dataArray: TGetListDataTableNrResult[] = [];

      const normalizeWithWorker = () =>
        new Promise<TGetListDataTableNrResult[]>((resolve, reject) => {
          try {
            const worker = new Worker(
              new URL('../workers/normalizeNr.worker.js', import.meta.url),
              { type: 'module' }
            );

            worker.onmessage = (e) => {
              const { data, error } = e.data;
              if (error) {
                worker.terminate();
                reject(new Error(error));
              } else {
                worker.terminate();
                resolve(data as TGetListDataTableNrResult[]);
              }
            };

            worker.onerror = (err) => {
              worker.terminate();
              reject(err);
            };

            worker.postMessage(rawData);
          } catch (err) {
            reject(err);
          }
        });

      try {
        if (typeof Worker !== 'undefined') {
          dataArray = await normalizeWithWorker();
        } else {
          console.warn('⚠️ Worker not supported, using sync normalization');
          dataArray = rawData.map(normalisePropsGetNr) as unknown as TGetListDataTableNrResult[];
        }
      } catch (err) {
        console.error('❌ Worker failed, fallback to sync normalize:', err);
        dataArray = rawData.map(normalisePropsGetNr) as unknown as TGetListDataTableNrResult[];
      }

      return {
        data: dataArray,
        total,
        pageSize: normalized.limit,
        page: normalized.page,
      };
    },

    placeholderData: (prev) => prev,
    refetchOnWindowFocus: false,
    refetchOnMount: false,
    staleTime: 0,
    gcTime: 0,
    retry: false,
  });
};

export const useGetNrById = (id: string, options = {}) =>
  useQuery({
    queryKey: queryKey.nr.detail(id),
    queryFn: async () => {
      const res = await nrApi.getNrById(id);
      console.log(res);
      if (!res) throw new Error('Data tidak ditemukan');
      const normalized = normalizeExistingNr(res);
      console.log('✅ Normalized data:', normalized);
      return normalized;
    },
    enabled: !!id,
    refetchOnWindowFocus: false,
    ...options,
  });

export default useGetNr;
