import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import { useEffect, useRef } from "react";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";
import {
  sendToRO,
  submitRecord,
  sendBack,
  goToNext,
  submitAndSendToRo,
  fetchApprovalTasks,
  ApprovalRecordQueryParams,
  makeUnderReview,
  fetchMyRecordsApprovals,
  fetchMyProcessedRecordsApprovals,
} from "@/record-management/services/api/approvalService";

export const useApprovalTasks = (queryParams?: ApprovalRecordQueryParams) => {
  // Explicitly type your options object using UseQueryOptions
  const queryClient = useQueryClient();
  const { t } = useTranslation();
  const { handleError } = useErrorHandler(t);

  const { data, isLoading, isError, error, refetch } = useQuery({
    queryKey: ["approvalRecord", queryParams],
    queryFn: ({ queryKey }) => {
      const [_key, params] = queryKey as [string, ApprovalRecordQueryParams];
      return fetchApprovalTasks(params);
    },
    staleTime: 0,
    placeholderData: { count: 0, items: [] },
  });

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

  const approveRecordMutation = useMutation({
    mutationFn: async ({
      taskId,
      stampId,
      signatureId,
      note,
    }: {
      taskId: string;
      stampId: string;
      signatureId: string;
      note: string;
    }) => {
      return await sendToRO(taskId, stampId, signatureId, note);
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const submitRecordMutation = useMutation({
    mutationFn: async ({
      id,
      delegatorId,
    }: {
      id: string;
      delegatorId?: string;
    }) => {
      return await submitRecord(id, delegatorId);
    },
    onSuccess: () => {
      // Toast is owned by the calling component (e.g. forwardRecord.tsx
      // shows "Record forwarded successfully"). Avoid double-toast here.
      queryClient.invalidateQueries({ queryKey: ["approvalRecord"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });
  const MakeRecordUnerReviewMutation = useMutation({
    mutationFn: async ({ id }: { id: string }) => {
      return await makeUnderReview(id);
    },
    onSuccess: () => {
      // Toast owned by calling component (UnderReviewRecord.tsx).
      queryClient.invalidateQueries({ queryKey: ["reviewRecord"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const acceptRecordMutation = useMutation({
    mutationFn: async (body: any) => {
      return await goToNext(body);
    },
    onSuccess: () => {
      // Toast owned by calling component (AcceptRecord.tsx).
      queryClient.invalidateQueries({ queryKey: ["approvalRecord"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const rejectRecordMutation = useMutation({
    mutationFn: async (body: any) => {
      return await sendBack(body);
    },
    onSuccess: () => {
      // Toast owned by calling component (rejectRecord.tsx).
      queryClient.invalidateQueries({ queryKey: ["approvalRecord"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });
  const adjustRecordMutation = useMutation({
    mutationFn: async (body: any) => {
      return await sendBack(body);
    },
    onSuccess: () => {
      // Toast owned by calling component (AdjustRecord.tsx).
      queryClient.invalidateQueries({ queryKey: ["approvalRecord"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const sendToRoMutation = useMutation({
    mutationFn: async ({
      id,
      stampId,
      signatureId,
      note,
      recordPrefixId,
      isWithTeamSignature,
    }: {
      id: string;
      stampId?: string;
      signatureId?: string;
      note?: string;
      recordPrefixId?: string;
      isWithTeamSignature?: boolean;
    }) => {
      return await sendToRO(
        id,
        stampId,
        signatureId,
        note,
        recordPrefixId,
        isWithTeamSignature,
      );
    },
    onSuccess: () => {
      // Toast owned by calling component (approveRecordPage.tsx).
      queryClient.invalidateQueries({ queryKey: ["approvalRecord"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const submitAndSendToRoMutation = useMutation({
    mutationFn: async ({
      id,
      stampId,
      signatureId,
      note,
      recordPrefixId,
    }: {
      id: string;
      stampId?: string;
      signatureId?: string;
      note?: string;
      recordPrefixId?: string;
    }) => {
      return await submitAndSendToRo(
        id,
        stampId,
        signatureId,
        note,
        recordPrefixId,
      );
    },
    onSuccess: () => {
      // Toast owned by calling component (approveRecord.tsx).
      queryClient.invalidateQueries({ queryKey: ["approvalRecord"] });
    },
    onError: (error) => {
      handleError(error);
    },
  });

  const approvalCount = data?.count || 0;

  return {
    approvalCount,
    approvalRecords: data?.items || [],

    approveRecord: approveRecordMutation.mutateAsync,
    approveRecordLoading: approveRecordMutation.isPending,
    acceptRecord: acceptRecordMutation.mutateAsync,
    acceptRecordLoading: acceptRecordMutation.isPending,
    adjustRecord: adjustRecordMutation.mutateAsync,
    adjustRecordLoading: adjustRecordMutation.isPending,

    isLoading,
    isError,
    refetch,
    submitRecord: submitRecordMutation.mutateAsync,
    submitRecordLoading: submitRecordMutation.isPending,
    sendToRo: sendToRoMutation.mutateAsync,
    sendToRoLoading: sendToRoMutation.isPending,
    submitAndSend: submitAndSendToRoMutation.mutateAsync,
    isSubmitAndSendLoading: submitAndSendToRoMutation.isPending,
    rejectRecord: rejectRecordMutation.mutateAsync,
    makeRecordUnderReview: MakeRecordUnerReviewMutation.mutateAsync,
  };
};

export const useMyApprovals = (params?: ApprovalRecordQueryParams) => {
  return useQuery({
    queryKey: ["myRecordApprovals", params],
    queryFn: () => fetchMyRecordsApprovals(params),
    staleTime: 1000 * 60 * 5,
  });
};
export const useMyProcessedApprovals = (params?: ApprovalRecordQueryParams) => {
  return useQuery({
    queryKey: ["myProcessedApprovals", params],
    queryFn: () => fetchMyProcessedRecordsApprovals(params),
    staleTime: 1000 * 60 * 5,
  });
};
