import { useCallback, useState } from 'react';

import { fetchLogin } from '@/services/login';

export interface UseActionParams {
    setToken: (data: API.UserInfo) => void;
    setUserConfig: (data: API.UserInfo | null) => void;
    onSuccess?: () => void;
}

export type LoginErrorKey = 'loginError' | null;

function getErrorMessage(err: unknown): { message: string | null; errorKey: LoginErrorKey } {
    const anyErr = err as {
        name?: string;
        info?: { errorMessage?: string };
        response?: { data?: { errorMessage?: string } };
    };
    const backendMsg = anyErr?.info?.errorMessage ?? anyErr?.response?.data?.errorMessage ?? null;
    if (backendMsg && typeof backendMsg === 'string') {
        return { message: backendMsg, errorKey: null };
    }
    return { message: null, errorKey: 'loginError' };
}

export function useAction({ setToken, setUserConfig, onSuccess }: UseActionParams) {
    const [loading, setLoading] = useState(false);
    const [errorMessage, setErrorMessage] = useState<string | null>(null);
    const [errorKey, setErrorKey] = useState<LoginErrorKey>(null);

    const handleSubmit = useCallback(
        (username: string, password: string) => {
            setErrorMessage(null);
            setErrorKey(null);
            setLoading(true);
            fetchLogin({ account: username.trim(), password }, { skipErrorHandler: true })
                .then((res) => {
                    const data = res?.data;
                    if (!data || !data.userConfig) return;
                    setToken(data.userConfig);
                    setUserConfig(data.userConfig);
                    onSuccess?.();
                })
                .catch((err) => {
                    const { message: msg, errorKey: key } = getErrorMessage(err);
                    setErrorMessage(msg);
                    setErrorKey(key);
                })
                .finally(() => {
                    setLoading(false);
                });
        },
        [setToken, setUserConfig, onSuccess]
    );

    return {
        loading,
        errorMessage,
        errorKey,
        handleSubmit,
    };
}
