import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import ExpenseRepository from "../repositories/ExpsenseRepository";
import showToast from "../services/toastService";
import { queryClient } from "../layouts/AuthLayout";
import { useSelector } from "react-redux";
import moment from "moment";

// -------------------Query------------------------------------------------------

const cleanFilter = (filter) => {
  const cleaned = { ...filter };

  ["projectIds", "statusIds", "createdByIds", "paidById"].forEach((key) => {
    if (Array.isArray(cleaned[key]) && cleaned[key].length === 0) {
      delete cleaned[key];
    }
  });

  // moment.utc() to get consistent UTC ISO strings
  if (!cleaned.startDate) {
    cleaned.startDate = moment.utc().subtract(7, "days").startOf("day").toISOString();
  }

  if (!cleaned.endDate) {
    cleaned.endDate = moment.utc().startOf("day").toISOString();
  }

  return cleaned;
};


export const useExpenseList = (
  pageSize,
  pageNumber,
  filter,
  searchString = ""
) => {
  return useQuery({
    queryKey: ["Expenses", pageNumber, pageSize, filter, searchString],
    queryFn: async () => {
      const cleanedFilter = cleanFilter(filter);
      const response = await ExpenseRepository.GetExpenseList(
        pageSize,
        pageNumber,
        cleanedFilter,
        searchString
      );
      return response.data;
    },
    keepPreviousData: true,
  });
};

export const useExpense = (ExpenseId) => {
  return useQuery({
    queryKey: ["Expense", ExpenseId],
    queryFn: async () =>
      await ExpenseRepository.GetExpenseDetails(ExpenseId).then(
        (res) => res.data
      ),
    enabled: !!ExpenseId,
  });
};

export const useExpenseFilter = () => {
  return useQuery({
    queryKey: ["ExpenseFilter"],
    queryFn: async () =>
      await ExpenseRepository.GetExpenseFilter().then((res) => res.data),
  });
};

// ---------------------------Mutation---------------------------------------------

export const useCreateExpnse = (onSuccessCallBack) => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async (payload) => {
      await ExpenseRepository.CreateExpense(payload);
    },
    onSuccess: (_, variables) => {
      queryClient.invalidateQueries({ queryKey: ["Expenses"] });
      showToast("Expense Created Successfully", "success");
      if (onSuccessCallBack) onSuccessCallBack();
    },
    onError: (error) => {
      showToast(
        error.message || "Something went wrong please try again !",
        "error"
      );
    },
  });
};

export const useUpdateExpense = (onSuccessCallBack) => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: async ({ id, payload }) => {
      const response = await ExpenseRepository.UpdateExpense(id, payload);
      return response.data;
    },
    onSuccess: (updatedExpense, variables) => {
      // queryClient.setQueriesData(
      //   {queryKey:['expenses'],exact:true},
      //   (oldData) => {
      //     if (!oldData || !oldData.data) return oldData;

      //     const updatedList = oldData.data.map((expense) => {
      //       if (expense.id !== variables.id) return expense;

      //       return {
      //         ...expense,
      //         project:
      //           expense.project.id !== updatedExpense.project.id
      //             ? updatedExpense.project
      //             : expense.project,
      //         expensesType:
      //           expense.expensesType.id !== updatedExpense.expensesType.id
      //             ? updatedExpense.expensesType
      //             : expense.expensesType,
      //         paymentMode:
      //           expense.paymentMode.id !== updatedExpense.paymentMode.id
      //             ? updatedExpense.paymentMode
      //             : expense.paymentMode,
      //         paidBy:
      //           expense.paidBy.id !== updatedExpense.paidBy.id
      //             ? updatedExpense.paidBy
      //             : expense.paidBy,
      //         createdBy:
      //           expense.createdBy.id !== updatedExpense.createdBy.id
      //             ? updatedExpense.createdBy
      //             : expense.createdBy,
      //         createdAt: updatedExpense.createdAt,
      //         status: updatedExpense.status,
      //         nextStatus: updatedExpense.nextStatus,
      //         preApproved: updatedExpense.preApproved,
      //         transactionDate: updatedExpense.transactionDate,
      //         amount: updatedExpense.amount,
      //       };
      //     });

      //     return {
      //       ...oldData,
      //       data: updatedList,
      //     };
      //   }
      // );
      queryClient.removeQueries({ queryKey: ["Expense", variables.id] });
      queryClient.invalidateQueries({ queryKey: ["Expenses"] });
      showToast("Expense updated Successfully", "success");

      if (onSuccessCallBack) onSuccessCallBack();
    },
    onError: (error) => {
      showToast("Something went wrong.Please try again later.", "error");
    },
  });
};

export const useActionOnExpense = (onSuccessCallBack) => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (payload) => {
      const response = await ExpenseRepository.ActionOnExpense(payload);
      return response.data;
    },
    onSuccess: (updatedExpense, variables) => {
      showToast("Request processed successfully.", "success");

      // queryClient.setQueriesData(
      //   {
      //     queryKey: ["Expenses"],
      //     exact: false,
      //   },
      //   (oldData) => {
      //     if (!oldData) return oldData;
      //     return {
      //       ...oldData,
      //       data: oldData.data.map((item) =>
      //         item.id === updatedExpense.id
      //           ? {
      //               ...item,
      //               nextStatus: updatedExpense.nextStatus,
      //               status: updatedExpense.status,
      //             }
      //           : item
      //       ),
      //     };
      //   }
      // );
      // queryClient.setQueriesData(
      //   { queryKey: ["Expense", updatedExpense.id] },
      //   (oldData) => {
      //     return {
      //       ...oldData,
      //       nextStatus: updatedExpense.nextStatus,
      //       status: updatedExpense.status,
      //     };
      //   }
      // );
      queryClient.invalidateQueries({queryKey:["Expense",updatedExpense.id]})
      queryClient.invalidateQueries({queryKey:["Expenses"]})

      if (onSuccessCallBack) onSuccessCallBack();
    },
    onError: (error) => {
      showToast(
        error.response.data.message ||
          "Something went wrong.Please try again later.",
        "error"
      );
    },
  });
};

export const useDeleteExpense = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({ id }) => {
      const response = await ExpenseRepository.DeleteExpense(id);
      return response.data;
    },
    onSuccess: (data, variables) => {
      queryClient.setQueryData(["Expenses"], (oldData) => {
        if (!oldData || !oldData.data)
          return queryClient.invalidateQueries({ queryKey: ["Expenses"] });

        const updatedList = oldData.data.filter(
          (expense) => expense.id !== variables.id
        );

        return {
          ...oldData,
          data: updatedList,
        };
      });

      showToast(data.message || "Expense deleted successfully", "success");
    },
    onError: (error) => {
      showToast(
        error.message ||
          error.response.message ||
          "Something went wrong.Please try again later.",
        "error"
      );
    },
  });
};

export const useHasAnyPermission = (permissionIdsInput) => {
  const permissions = useSelector((state) => state?.profile?.permissions || []);

  const permissionIds = Array.isArray(permissionIdsInput)
    ? permissionIdsInput
    : [];

  // No permission needed
  if (permissionIds.length === 0) return true;

  return permissionIds.some((id) => permissions.includes(id));
};
