import { isEmpty } from 'lodash';
import { useQuery, type UseQueryOptions } from '@tanstack/react-query';
import dnApi from '../utils/api';
import type { TGetListDataTableDn, TGetListDataTableDnResult } from '../types/types';
import { FG_PDF_STATUS, FG_SIGN_STATUS } from '../constant';
import queryKey from '../constant/queryKey';

export type TGetDnApiWrapped = {
  data: TGetListDataTableDnResult[];
  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 normalisePropsGetDn = (params: TGetListDataTableDn) => ({
  ...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),
});

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 useGetDn = ({
  params,
  option,
}: {
  params: any;
  option?: Omit<UseQueryOptions, 'queryKey' | 'queryFn'>;
}) => {
  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 dnApi.getDn({ 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: TGetListDataTableDnResult[] = [];

      const normalizeWithWorker = () =>
        new Promise<TGetListDataTableDnResult[]>((resolve, reject) => {
          try {
            const worker = new Worker(
              new URL('../workers/normalizeDn.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 TGetListDataTableDnResult[]);
              }
            };

            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(normalisePropsGetDn) as unknown as TGetListDataTableDnResult[];
        }
      } catch (err) {
        console.error('❌ Worker failed, fallback to sync normalize:', err);
        dataArray = rawData.map(normalisePropsGetDn) as unknown as TGetListDataTableDnResult[];
      }

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

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

export const useGetDnById = (id: string, options = {}) =>
  useQuery({
    queryKey: queryKey.dn.detail(id),
    queryFn: async () => {
      console.log('🔍 Fetching getDnById with ID:', id);
      const res = await dnApi.getDnById(id);
      if (!res) throw new Error('Data tidak ditemukan');

      const normalized = {
        id: res.id ?? '',
        tglPemotongan: res.tglpemotongan ?? '',
        thnPajak: res.tahunPajak ?? '',
        msPajak: res.masaPajak ?? '',
        idDipotong: res.npwpPemotong ?? '',
        nitku: res.idTku ?? '',
        namaDipotong: res.nama ?? '',
        email: res.email ?? '',
        keterangan1: res.keterangan1 ?? '',
        keterangan2: res.keterangan2 ?? '',
        keterangan3: res.keterangan3 ?? '',
        keterangan4: res.keterangan4 ?? '',
        keterangan5: res.keterangan5 ?? '',
        kdObjPjk: res.kodeObjekPajak ?? '',
        fgFasilitas: res.sertifikatInsentifDipotong ?? '',
        noDokLainnya: res.nomorSertifikatInsentif ?? '',
        jmlBruto: res.dpp ?? '',
        tarif: String(res.tarif ?? ''),
        pphDipotong: String(res.pphDipotong ?? ''),
        namaDok: res.dokumen_referensi?.[0]?.dokReferensi ?? '',
        nomorDok: res.dokumen_referensi?.[0]?.nomorDokumen ?? '',
        tglDok: res.dokumen_referensi?.[0]?.tanggal_Dokumen ?? '',
        idTku: res.idTku ?? '',
        revNo: res.revNo ?? 0,
        noBupot: res.noBupot ?? '',
        idBupot: res.idBupot ?? '',
      };

      console.log('✅ Normalized data:', normalized);
      return normalized;
    },
    enabled: !!id,
    refetchOnWindowFocus: false,
    ...options,
  });

export default useGetDn;
