import { useQuery, type UseQueryOptions } from '@tanstack/react-query';
import type { AxiosError } from 'axios';

import { fetcher, endpoints } from 'src/lib/axios-ctas-box';

interface ApiResponse<T> {
  status: string;
  message?: string;
  data: T;
}

interface KodeNegara {
  kode: string;
  nama: string;
}

interface KodeNegaraResponse {
  data: KodeNegara[];
}

interface UseKodeNegaraReturn {
  kodeNegara: KodeNegara[];
  kodeNegaraLoading: boolean;
  kodeNegaraError: AxiosError | null;
}

interface QueryParams {
  [key: string]: any;
}

const queryOptions = {
  refetchOnWindowFocus: false,
  refetchOnReconnect: false,
  retry: 1,
} satisfies Omit<UseQueryOptions, 'queryKey' | 'queryFn'>;

const validateResponse = <T>(response: ApiResponse<T>): T => {
  if (response.status === 'fail' || response.status === 'error' || response.status === '0') {
    throw new Error(
      response.message || 'System tidak dapat memenuhi permintaan, coba beberapa saat lagi'
    );
  }

  return response.data;
};

const {
  kodeNegara,
  services,
  goods,
  kop_all,
  kop_bpnr,
  kop_bpsp,
  kop_bpu,
  faktur_keterangan,
  faktur_idtambahan,
  satuan,
} = endpoints.masterData;

export function useKodeNegara(): UseKodeNegaraReturn {
  const { data, isLoading, error } = useQuery<KodeNegara[], AxiosError>({
    queryKey: ['kodeNegara'],
    queryFn: async () => {
      const response = await fetcher<ApiResponse<KodeNegara[]>>(kodeNegara);

      return validateResponse(response);
    },
    ...queryOptions,
  });

  return {
    kodeNegara: data || [],
    kodeNegaraLoading: isLoading,
    kodeNegaraError: error,
  };
}

// ----------------------------------------------------------------------

export function useServices(params?: QueryParams) {
  const { data, isLoading, error } = useQuery<any, AxiosError>({
    queryKey: ['services', params],
    queryFn: async () => {
      const response = await fetcher<ApiResponse<any>>(services);
      return validateResponse(response);
    },
    ...queryOptions,
  });

  return {
    services: data,
    servicesLoading: isLoading,
    servicesError: error,
  };
}

// ----------------------------------------------------------------------

export function useGoods(params?: QueryParams) {
  const { data, isLoading, error } = useQuery<any, AxiosError>({
    queryKey: ['goods', params],
    queryFn: async () => {
      const response = await fetcher<ApiResponse<any>>(goods);
      return validateResponse(response);
    },
    ...queryOptions,
  });

  return {
    goods: data,
    goodsLoading: isLoading,
    goodsError: error,
  };
}

// ----------------------------------------------------------------------

export function useSatuan(params?: QueryParams) {
  const { data, isLoading, error } = useQuery<any, AxiosError>({
    queryKey: ['satuan', params],
    queryFn: async () => {
      const response = await fetcher<ApiResponse<any>>(satuan);
      return validateResponse(response);
    },
    ...queryOptions,
  });

  return {
    satuan: data,
    satuanLoading: isLoading,
    satuanError: error,
  };
}

// ----------------------------------------------------------------------

interface Penandatangan {
  // Define properties based on your API response
  [key: string]: any;
}

export function usePenandatangan() {
  const { data, isLoading, error } = useQuery<Penandatangan, AxiosError>({
    queryKey: ['penandatangan'],
    queryFn: async () => {
      const response = await fetcher<ApiResponse<Penandatangan>>('/signer');

      if (response.status === 'error') {
        throw new Error(response.message);
      }

      return response.data;
    },
    ...queryOptions,
  });

  return {
    penandatangan: data,
    penandatanganLoading: isLoading,
    penandatanganError: error,
  };
}

// ----------------------------------------------------------------------

type KodeObjekPajakType = 'bpnr' | 'bpu' | 'bpsp' | 'all';

const KODE_OBJEK_PAJAK_ENDPOINTS: Record<KodeObjekPajakType, string> = {
  bpnr: kop_bpnr,
  bpu: kop_bpu,
  bpsp: kop_bpsp,
  all: kop_all,
} as const;

export function useKodeObjekPajak(type: KodeObjekPajakType, params?: QueryParams) {
  const { data, isLoading, error } = useQuery<any, AxiosError>({
    queryKey: ['kodeObjekPajak', type, params],
    queryFn: async () => {
      const endpoint = KODE_OBJEK_PAJAK_ENDPOINTS[type];
      const response = await fetcher<ApiResponse<any>>(endpoint);

      // Endpoint 'all' mengembalikan response utuh, bukan hanya data
      return type === 'all' ? response : validateResponse(response);
    },
    ...queryOptions,
  });

  return {
    kodeObjekPajak: data,
    kodeObjekPajakLoading: isLoading,
    kodeObjekPajakError: error,
  };
}

// ----------------------------------------------------------------------

export function useKeteranganTambahan(params?: QueryParams) {
  const { data, isLoading, error } = useQuery<any, AxiosError>({
    queryKey: ['keteranganTambahan', params],
    queryFn: async () => {
      const response = await fetcher<ApiResponse<any>>(faktur_keterangan);
      return validateResponse(response);
    },
    ...queryOptions,
  });

  return {
    keteranganTambahan: data,
    keteranganTambahanLoading: isLoading,
    keteranganTambahanError: error,
  };
}

// ----------------------------------------------------------------------

export function useIdKeteranganTambahan(params?: QueryParams) {
  const { data, isLoading, error } = useQuery<any, AxiosError>({
    queryKey: ['idKeteranganTambahan', params],
    queryFn: async () => {
      const response = await fetcher<ApiResponse<any>>(faktur_idtambahan);
      return validateResponse(response);
    },
    ...queryOptions,
  });

  return {
    idKeteranganTambahan: data,
    idKeteranganTambahanLoading: isLoading,
    idKeteranganTambahanError: error,
  };
}
