"use client";
import { UseFormSubmissionTypo } from "@/types";
import axios, { AxiosError } from "axios";

import { useMutation } from "@tanstack/react-query"
import { useTranslations } from "next-intl";

import { toast } from "./use-toast";
import { Ghost } from "lucide-react";
import { USER_TOKEN_CL } from "@/utils/data/user-client";
import { BASE_URL } from "@/utils/url";

export const useFormSubmission = ({
    endPoint,
    method,
    headers,
    context = "main",

    beforeSuccess,
    onSuccess,
    onError,
    onSettled,
    clearErrors,
    setError,

    errorFields,
    ...mutationOptions
}: UseFormSubmissionTypo) => {
    const t = useTranslations();
    const submitForm = async (body: any) => {
        const token = USER_TOKEN_CL();
        const urlToFetch = context === "special" ? endPoint : `${BASE_URL}${endPoint}`;

        clearErrors?.();
        const response = await axios({
            method,
            url: urlToFetch,
            data: body,
            headers: headers ?? (body instanceof FormData ? {
                'Authorization': `Bearer ${token}`,
                'Accept': 'application/json',
            } : {
                'Authorization': `Bearer ${token}`,
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            })
        });

        if (![200, 201,].includes(response.status)) {
            throw new Error(response.statusText);
        };

        return response.data;
    };

    const mutation = useMutation({
        ...mutationOptions,
        mutationKey: [`form-submission-${endPoint}`],
        mutationFn: submitForm,
        onSuccess: async (response) => {
            await beforeSuccess?.(response);
            await onSuccess?.(response);
        },
        onError: (error: AxiosError | any) => {
            const hasHandled = onError?.(error);

            if (hasHandled?.handled) {
                return;
            };

            const errorData = error?.response?.data;
            const fields = typeof errorFields === "function" ? errorFields() : errorFields;

            clearErrors?.();

            if (!Array.isArray(errorData?.data)) {
                toast({
                    title: `String | Error`,
                    description: `Returned data is not Array`,
                    variant: 'destructive'
                });
            }

            if (errorData?.status === 404 || Array.isArray(errorData?.data)) {
                fields?.forEach((field) => {
                    const err = errorData.data?.find((err: string) =>
                        err.toLowerCase().includes(field)
                    );

                    if (err && setError) {
                        setError(field, { type: 'server', message: err });
                    }
                });

                toast({
                    title: `${errorData.status} | Error`,
                    description: errorData.statusText || t('custom.failed message'),
                    variant: 'destructive'
                });
            } else if (errorData?.status === 403) {
                toast({
                    variant: "destructive",
                    title: (
                        <div className="flex items-center gap-4">
                            <Ghost size={25} />
                            <p className="text-xs">
                                403 | You don’t have permission to make this action.
                            </p>
                        </div>
                    ) as any,
                });

                setTimeout(() => window.location.reload(), 1100);
                return;
            } else {
                toast({
                    title: `${errorData?.status || error?.status || '401'} | Error`,
                    description: `${error}`,
                    variant: 'destructive'
                });
            }
        },
        onSettled: () => onSettled?.(),
    });

    return {
        ...mutation,
    }
}