import { actionPromise } from "./actionsPromise";
import { gql } from "../helpers/gql";
import { actionUploadFiles } from "./actionsMedia";
import { history } from "../App";
import { actionSetDropMedia, actionSetMessageEditor } from "../reducers/chatReducer";
import { addUploadDate } from "../components/utils/addUploadDate";
import { actionOpenModal } from "../reducers/modalReducer";
import { actionGetOneChat } from "./actionsForChats";

export const actionAddMessages = (data, id) => ({type: 'MSG', data, id});
const actionAddMessage = (message, id) => ({type: 'MSG', data: [message], id});

const actionGetOneMessage = (_id) => 
	actionPromise('oneMessage', gql(`query getOneMes($mesId: String){
		MessageFindOne(query: $mesId){
			_id
			text
			createdAt
			chat{
				_id
			}
			media {
				url
				_id
				type
				originalFileName
			}
			replyTo{
				_id
				text 
				media {
					url
					_id
					type
				}
				owner {
					nick
				}
			}
			replies{
				_id text 
				chat{
					_id
				}
			}
			forwarded{
				_id
				text
				owner {
					nick
				  }
				  media {
					url
					_id
					type
				  }
			}
			forwardWith{
				_id
				text
				chat{
					_id
				}
			}
			owner {
				_id
				nick
				avatar {
				  url
				}
			}
		}
	}`, {mesId: JSON.stringify([{_id}])}))

export const actionUpsertMSG = (message) => 
	actionPromise('sendMSG', gql(`mutation MessageUpsert($message: MessageInput) {
		MessageUpsert(message: $message) {
		  _id
		  createdAt
		  text
		  media {
			url
			_id
			type
		  }
		  replyTo{
			  _id
		  }
		  forwarded{
			  _id
		  }
		  owner {
			nick
			avatar {
			  url
			}
		  }
		  chat{
			_id
		  }
		}
	  }`, {
		  message 
	  }))

export const actionSendMessage = (messageId, chatId, text, media, replyTo, forwarded) => 
	async (dispatch, getState) => {
		let newMedia = null
		if(media){
			let checkedMedia = media.filter(item => !item._id && item)
			console.log(media, checkedMedia)
			let uploadedFiles =  checkedMedia.length !== 0 ? await  dispatch(actionUploadFiles(checkedMedia)) : null;
			newMedia = uploadedFiles ? [...uploadedFiles, ...media.filter(item => item._id && item)].map(({_id}) => ({_id})) : null;
			console.log(uploadedFiles)
		}
		
		const mes = Object.fromEntries(Object.entries({
			_id: messageId, chat: (chatId ? {_id: chatId} : chatId), text: text, media: newMedia, replyTo: (replyTo ? {_id: replyTo} : replyTo), forwarded: (forwarded ? {_id: forwarded} : forwarded) 
		}).filter(([_, v]) => v != null));
		console.log(mes)
			let message = await dispatch(actionUpsertMSG(mes))
			
			return message
		
	}

export const actionGetMessageFromSocket = (msg) => 
	async (dispatch, getState) => {
		let message = await dispatch(actionGetOneMessage(msg._id));
		dispatch(actionAddMessage(message, message.chat._id));
		dispatch(actionGetOneChat(msg.chat._id));
		////////check all replies and forwardWith (if message has them to send changes)
		const {replies, forwardWith} = message;
		const state = getState();
		// const [,route, histId] = history.location.pathname.split('/');
		if(replies){
			replies.forEach(async ({_id, chat}) => {
				if(state.chats[chat._id].messages?.hasOwnProperty(_id)){
					let mes = await dispatch(actionGetOneMessage(_id))
					dispatch(actionAddMessage(mes, chat._id));
				}
				
			})
		}
		if(forwardWith){
			forwardWith.forEach(async ({_id, chat}) => {
				if(state.chats[chat._id].messages?.hasOwnProperty(_id)){
					let mes = await dispatch(actionGetOneMessage(_id))
					dispatch(actionAddMessage(mes, chat._id));
				}
				
			})
		}
	}

export const actionEditMessage = (chatId, message) => 
	(dispatch, getState) => {
		dispatch(actionSetMessageEditor(chatId, {message: message, value: message.text}))
		if (message.media){
			let files = addUploadDate([...message.media])
			console.log(files)
			dispatch(actionSetDropMedia(chatId, files))
			dispatch(actionOpenModal('messageEditorMediaModal'))
		}
	}
