/* 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 axios, { AxiosRequestConfig } from "axios";
import { QueryClient, useMutation, useQuery, useQueryClient } from "react-query";
import { useAuth } from "./Auth/AuthContext";
import { API_URL, reportAxiosError } from "../utils/RequestUtils";
import { queryKeys } from "./query-keys";

/**
 * Interface representing a landmark's comment.
 */
export interface LMComment {
    /**
     * The comment's id.
     */
    id: string,
    /**
     * The id of the user who posted the comment
     */
    poster: string,
    /**
     * The username of the user who posted the comment
     */
     poster_name: string,
    /**
     * The text content of the comment
     */
    content: string
    /**
     * The landmark id that this comment is associated with.
     */
    landmark: string
    /**
     * Timestamp of when the comment was posted.
     */
     timestamp?: Date
    /**
     * Whether or not the comment has been edited.
     */
     edited: boolean
}

/**
 * A custom hook containing [react-query]{@link https://react-query.tanstack.com/} queries and mutations and other logic related to interacting with {@link comment} objects.
 * @category Hooks
 * @namespace useComments
 * @param landmarkId - The id of the current landmark focused by the user. Used to fetch only the comments relevant to that landmark.
 */

export const useLandmarkComments = (landmarkId: string) => {
    const {sendApiRequestAsync} = useAuth()
    const queryClient = useQueryClient()

    const getCommentsForLandmark = async (landmarkId: string) => {
        if (landmarkId) { 
    
                const response = await sendApiRequestAsync({
                    axiosConfig: {
                        method: 'GET',
                        url: `${API_URL}/api/comments/${landmarkId}`
                    },
                    authorized: false,
                    errorMessage: 'Something went wrong when retrieving comments'
                });
                return response?.data?.reverse();
        }
    }

    return useQuery<LMComment[], Error>([queryKeys.getComments, landmarkId], async () => getCommentsForLandmark(landmarkId), {
        placeholderData: () => queryClient.getQueryData(queryKeys.getComments),
        staleTime: 1000,
        refetchInterval: 30000,
        refetchOnReconnect: true,
        refetchOnMount: false
    })
}

export const useAddComment = () => {
    const {sendApiRequestAsync} = useAuth()
    const queryClient = useQueryClient()

    const createComment = async (commentValue: LMComment) => {
        if (commentValue) {
            const response = await sendApiRequestAsync({
                axiosConfig: {
                    method: 'POST',
                    data: commentValue,
                    url: `/api/comments/`,
                },
                authorized: true,
                errorMessage: 'Something went wrong when creating a comment'
            })
            response?.data
        }
    }

    return useMutation(createComment, {
        onSuccess: data => {
            queryClient.invalidateQueries(queryKeys.getComments)
        },  
    })
}

export const useEditComment = () => {
    const {sendApiRequestAsync} = useAuth()
    const queryClient = useQueryClient()

    const editComment =  async (commentValue: LMComment) => {
        if (commentValue) { 
            const response = await sendApiRequestAsync({
                axiosConfig: {
                    method: 'PUT',
                    data: {...commentValue, edited: true},
                    url: `/api/comments/`,
                },
                authorized: true,
                errorMessage: 'Something went wrong when editing a comment'
            })
            return response?.data;
        }
    }

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

export const useDeleteComment = () => {
    const {sendApiRequestAsync} = useAuth()
    const queryClient = useQueryClient()

    const removeComment =  async (id?: string | null) => {
        if (id) {
            const response = await sendApiRequestAsync({
                axiosConfig: {
                    method: 'DELETE',
                    url: API_URL + `/api/comments/${id}`,
                },
                authorized: true,
                errorMessage: 'Something went wrong when deleting a comment'
            });   
            return response?.data;
        }
    }

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