import useSWR, { mutate } from "swr";
import axiosInstance, { fetcher } from "./server";
import { IChatConversationClient, IChatMessage, IChatMessageClient, MessageType } from "../types/chat";
import axios from "axios";
import { useMemo } from "react";
import { useMockedUser } from "@/hooks";
import uuidv4 from "@/utils/uuidv4";


export async function editMessage(updatedMessage: IChatMessage) {
    // const { data, error, mutate } = useSWR(`http://localhost:4000/message/update`, fetcher);
    // return {
    //     messages: data,
    //     isLoading: !error && !data,
    //     isError: error,
    //     mutate
    // };
    const upp = {
        destinationUuid: updatedMessage.destinationUuid,
        type: updatedMessage.type,
        body: updatedMessage.body,
        uuid: updatedMessage.uuid,
        owner: updatedMessage.owner,
        update: true,
    };
    console.log('msg : ' + upp.body)
    const URL = 'http://localhost:4000/conversation/71dd740b-bea8-4ff3-a292-349f03915d3f';
    try {
        await axiosInstance.post('http://localhost:4000/message/update', upp);
        // Mettre à jour le cache SWR après modification
        mutate(URL);
    } catch (error) {
        console.error("Failed to edit message", error);
    }
    // mutate(URL)
};
export const reactToMessage = async (messageUuid: string, clientUuid: string, emoji: string, selectedConversationId: string) => {

    try {
        const response = await axiosInstance.post('http://localhost:4000/message/reactTomsg', {
            message: { uuid: messageUuid },
            reactor: { uuid: clientUuid },
            emoji: emoji,
        });

        if (response.status !== 200) {
            throw new Error('Failed to react message');

        } else {
            console.log("reaction data : ", response.data);
            mutate(
                `http://localhost:4000/conversation/${selectedConversationId}`,
                (conversation: any) => {
                    if (conversation && conversation.messages) {
                        const reactedMessages = conversation.messages.map((msg: any) => {
                            if (msg.uuid === messageUuid) {
                                return {
                                    ...msg,
                                    reactions: response.data.reactions,
                                };
                            }
                            return msg;
                        });
                        console.log(conversation)
                        return {
                            ...conversation,
                            messages: reactedMessages,
                        };
                    }

                    return conversation;
                }, false);
            return response.data;
        }
    } catch (error) {
        console.error('Error reacting message:', error);
        throw error;
    }

};

// export const pinMessage = async (messageUuid: string) => {
//     try {
//         const response = await axios.post(`http://localhost:4000/message/pin`, { uuid: messageUuid });
//         return response.data;
//     } catch (error) {
//         console.error('Failed to pin/unpin message:', error);
//         throw error;
//     }
// };

export const pinMessage = async (messageUuid: string) => {
    const response = await axiosInstance.post('http://localhost:4000/message/pin', {
        uuid: messageUuid
    });
    if (response.status !== 200) {
        throw new Error('Failed to pin/unpin message');
    } else {
        console.log('pined message with uuid ' + messageUuid)
    }
    return response.data;
};


export const deleteMessage = async (messageUuid: string, selectedConversationId: string) => {
    try {
        const response = await axiosInstance.delete(`http://localhost:4000/message/delete/${messageUuid}`);

        if (response.status !== 200) {
            throw new Error('Failed to delete message');

        } else {

            confirm('deleted');

            // Mise à jour locale sans faire un nouvel appel au backend
            mutate(
                `http://localhost:4000/conversation/${selectedConversationId}`,
                (conversation: any) => {
                    if (conversation && conversation.messages) {
                        return {
                            ...conversation,
                            messages: conversation.messages.filter((msg: any) => msg.uuid !== messageUuid),
                        };
                    }
                    return conversation;
                },
                false // Ne pas revalider avec le backend
            );
        }
        return response.data;
    } catch (error) {
        console.error('Error deleting message:', error);
        throw error;
    }
};

export async function useGetPinnedMessages(conversationUuid: string) {

    const URL = `http://localhost:4000/message/delete/${conversationUuid}`;

    const { data, isLoading, error, isValidating } = useSWR(URL, fetcher);

    const memoizedValue = useMemo(
        () => ({
            pinnedMessages: (data as IChatMessage[]) || [],
            // contactsLoading: isLoading,
            // contactsError: error,
            // contactsValidating: isValidating,
            // contactsEmpty: !isLoading && !data?.contacts?.length,
        }),
        [data?.pinnedMessages, error, isLoading, isValidating]
    );

    return memoizedValue;
}


export async function createConversation(ownerUuid: string, recipientUuid: string, messageData: MessageType, userId: number | string) {

    // const { user1 } = useMockedUser();
    const URL = `http://localhost:4000/conversation/create`;

    /**
     * Work on server
     */
    const data = {
        owner: { uuid: ownerUuid },
        recipient: { uuid: recipientUuid },
        message: {
            sourceUuid: messageData.sourceUuid,
            destinationUuid: messageData.destinationUuid,
            type: "TEXT",
            destinationType: "",
            body: messageData.body,
            uuid: uuidv4()
        }
    };
    // const res = await axios.post(URL, data);

    /**
     * Work in local
     */
    try {
        const res = await axios.post(URL, data);

        // Clé de cache pour SWR : Utilisez l'URL avec l'ID du client
        const cacheKey = `http://localhost:4000/conversations/${userId}`;

        // Mise à jour du cache SWR
        mutate(
            cacheKey
            // (currentData: any) => {
            //     // Assurez-vous que `currentData` et `currentData.conversations` sont définis
            //     const existingConversations = Array.isArray(currentData?.conversations) ? currentData.conversations : [];
            //     const conversations = [...existingConversations, res.data];

            //     return {
            //         ...currentData,
            //         conversations,
            //     };
            // },
            // false
        );

        return res.data;
    } catch (error) {
        console.error('Error creating conversation:', error);
        throw error;
    }
}

export async function sendMessagee(conversationId: string, messageData: any) {

    const { user1 } = useMockedUser();

    const CONVERSATIONS_URL = `http://localhost:4000/conversations/${user1.id}`;

    const CONVERSATION_URL = `http://localhost:4000/conversation/${conversationId}`

    /**
     * Work on server
     */
    // const data = { conversationId, messageData };
    // await axios.put(endpoints.chat, data);

    /**
     * Work in local
     */
    mutate(
        CONVERSATION_URL,
        (currentData: any) => {
            const { conversation: currentConversation } = currentData || {};
            const updatedConversation = {
                ...currentConversation,
                messages: [...(currentConversation?.messages || []), messageData],
            };
            return { conversation: updatedConversation };
        },
        false
    );
    // mutate(
    //     `http://localhost:4000/conversation/${selectedConversationId}`,
    //     (conversation: any) => ({
    //       ...conversation,
    //       messages: [...(conversation?.messages || []), newMessage],
    //     }),
    //     false
    //   );
    /**
     * Work in local
     */
    // mutate(
    //     CONVERSATIONS_URL,
    //     (currentData: any) => {
    //         const { conversations: currentConversations } = currentData;

    //         const conversations: IChatConversationClient[] = currentConversations.map(
    //             (conversation: IChatConversationClient) =>
    //                 conversation.uuid === conversationId
    //                     ? {
    //                         ...conversation,
    //                         messages: [...conversation.messages, messageData],
    //                     }
    //                     : conversation
    //         );

    //         return {
    //             conversations,
    //         };
    //     },
    //     false
    // );
}

export async function mutateConversation(conversationId: string, newMessage: any) {
    console.log("new message :", newMessage)
    mutate(
        `http://localhost:4000/conversation/${conversationId}`,
        (conversation: any) => ({
            ...conversation,
            messages: [...(conversation?.messages || []), newMessage],
        }),
        false
    );
}

export async function mutateConversationInUpdate(conversationId: string, updatedMessage: IChatMessage) {

    mutate(
        `http://localhost:4000/conversation/${conversationId}`,
        (conversation: any) => {
            if (conversation && conversation.messages) {
                const updatedMessages = conversation.messages.map((msg: any) => {
                    if (msg.uuid === updatedMessage.uuid) {
                        return {
                            ...msg,
                            body: updatedMessage.body,
                        };
                    }
                    return msg;
                });

                return {
                    ...conversation,
                    messages: updatedMessages,
                };
            }
            console.log(conversation)
            return conversation;
        }, false); // false pour ne pas revalider avec le backend
}
export async function mutateConversationInreact(conversationId: string, reactedMessage: any) {

    mutate(
        `http://localhost:4000/conversation/${conversationId}`,
        (conversation: any) => {
            if (conversation && conversation.messages) {
                const reactedMessages = conversation.messages.map((msg: any) => {
                    if (msg.uuid === reactedMessage.uuid) {
                        return {
                            ...msg,
                            reactions: reactedMessage.reactions,
                        };
                    }
                    return msg;
                });
                console.log(conversation)
                return {
                    ...conversation,
                    messages: reactedMessages,
                };
            }

            return conversation;
        }, false); // false pour ne pas revalider avec le backend
}


/* export async function mutateConversations(userId: string | number, conversationId: any, newMessage: any) {
console.log("conversation id "+ conversationId)
    mutate(
        `http://localhost:4000/conversations/${userId}`,
        (currentData: any) => {
            if (!Array.isArray(currentData)) {
                console.error('Expected currentData to be an array of conversations.');
                return currentData;
            }
            const updatedConversations = currentData.map((conversation: any) =>
                conversation.uuid === conversationId
                    ? {
                        ...conversation,
                        messages: [...(conversation.messages || []), newMessage],
                    }
                    : conversation
            );

            return updatedConversations;
        },
        false
);
} */


export async function mutateConversations(userId: string | number, conversationId: any, newMessage: any) {
    mutate(
        `http://localhost:4000/conversations/${userId}`,
        (currentData: any) => {
            // If currentData is undefined or null, initialize it as an empty array
            if (!Array.isArray(currentData)) {
                console.error('Expected currentData to be an array of conversations, initializing with an empty array.');
                currentData = [];
            }

            // Check if the conversation already exists in the current data
            const existingConversation = currentData.find((conversation: any) => conversation.uuid === conversationId);

            if (existingConversation) {
                // Update the existing conversation with the new message
                const updatedConversations = currentData.map((conversation: any) =>
                    conversation.uuid === conversationId
                        ? {
                            ...conversation,
                            messages: [...(conversation.messages || []), newMessage],
                        }
                        : conversation
                );

                return updatedConversations;
            } else {
                // If the conversation doesn't exist, fetch the full conversation and add it to the list
                return fetcher(`http://localhost:4000/conversation/${conversationId}`).then((newConversation) => {
                    return [...currentData, { ...newConversation, messages: [newMessage] }];
                });
            }
        },
        false
    );
}


export async function getOrCreateConversation(ownerUuid: string, recipientUuid: string, userId: number | string) {
    const URL = `http://localhost:4000/conversation/by-participants`;
  
    try {
      // Step 1: Check if a conversation exists
      const response = await axios.post(URL, {
        participant1Uuid: ownerUuid,
        participant2Uuid: recipientUuid,
      });
      const cacheKey = `http://localhost:4000/conversations/${userId}`;

      // Mise à jour du cache SWR
      mutate(
          cacheKey
    
      );
      return response.data.conversationId;
    } catch (error) {
      console.error('Error fetching or creating conversation:', error);
      throw error;
    }
  }
  
