local common = require "interactionmanip.common"
local cjson = require "cjson"
local utf8 = require "icu.utf8"
local facebook = {}

function facebook.module_type ()
	return "facebook"
end

local function getMessageText(message)
	return message.message or message.story or message.text or 
		(message.attachment and message.attachment.payload and message.attachment.payload.text) or ""
end

---
-- returns the conversation contact or member display text
--
function facebook.getUserName (interaction, index, withType)
	assert(type(index) == "number")

	if not interaction.events or not interaction.events[index] then
		return ""
	end

	local event = interaction.events[index]
	if not withType then
		return event.message.from.name
	end
	local agent_id = event.agent
	if not agent_id then
		return "text:"..event.message.from.name
	else
		return "agent_id:"..agent_id
	end
end

---
-- Returns the first user name from the events array
--
function facebook.getDisplayName (interaction, withType)
	local index = 1
	if interaction.interactionData and interaction.interactionData.subtype == "NewPostComment" 
		and interaction.events and #interaction.events > 1 
	then
		index = 2
	end
	return facebook.getUserName(interaction, index, withType)
end

function facebook.getExtendedInfo (interaction)
	--LogInfo("facebook.getExtendedInfo id: '%s'", interaction.id)

	if not interaction.events or not interaction.events[1] then
		--LogInfo("facebook.getExtendedInfo nos fuimos")
		return ""
	end

	local event = interaction.events[1]

	local message = getMessageText(event.message)
	if type(message) == "string" then
		return utf8.sub(message, 1, 200)
	end

	return ""
end

---
-- returns true if at least one event is a private message
function facebook.isPrivateMessage (interaction)
	if interaction.interactionData and interaction.interactionData.subtype then
		return interaction.interactionData.subtype == "PageInboxNewMessage"
	end
	if interaction.events then
		for _, event in ipairs(interaction.events) do
			local message = event.message
			if message and (message.type == "mail" or message.type == "pageMail" or message.type == "webhookMessage") then
				return true
			end
		end
	end
	return false
end

---
-- Normalize the structure of events. This was being done in the agent.
--
function facebook.normalizeEvents (interaction)

	if not interaction.events then
		return
	end

	for _, event in ipairs(interaction.events) do

		if type(event.message) == "string" then
			event.message = cjson.decode(event.message)
		end

		-- It happened that created_time was missing. 
		event.message.created_time = event.message.created_time or event.timestamp

		-- normalize private messages
		if event.message.body then
			event.message.id = event.message.id or event.message.message_id
			event.message.message = event.message.message or event.message.body
			event.message.type = event.message.type or "mail"
			event.message.from = {
				id = (event.message.from and event.message.from.id) and event.message.from.id or event.message.author_id,
				name = (event.message.from and event.message.from.name) and event.message.from.name or event.message.author_id
			}
			event.message.body = nil
		end
	end
end

local getSocialNetworkPostId_subtypes = {
	NewPostComment = function(interaction)
		if not interaction.events or #interaction.events < 1 then
			return nil
		end
		return interaction.events[1].message.id
	end
}

function facebook.getSocialNetworkPostId (interaction)
	local postId = common.getSocialNetworkPostId (interaction)
	if postId then
		return postId
	end
	local subtype = interaction.interactionData and interaction.interactionData.subtype or ""
	local getFunction = getSocialNetworkPostId_subtypes[subtype]
	return getFunction and getFunction(interaction) or nil
end

---
-- Takes an interaction and precomputes properties based on events
--
function facebook.updateInteraction (interaction)

	--LogWarning("Updating interaction '%s'", interaction.id)

	interaction.properties = interaction.properties or {}

	facebook.updateReaders(interaction)
	facebook.updateLabels(interaction)
	facebook.isTransferred(interaction)
	facebook.getLastAgentEndsConversation(interaction)
	facebook.getLastStep(interaction)
	facebook.normalizeEvents(interaction)

	interaction.properties.display_name = facebook.getDisplayName(interaction, true)
	interaction.properties.summary = facebook.getExtendedInfo(interaction)
	interaction.properties.event_count = facebook.getEventsCountWithoutAutoResponse(interaction)
	interaction.properties.unread_event_count = facebook.getUnreadEventCount(interaction)
	interaction.properties.is_private_message = facebook.isPrivateMessage(interaction)
	interaction.properties.unanswered_event_count = facebook.getUnAnsweredContactEventCount(interaction)
	interaction.interactionData.postId = interaction.interactionData.postId or facebook.getSocialNetworkPostId(interaction)
	interaction.properties.has_attachments = facebook.hasAttachments(interaction)
	return interaction
end

---
-- Takes an interaction and returns a block of text to be sent to the search engine
--
function facebook.getSearchableContent (interaction)
	if not interaction.events then return "" end
	local data = {}

	for _, event in ipairs(interaction.events) do
		table.insert(data, getMessageText(event.message))
	end

	if interaction.comments then
		for _, comment in pairs(interaction.comments) do
			table.insert(data, comment.comment)
			table.insert(data, comment.authorName)
		end
	end

	return table.concat(data, " ")
end

--[[
	
--]]
function facebook.calculateConversationTotalCharacters (interaction)
	assert(interaction)
	return common.calculateConversationTotalCharactersFacebookInstagram(interaction)
end

function facebook.hasAttachments (interaction)
	assert(interaction)
	local messages = interaction.events
	if messages then
		for _, event in ipairs(messages) do
			if event.message and event.message.files and #event.message.files > 0 then
				return true
			end
		end
	end
	return false
end

-------------------------------------------
facebook.isTransferred                        = common.isTransferred
facebook.isTaken                              = common.isTaken
facebook.isWrappedUp                          = common.isWrappedUp
facebook.isFinished                           = common.isFinished
facebook.getConversationOwner                 = common.getConversationOwner
facebook.getFirstAssignedAgent                = common.getFirstAssignedAgent
facebook.getLastAgentEndsConversation         = common.getLastAgentEndsConversation
facebook.getLastEventTimestamp                = common.getLastEventTimestamp
facebook.updateReaders                        = common.updateReaders
facebook.updateLabels                         = common.updateLabels
facebook.getLastStep                          = common.getLastStep
facebook.isAutoResponseEvent                  = common.isAutoResponseEvent
facebook.getUnreadEventCount                  = common.getUnreadEventCount
facebook.getUnAnsweredContactEventCount		 = common.getUnAnsweredContactEventCount
facebook.getEventsCountWithoutAutoResponse    = common.getEventsCountWithoutAutoResponse
facebook.getAllEventsCount                    = common.getAllEventsCount
facebook.newInteractionEvent                  = common.newInteractionEvent
facebook.newInteractionEvents                 = common.newInteractionEvents
facebook.getFirstTransferringInfo             = common.getFirstTransferringInfo
facebook.getBatchId                           = common.getBatchId
facebook.loadFirstPendingStep                 = common.loadFirstPendingStep
facebook.loadStatusInteraction                = common.loadStatusInteraction
facebook.loadFirstTakenStep                   = common.loadFirstTakenStep
facebook.loadStartAttention                   = common.loadStartAttention
facebook.loadTicket                           = common.loadTicket
facebook.loadFirstAgentResponse               = common.loadFirstAgentResponse
facebook.loadLastAgentResponse                = common.loadLastAgentResponse
facebook.loadSubType                          = common.loadSubType
facebook.loadPage                             = common.loadPage
facebook.getConversationTotals                = common.getConversationTotals
facebook.calculateConversationTimeSec         = facebook.calculateConversationTimeSec or common.calculateConversationTimeSec
facebook.calculateConversationTotalCharacters = facebook.calculateConversationTotalCharacters or common.calculateConversationTotalCharacters

return facebook