/* Copyright (C) Click & Push Accessibility, Inc - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 * Written and maintained by the Click & Push Development team 
 * <dev@clicknpush.ca>, January 2022
 */

import { useMutation, useQuery, useQueryClient } from "react-query";
import { RegisterCredsValues } from "../utils/RegistrationUtils";
import { API_URL } from "../utils/RequestUtils";
import { useAuth } from "./Auth/AuthContext";
import { queryKeys } from "./query-keys";

/**
 * Interface that contains data in a user's profile.
 */
export interface UserProfile {
    /**
     * The user's id
     */
    id?: string
    /**
     * The user's username
     */
    username?: string
    /**
     * The user's email
     */
    email?: string
    /**
     * The user's base64 encoded profile picture.
     */
    image_b64?: string
    /**
     * The user's preference for seeing tips.
     */
    show_tips?: boolean
}

/**
 * A custom hook containing [react-query]{@link https://react-query.tanstack.com/} queries and mutations and other logic related to interacting with {@link UserProfile} objects.
 * @category Hooks
 * @namespace useProfile
 */
export const useOwnedProfile = () => {
    const queryClient = useQueryClient();
    const {sendApiRequestAsync, accessToken, userId} = useAuth()

    const getOwnedProfile = async () => {
        const response = await sendApiRequestAsync({
            axiosConfig: {
                method: 'GET',
                url: `/api/user-profile/${userId}/`,
            }, 
            authorized: true,
            errorMessage: 'Something went wrong when retrieving user profile',
            loggingCategory: 'PROFILE',
        });   
        return response.data;
    }

    const {data: profile} = useQuery<UserProfile, Error>(queryKeys.getOwnedProfile, getOwnedProfile, {
        enabled: !!userId && !!accessToken
    })

    const changeProfile = async (profile: UserProfile) => {
        queryClient.setQueriesData(queryKeys.getOwnedProfile, profile)
    }

    const clearProfile = async () => {
        queryClient.setQueryData(queryKeys.getOwnedProfile, null);
        queryClient.removeQueries();
    }

 return {profile, changeProfile, clearProfile}
}

export const useEditProfile = () => {
    const queryClient = useQueryClient();
    const {sendApiRequestAsync, userId} = useAuth()

     const editProfile = async (values: RegisterCredsValues) => {
        const response = await sendApiRequestAsync({
            axiosConfig: {
                method: 'PUT',
                url: API_URL + `/api/user-profile/${userId}/`,
                data: values,
            },
            authorized: true,
            errorMessage: 'Something went wrong when editing profile',
            loggingCategory: 'PROFILE',
        });   
        return response.data;
    }
    return useMutation(editProfile, {
        onSuccess: () => { queryClient.invalidateQueries(queryKeys.getOwnedProfile)},  
        onError: () => queryClient.invalidateQueries(queryKeys.getOwnedProfile),  
    })
}

export const useChangePassword = () => {
    const queryClient = useQueryClient();
    const {sendApiRequestAsync, userId} = useAuth()
    const changePassword = async (password: string) => {
        if (password && userId) { 
            const response = await sendApiRequestAsync({
                axiosConfig: {
                    method: 'POST',
                    url: `/api/user-profile/change-password/${userId}/`,
                    data: {password: password},
                }, 
                authorized: true,
                errorMessage: 'Something went wrong when changing password',
                loggingCategory: 'PROFILE',
            });   
            return response.data;
        }
    }

    return useMutation(changePassword, {
        onSuccess: () => { queryClient.invalidateQueries(queryKeys.getOwnedProfile)},  
        onError: () => queryClient.invalidateQueries(queryKeys.getOwnedProfile),  
    })
}

export const useDeleteProfile = () => {
    const {clearProfile} = useOwnedProfile()
    const {clearAuthStorage} = useAuth()
    const queryClient = useQueryClient();
    const {sendApiRequestAsync, userId} = useAuth()

    const deleteProfile = async () => {
        if (userId) { 
            const response = await sendApiRequestAsync({
                axiosConfig: {
                    method: 'DELETE',
                    url: API_URL + `/api/user-profile/${userId}/`,
                },
                authorized: true,
                errorMessage: 'Something went wrong when deleting profile',
                loggingCategory: 'PROFILE',
            });   
            
            if (response.status == 200) {
                await clearProfile()
                await clearAuthStorage()
            }
        }
    }

    return useMutation(deleteProfile, {
        onSuccess: () => { queryClient.invalidateQueries(queryKeys.getOwnedProfile)},  
        onError: () => queryClient.invalidateQueries(queryKeys.getOwnedProfile),  
    })
}
    //*NOT CURRENTLY IN USER*
    // const changePicture = async () => {
    //     if (userId) {
    //         const config: AxiosRequestConfig = {
    //             method: 'POST',
    //             url: API_URL + `/api/user-profile/change-picture/${userId}/`,
    //             headers: { "Authorization": "Bearer " + accessToken, }
    //         }   
    //         try {
    //             const response = await axios(config);   
    //             return response.data;
    //         } catch (error) {
    //             if (error.response.status == 401) {
    //                 try {
    //                     await refreshAccessToken()    
    //                     const response = await axios({...config, headers: { "Authorization": "Bearer " + accessToken }});   
    //                     return response.data;
    //                 } catch (error) {
    //                     // refreshAccessToken will report errors
    //                 }
    //             }
    //         }
    //     }
    // }

    
export const useToggleTips = () => {
    const {sendApiRequestAsync, userId} = useAuth()
    const queryClient = useQueryClient();

    const toggleTips = async () => {
        if (userId) { 
            const response = await sendApiRequestAsync({
                axiosConfig: {
                    method: 'POST',
                    url: `/api/user-profile/toggle-tips/${userId}/`,
                },
                authorized: true,
                errorMessage: 'Something went wrong when toggling tips',
                loggingCategory: 'PROFILE',
            });   
            return response.data;
        }
    }

    return useMutation(toggleTips, {
        onSuccess: () => { queryClient.invalidateQueries(queryKeys.getOwnedProfile)},  
        onError: () => queryClient.invalidateQueries(queryKeys.getOwnedProfile),  
    })
}