import { AuthenticationError } from "@/src/entities/errors/auth";
import { useState } from "react";
import { useAuthActions } from "./mutation";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { defaultSignInPasswordlessValues, SignInFormData, SignInPasswordless, SignInPasswordlessSchema, SignInSchema } from "@/src/entities/models/auth/sign-in.model";
import { createFormData } from "@/app/_utils/common";
import { useFormHandler } from "@/app/_hooks/use-form-handler";
import { toast } from "sonner";
import { signIn } from "./action";
import { useNavigations } from "@/app/_hooks/use-navigations";
import { VerifyOtpFormData, verifyOtpSchema } from "@/src/entities/models/auth/verify-otp.model";

/**
 * Hook untuk menangani proses sign in
 * 
 * @returns {Object} Object berisi handler dan state untuk form sign in
 * @example
 * const { handleSubmit, isPending, error } = useSignInHandler();
 * <form onSubmit={handleSubmit}>...</form>
 */
export function useSignInHandler() {
    const { signIn } = useAuthActions();
    const { router } = useNavigations();

    const [error, setError] = useState<string>();

    const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
        event.preventDefault();
        if (signIn.isPending) return;

        setError(undefined);

        const formData = new FormData(event.currentTarget);
        const email = formData.get("email")?.toString()

        try {
            await signIn.mutateAsync(formData, {
                onSuccess: () => {
                    toast("An email has been sent to you. Please check your inbox.");
                    if (email) router.push(`/verify-otp?email=${encodeURIComponent(email)}`);
                },
                onError: (error) => {
                    setError(error.message);
                }
            });
        } catch (error) {
            if (error instanceof Error) {
                setError(error.message);
            }
        }
    };

    return {
        // formData,
        // handleChange,
        handleSubmit,
        error,
        isPending: signIn.isPending,
        errors: !!error || signIn.error,
        clearError: () => setError(undefined)
    };
}



export function useVerifyOtpHandler(email: string) {
    const { router } = useNavigations()
    const { verifyOtp } = useAuthActions()
    const [error, setError] = useState<string>()

    const {
        register,
        handleSubmit: hookFormSubmit,
        control,
        formState: { errors },
        setValue
    } = useForm<VerifyOtpFormData>({
        resolver: zodResolver(verifyOtpSchema),
        defaultValues: {
            email,
            token: ""
        }
    })

    const handleOtpChange = (value: string, onChange: (value: string) => void) => {
        onChange(value)

        // Clear error when user starts typing
        if (error) {
            setError(undefined)
        }
    }

    const handleSubmit = hookFormSubmit(async (data) => {
        if (verifyOtp.isPending) return

        setError(undefined)

        // Create FormData object
        const formData = new FormData()
        formData.append("email", data.email)
        formData.append("token", data.token)

        try {
            await verifyOtp.mutateAsync(formData, {
                onSuccess: () => {
                    toast.success("OTP verified successfully")
                    // Navigate to dashboard on success
                    router.push("/dashboard")
                },
                onError: (error) => {
                    setError(error.message)
                }
            })
        } catch (error) {
            if (error instanceof Error) {
                setError(error.message)
            }
        }
    })

    return {
        register,
        control,
        handleSubmit,
        handleOtpChange,
        errors: {
            ...errors,
            token: error ? { message: error } : errors.token
        },
        isPending: verifyOtp.isPending,
        clearError: () => setError(undefined)
    }
}

export function useSignOutHandler() {
    const { signOut } = useAuthActions()
    const { router } = useNavigations()
    const [error, setError] = useState<string>()

    const handleSignOut = async () => {
        if (signOut.isPending) return

        setError(undefined)

        try {
            await signOut.mutateAsync(undefined, {
                onSuccess: () => {
                    toast.success("You have been signed out successfully")
                    router.push("/sign-in")
                },
                onError: (error) => {
                    if (error instanceof AuthenticationError) {
                        setError(error.message)
                        toast.error(error.message)
                    }
                }
            })
        } catch (error) {
            if (error instanceof Error) {
                setError(error.message)
                toast.error(error.message)
                // toast.error("An error occurred during sign out. Please try again later.")
            }
        }
    }

    return {
        handleSignOut,
        error,
        isPending: signOut.isPending,
        errors: !!error || signOut.error,
        clearError: () => setError(undefined)
    }
}
