import { useMutation, useQuery } from "@tanstack/react-query";
import { useEffect, useRef } from "react";
import { useTranslation } from "react-i18next";
import { fetchAttachment } from "@/record-management/services/api/attachmentService";
import {
  getIncoming,
  getIncomingParent,
  getIncomingV2,
} from "@/record-management/services/api/incomingRecordService";
import { MeDto } from "@/shared/dto/user/meDto";
import { useUserDetail } from "./useUserDetail";
import { useAuthUser } from "@/shared/hooks/useAuthUser";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";

export interface UseExternalIncomingRecordsParams {
  pageIndex?: number;
  pageSize?: number;
  status?: string;
  order?: string;
  searchQuery?: string;
  filterType?: string;
  referenceNumber?: string;
  subject?: string;
  fromDispatchedDate?: string;
  toDispatchedDate?: string;
  sendingPosition?: string;
  from?: string; // Sender information filter
  [key: string]: any; // allow extra filters
}

export const useExternalIncomingRecords = ({
  fetchParent,
  recordType = ["external", "non_smart_user", "external_non_smart_user"],
  pageIndex = 0,
  pageSize = 10,
  status,
  order = "createdAt:DESC",
  searchQuery,
  filterType,
  ...filters
}: UseExternalIncomingRecordsParams = {}) => {
  const { userDetails } = useAuthUser();
  const { permissionKeys } = useUserDetail(userDetails as MeDto);
  const RO = permissionKeys.includes("can:dispatchRecords");
  const { t } = useTranslation();
  const { handleError } = useErrorHandler(t);
  // const recordTypes: string[] = [
  //   "external",
  //   "non_smart_user",
  //   "branch",
  //   "external_non_smart_user",
  // ];

  // Build query params
  const params: Record<string, any> = {
    recordType: recordType,
    status: status ?? undefined,
    skip: pageIndex,
    take: pageSize,
    orderBy: order,
  };

  // Map searchQuery depending on filterType
  if (searchQuery) {
    switch (filterType) {
      case "Department":
        params.receiverPosition = searchQuery;
        break;
      case "Subject":
        params.subject = searchQuery;
        break;
      case "Date":
      case "Dispatched Date":
        params.fromDispatchedDate = searchQuery;
        break;
      case "Reference Number":
        params.referenceNumber = searchQuery;
        break;
    }
  }

  // Handle dispatched date range filters
  if (filters.fromDispatchedDate) {
    params.fromDispatchedDate = filters.fromDispatchedDate;
  }
  if (filters.toDispatchedDate) {
    params.toDispatchedDate = filters.toDispatchedDate;
  }

  Object.assign(params, filters); // merge extra filters
  const v2Params = { ...params };
  delete v2Params.orderBy;

  const { data, isLoading, isError, error, refetch } = useQuery({
    queryKey: [
      "external-incoming",
      pageIndex,
      pageSize,
      status,
      filterType,
      searchQuery,
      order,
      filters,
      recordType,
    ],
    queryFn: () => getIncoming(!RO ? params : {}),
    staleTime: 1000 * 60 * 5, // 5 minutes
    enabled: Boolean(!RO),
  });
  const {
    data: dataV2,
    isLoading: isLoadingV2,
    isError: isErrorV2,
    error: errorV2,
    refetch: refetchV2,
  } = useQuery({
    queryKey: [
      "external-incoming-v2",
      pageIndex,
      pageSize,
      status,
      filterType,
      searchQuery,
      order,
      filters,
      recordType,
    ],
    queryFn: () => getIncomingV2(!RO ? v2Params : {}),
    staleTime: 1000 * 60 * 5, // 5 minutes
    enabled: Boolean(!RO),
  });
  const {
    data: dataParent,
    isLoading: isLoadingParent,
    isError: isErrorParent,
    error: parentError,
    refetch: refetchParent,
  } = useQuery({
    queryKey: [
      "external-incoming-parent",
      pageIndex,
      pageSize,
      status,
      filterType,
      searchQuery,
      order,
      filters,
      recordType,
    ],
    queryFn: () => getIncomingParent(fetchParent ? params : {}),
    staleTime: 1000 * 60 * 5, // 5 minutes
    enabled: Boolean(fetchParent),
  });

  // Surface list-fetch failures via the centralized error handler.
  const listFetchError = error || parentError;
  const prevListErrorRef = useRef<unknown>(null);
  useEffect(() => {
    if (listFetchError && listFetchError !== prevListErrorRef.current) {
      prevListErrorRef.current = listFetchError;
      handleError(listFetchError);
    }
  }, [listFetchError, handleError]);

  const externalRecords = data?.items ?? [];
  const externalCount = data?.count ?? 0;
  const externalRecords2 = dataV2?.items ?? [];
  const externalCount2 = dataV2?.count ?? 0;

  const {
    mutate: fetchAttachments,
    data: attachmentsData,
    isError: isAttachmentsError,
  } = useMutation({
    mutationFn: (recordId: string) => fetchAttachment(recordId),
  });
  return {
    externalRecords,
    externalCount,
    externalRecords2,
    externalCount2,
    isLoadingV2,
    isErrorV2,
    refetchV2,
    isLoading,
    isError,
    refetch,
    fetchAttachments,
    attachmentsData,
    isAttachmentsError,
    ...(fetchParent
      ? {
          externalParent: dataParent?.items ?? [],
          externalParentCount: dataParent?.count ?? 0,
          isLoadingParent,
          refetchParent,
          isErrorParent,
        }
      : {}),
  };
};
