"use client";
import axios, { AxiosRequestConfig } from "axios";
import { useState } from "react";
import Cookies from "js-cookie";
import { useLocale, useTranslations } from "next-intl";
import ShowAlertMixin from "@/shared/ShowAlertMixin";
import { deleteCredentials } from "@/store/auth.slice";
import { AppDispatch } from "@/store/store";
import { useDispatch } from "react-redux";

type UseMutateProps<ResponseType> = {
  endpoint: string | ((id: string) => string); // Updated this line
  method?: "POST" | "DELETE" | "PUT" | "PATCH";
  onSuccess?: (data: ResponseType) => void;
  onError?: (error: unknown) => void;
  formData?: boolean;
  customHeaders?: Record<string, string>;
};

export function UseMutate<ResponseType>({
  endpoint,
  method = "POST",
  onSuccess,
  onError,
  formData,
  customHeaders,
}: UseMutateProps<ResponseType>) {
  const t = useTranslations();
  const dispatch = useDispatch<AppDispatch>();

  const [isLoading, setIsLoading] = useState(false);
  const [data, setData] = useState<ResponseType | null>(null);
  const [error, setError] = useState<unknown | null>(null);

  const userToken = Cookies.get("token");
  const token = userToken;
  const authorizationHeader = token ? `Bearer ${token}` : undefined;
  const locale = useLocale();

  const BaseUrl = process.env.NEXT_PUBLIC_BASE_URL;

  const mutate = async (values: any, actions?: { onSuccess: () => void }) => {
    setIsLoading(true);

    const url = new URL(
      `${BaseUrl}${
        typeof endpoint === "function" ? endpoint(values) : endpoint
      }`,
    );

    const headers: Record<string, string> = {
      "Accept-Language": locale,
      ...(customHeaders || {}),
      ...(authorizationHeader ? { Authorization: authorizationHeader } : {}),
    };

    if (!formData) {
      headers["Content-Type"] = "application/json; charset=utf-8";
    }

    const axiosConfig: AxiosRequestConfig = {
      method,
      url: url.toString(),
      headers,
      data: formData ? values : (values ?? {}),
    };

    // Return the Promise chain
    return await axios(axiosConfig)
      .then((res) => {
        const responseData = res.data as ResponseType;
        setData(responseData);

        if (onSuccess) {
          onSuccess(responseData);
          actions?.onSuccess?.();
        } else {
          ShowAlertMixin({
            icon: "success",
            title: (res.data as any)?.message,
          });
        }
      })
      .catch((err: any) => {
        setError(err);
        const errorMessage = err?.response?.data?.message;
        if (err?.response?.status === 401) {
          dispatch(deleteCredentials());
          setTimeout(() => {
            window.location.replace(
              `${locale == "ar" ? "" : "/en"}/auth/login`,
            );
          }, 500);
        }
        if (onError) {
          onError(err?.response?.data);
        } else {
          ShowAlertMixin({
            icon: "error",
            title: errorMessage,
          });
        }
      })
      .finally(() => {
        setIsLoading(false);
      });
  };

  return { isLoading, data, error, mutate };
}
