--============= Survivalist_InHouse: FreeNPC Give Quest When TALK =============--
--FreeNPC trong Event Survivalist_InHouse nếu không bị nhiễm virus thì sẽ có Quest cho player
--Quest yêu cầu 1 loại vật phẩm, phần thưởng được chọn ngẫu nhiên 1 trong tối đa 3 loại
--Tất cả vật phẩm yêu cầu và phần thưởng đều sẽ ngẫu nhiên
--FreeNPC sẽ bị xóa khi unload, hoặc bị xóa sau 24 giờ nếu player vẫn ở gần đó
--=============================================================================--
--CÁC BƯỚC ĐỂ QUEST CỦA FREENPC HOẠT ĐỘNG:
	--IGUI_VLQ_Event_freeNPC = "...Người này cho biết họ		--text hiển thị bảng talk đầu tiên		--freeNPC là qStep
	--VLINTER.SetButtons["freeNPC"] = function(player, qStep, buttonList)		--func xác định các nút nào được hiển thị
	--IGUI_VLQ_Reward_freeNPC = "Đổi lấy %1 %2"		--text hiển thị ở đầu button reward		--freeNPC là qStep
	--playerGMD_Event[qStep]["rewardItem1FName"] 	--tên của item reward 1 hiển thị trên button
	--playerGMD_Event[qStep]["reward1Num"]			--số lượng item reward 1 hiển thị trên button
	--playerGMD_Event[qStep]["rewardItem2FName"]	--tên của item reward 2 hiển thị trên button
	--playerGMD_Event[qStep]["reward2Num"]			--số lượng item reward 2 hiển thị trên button
	--playerGMD_Event[qStep]["rewardItem3FName"]	--tên của item reward 3 hiển thị trên button
	--playerGMD_Event[qStep]["reward3Num"]			--số lượng item reward 3 hiển thị trên button
	--VLINTER.Rewards["freeNPC"] = function(player, qStep, args)   --(player, qStep, {chooseReward = 1})	--xác định các phần thưởng
--=============================================================================--	

VLF.TalkToNPC = VLF.TalkToNPC or {}

local GetQuestGlobalModData = VLGMD.GetQuestGlobalModData
local SetPlayerGMD_Event = VLGMD.SetPlayerGMD_Event
local GetPlayerGlobalModData = VLGMD.GetPlayerGlobalModData
local RemoveNPCQuest = VLZB.RemoveNPCQuest
local GetPlayerGlobalModDataEvent = VLGMD.GetPlayerGlobalModDataEvent
local ClearTablePlayerGMD = VLGMD.ClearTablePlayerGMD
local GetNPCsByVarAndQStep = VLZB.GetNPCsByVarAndQStep
local IsCharExistAndAlive = VLZB.IsCharExistAndAlive
local GetItemsInContainer = VLIT.GetItemsInContainer
local GetAmountFluidInContainer = VLIT.GetAmountFluidInContainer
local GetAmountReduceHungerInContainer = VLIT.GetAmountReduceHungerInContainer
local RemoveFluidKeepSource = VLIT.RemoveFluidKeepSource
local RemoveItemFromContainer = VLIT.RemoveItemFromContainer
local AddItemToContainer = VLIT.AddItemToContainer
local RemoveFoodInContainer = VLIT.RemoveFoodInContainer
local AddReputationPoint = VLGMD.AddReputationPoint

local VLF_var_itemList = VLF.var.itemList

--local requestTypeList = {"gasoline", "water", "foodItems", "smokeItems", "rangedWpnItems", "ammoItems", "meleeWpnItems", "weaponPartItems", "explosivesItems", "skillBookItems", "medicalItems"}
local requestTypeList = {"gasoline", "water", "foodItems", "smokeItems", "rangedWpnItems", "ammoItems", "meleeWpnItems", "weaponPartItems", "explosivesItems", "skillBookItems", "medicalItems"}
local rewardTypeList = {"gasoline", "foodItems", "smokeItems", "rangedWpnItems", "ammoItems", "meleeWpnItems", "weaponPartItems", "explosivesItems", "skillBookItems", "medicalItems"}
local exceptionItems = {
	["Base.FISH_DEV_ITEM"] = true,

}
local requestTypeWeight = {
	["gasoline"] = 			{list = VLF_var_itemList["gasoline"], 		weight = 50 },
	["water"] = 			{list = VLF_var_itemList["water"], 			weight = 110 },
	["foodItems"] = 		{list = VLF_var_itemList["foodItems"], 		weight = 150 },
	["smokeItems"] = 		{list = VLF_var_itemList["smokeItems"], 	weight = 25 },
	["rangedWpnItems"] = 	{list = VLF_var_itemList["rangedWpnItems"], weight = 70 },
	["ammoItems"] = 		{list = VLF_var_itemList["ammoItems"], 		weight = 70 },
	["meleeWpnItems"] = 	{list = VLF_var_itemList["meleeWpnItems"],	 weight = 90 },
	["weaponPartItems"] =	{list = VLF_var_itemList["weaponPartItems"], weight = 30 },
	["explosivesItems"] = 	{list = VLF_var_itemList["explosivesItems"], weight = 30 },
	["skillBookItems"] = 	{list = VLF_var_itemList["skillBookItems"], weight = 50 },
	["medicalItems"] = 		{list = VLF_var_itemList["medicalItems"], 	weight = 80 }
}
local rewardTypeWeight = {
	["gasoline"] = 			{list = VLF_var_itemList["gasoline"], 		weight = 15 },
	["foodItems"] = 		{list = VLF_var_itemList["foodItems"], 		weight = 60 },
	["smokeItems"] = 		{list = VLF_var_itemList["smokeItems"], 	weight = 60 },
	["rangedWpnItems"] = 	{list = VLF_var_itemList["rangedWpnItems"], weight = 30 },
	["ammoItems"] = 		{list = VLF_var_itemList["ammoItems"], 		weight = 50 },
	["meleeWpnItems"] = 	{list = VLF_var_itemList["meleeWpnItems"],	 weight = 90 },
	["weaponPartItems"] =	{list = VLF_var_itemList["weaponPartItems"], weight = 60 },
	["explosivesItems"] = 	{list = VLF_var_itemList["explosivesItems"], weight = 40 },
	["skillBookItems"] = 	{list = VLF_var_itemList["skillBookItems"], weight = 120 },
	["medicalItems"] = 		{list = VLF_var_itemList["medicalItems"], 	weight = 60 }
}

local function RandomByWeight(groupTable)
    local totalWeight = 0

    for _, data in pairs(groupTable) do
        totalWeight = totalWeight + data.weight
    end
	
	if totalWeight <= 0 then return nil, nil end
	
    local rnd = ZombRand(totalWeight) + 1
    local current = 0

    for qType, data in pairs(groupTable) do
        current = current + data.weight
        if rnd <= current then
            return qType, data.list
        end
    end

    return nil, nil
end

local function RandomItemFromList(list)
    if not list or #list == 0 then return nil end
	--không chọn các item có trong danh sách exceptionItems
	for i = 1, 20 do
		local item = list[ZombRand(#list) + 1]
		if not exceptionItems[item] then
			return item
		end
	end
end

--Tạo quest ngẫu nhiên VÀ tạo các dữ liệu cần thiết cho quest
local function CreateAQuest(player, square, zNPC, qStep)
	--Chọn requestType theo tỉ lệ
	--local qType, itemList = "medicalItems", requestTypeWeight["medicalItems"].list	--TEST ONLY	--FIXME
	local qType, itemList = RandomByWeight(requestTypeWeight)
	if not itemList or #itemList == 0 then
		print("ERROR: itemList empty for qType:", qType)
		return
	end

	--if isDebugEnabled() then
	--	for i = 1, #itemList do
	--		print(itemList[i])
	--	end
	--end
	
	--chọn tên item của loại quest đó
	local requestItem = RandomItemFromList(itemList)
	--chọn số lượng yêu cầu
	local reqItemNum = 1
	
	--Phần thưởng
	local rewardType1, rewardType2, rewardType3
	local rewardList1, rewardList2, rewardList3
	local reward1Num, reward2Num, reward3Num

	local function getRewardType()
		local pool = {}
		for _qType, data in pairs(rewardTypeWeight) do
			pool[_qType] = data
		end
		
		--Xóa qType để không chọn lại qType
		if pool[qType] then
			pool[qType] = nil
		end
		
		rewardType1, rewardList1 = RandomByWeight(pool)
		pool[rewardType1] = nil
		rewardType2, rewardList2 = RandomByWeight(pool)
		pool[rewardType2] = nil
		rewardType3, rewardList3 = RandomByWeight(pool)
	end
	getRewardType()
	
	local rewardItem1 = RandomItemFromList(rewardList1)
	local rewardItem2 = RandomItemFromList(rewardList2)
	local rewardItem3 = RandomItemFromList(rewardList3)
	
	SetPlayerGMD_Event(player, qStep, "questType", qType)
	SetPlayerGMD_Event(player, qStep, "reqItemFullName", requestItem)
	SetPlayerGMD_Event(player, qStep, "reqItemNum", reqItemNum)
	SetPlayerGMD_Event(player, qStep, "rewardItem1FName", rewardItem1)
	reward1Num = 1
	SetPlayerGMD_Event(player, qStep, "reward1Num", reward1Num)
	
	if rewardItem2 and ZombRand(100) < 75 then
		SetPlayerGMD_Event(player, qStep, "rewardItem2FName", rewardItem2)
		reward2Num = 1
		SetPlayerGMD_Event(player, qStep, "reward2Num", reward2Num)
	end
	
	if rewardItem3 and ZombRand(100) < 50 then
		SetPlayerGMD_Event(player, qStep, "rewardItem3FName", rewardItem3)
		reward3Num = 1
		SetPlayerGMD_Event(player, qStep, "reward3Num", reward3Num)
	end
	
	--print("------------qType= ", qType)
	--print("------------requestItem= ", requestItem)
	--print("------------reqItemNum= ", reqItemNum)
	--print("------------rewardItem1= ", rewardItem1)
	--print("------------reward1Num= ", reward1Num)
	--print("------------rewardItem2= ", rewardItem2)
	--print("------------reward2Num= ", reward2Num)
	--print("------------rewardItem3= ", rewardItem3)
	--print("------------reward3Num= ", reward3Num)
	--print("--========= CREATED QUEST =========--")
	return qType
end

--Thêm dữ liệu khi questType là water, foodItems, gasoline 	--Vì là yêu cầu đặc biệt vì tính số liệu riêng
local function SetRequestItems(player, zNPC, qStep)
	local reqItemName, reqItemNum
	local playerGMD_Event = GetPlayerGlobalModDataEvent(player, qStep)
	if playerGMD_Event[qStep]["questType"] == "water" then
		reqItemName = getText("ContextMenu_WaterName")
		reqItemNum = ZombRand(3,7)
		SetPlayerGMD_Event(player, qStep, "reqWaterName", reqItemName)
		SetPlayerGMD_Event(player, qStep, "reqWaterNum", reqItemNum)
		
	elseif playerGMD_Event[qStep]["questType"] == "foodItems" then
		reqItemName = getText("IGUI_VLQ_ReduceHungerFromFood")
		reqItemNum = ZombRand(130,201)
		SetPlayerGMD_Event(player, qStep, "reqFoodName", reqItemName)
		SetPlayerGMD_Event(player, qStep, "reqReduceHungerNum", reqItemNum)
		
	elseif playerGMD_Event[qStep]["questType"] == "gasoline" then
		reqItemName = getText("Fluid_Name_Petrol")
		reqItemNum = ZombRand(1,4)
		SetPlayerGMD_Event(player, qStep, "reqGasName", reqItemName)
		SetPlayerGMD_Event(player, qStep, "reqGasNum", reqItemNum)
		
	else
		reqItemName = getScriptManager():getItem(playerGMD_Event[qStep]["reqItemFullName"]):getDisplayName()
		reqItemNum = playerGMD_Event[qStep]["reqItemNum"]
	end
	
	return reqItemName, reqItemNum
end

--Lấy dữ liệu vật tư yêu cầu của NPC theo questType
local function GetRequestItems(player, zNPC, qStep)
	local reqItemName, reqItemNum
	local playerGMD_Event = GetPlayerGlobalModDataEvent(player, qStep)
	if playerGMD_Event[qStep]["questType"] == "water" then
		reqItemName = playerGMD_Event[qStep]["reqWaterName"]
		reqItemNum = playerGMD_Event[qStep]["reqWaterNum"]
		
	elseif playerGMD_Event[qStep]["questType"] == "foodItems" then
		reqItemName = playerGMD_Event[qStep]["reqFoodName"]
		reqItemNum = playerGMD_Event[qStep]["reqReduceHungerNum"]
		
	elseif playerGMD_Event[qStep]["questType"] == "gasoline" then
		reqItemName = playerGMD_Event[qStep]["reqGasName"]
		reqItemNum = playerGMD_Event[qStep]["reqGasNum"]
		
	else
		--reqItemName = playerGMD_Event[qStep]["requestItem"]:getDisplayName()
		reqItemName = getScriptManager():getItem(playerGMD_Event[qStep]["reqItemFullName"]):getDisplayName()
		reqItemNum = playerGMD_Event[qStep]["reqItemNum"]
	end
	
	return reqItemName, reqItemNum
end
	
--====================================================================--
local activeEvent = false

--Talk với các freeNPC của event Survivalist_InHouse
VLF.TalkToNPC["freeNPC"] = function(player, square, zNPC, qStep)
	if not qStep or not zNPC then return end
	if IsCharExistAndAlive(zNPC) then
		local playerGMD_Event = GetPlayerGlobalModDataEvent(player, qStep)
				
		--Lấy thời gian bắt đầu nói chuyện
		if not playerGMD_Event[qStep]["startHour"] then
			SetPlayerGMD_Event(player, qStep, "startHour", getGameTime():getWorldAgeHours())
		end
		
		--Tính thời gian để xóa NPC sau 1 ngày.
		if activeEvent == false then	--chỉ chạy 1 lần khi Talk, active lại khi relogin
		
			local function EveryHours_RemoveFreeNPC()
				if IsCharExistAndAlive(zNPC) then
					if playerGMD_Event[qStep] and playerGMD_Event[qStep]["startHour"] then
						local now = getGameTime():getWorldAgeHours()
						if (now - playerGMD_Event[qStep]["startHour"]) >= 24 then
							RemoveNPCQuest(zNPC)
							SetPlayerGMD_Event(player, qStep, "startHour", nil)
							Events.EveryHours.Remove(EveryHours_RemoveFreeNPC)
						end
					else
						Events.EveryHours.Remove(EveryHours_RemoveFreeNPC)
					end	
				else
					Events.EveryHours.Remove(EveryHours_RemoveFreeNPC)
				end
			end
			Events.EveryHours.Remove(EveryHours_RemoveFreeNPC)
			Events.EveryHours.Add(EveryHours_RemoveFreeNPC)
			
			activeEvent = true
		end
		
		local qType
		local reqItemName, reqItemNum
		--Tạo quest ngẫu nhiên
		if not playerGMD_Event[qStep]["isQCreated"] then
			qType = CreateAQuest(player, square, zNPC, qStep)
			reqItemName, reqItemNum = SetRequestItems(player, zNPC, qStep)
			SetPlayerGMD_Event(player, qStep, "isQCreated", true)
		end
		
		local reqItemName, reqItemNum = GetRequestItems(player, zNPC, qStep)
		local textReqItemNum = ""
		local _qType = playerGMD_Event[qStep]["questType"]
		if _qType == "gasoline" or _qType == "water" then
			textReqItemNum = tostring(reqItemNum) .. "L"
		elseif _qType == "foodItems" then
			textReqItemNum = tostring(reqItemNum)
		else
			textReqItemNum = tostring(reqItemNum) .. "x"
		end
		
		--Hiện bảng talk interaction
		VLF.QuestUI.NPCInteractionWindow(player, qStep, getText("IGUI_VLQ_Event_freeNPC", textReqItemNum, reqItemName), 800, 700, zNPC)
	else
		HaloTextHelper.addBadText(player, getText("IGUI_VLQ_Notification_NPCNotExist"))
	end
end

--clear modData Quest của freeNPC nếu freeNPC không tồn tại
local function EveryTenMinutes_ClearData()
	--lấy qStep từ Event
	--kiểm tra qStep freeNPC này có đang spawned không, không thì clear data
	local player = getPlayer()
	local questMD = GetQuestGlobalModData(nil)
	local playerGMD = GetPlayerGlobalModData(player)
	for qStep, _ in pairs(playerGMD.Event) do
		--lọc qStep freeNPC_ để không xóa nhầm table event khác
		if qStep and string.find(qStep, "freeNPC_") then
			if not questMD.NPC[qStep] or questMD.NPC[qStep]["spawned"] ~= true then
				--print("Client---EveryTenMinutes_ClearData---XOA TABLE= ", qStep)
				ClearTablePlayerGMD(player, true, "Event", qStep)
			end
        end
    end
end
Events.EveryTenMinutes.Remove(EveryTenMinutes_ClearData)
Events.EveryTenMinutes.Add(EveryTenMinutes_ClearData)

local function IsEnoughRequestItems(player, qStep)
	local playerGMD_Event = GetPlayerGlobalModDataEvent(player, qStep)
	if playerGMD_Event[qStep]["questType"] == "water" then
		local reqItemNum = playerGMD_Event[qStep]["reqWaterNum"]
        local waterInInv = GetAmountFluidInContainer(player:getInventory(), Fluid.Water)
        if waterInInv and reqItemNum and waterInInv >= reqItemNum then
            return true
        end
		 
	elseif playerGMD_Event[qStep]["questType"] == "foodItems" then
		local reqItemNum = playerGMD_Event[qStep]["reqReduceHungerNum"]
        local rHungerInInv = GetAmountReduceHungerInContainer(player:getInventory(), true, true, false)
		if rHungerInInv and reqItemNum and rHungerInInv >= reqItemNum then
            return true
        end

	elseif playerGMD_Event[qStep]["questType"] == "gasoline" then
        local reqItemNum = playerGMD_Event[qStep]["reqGasNum"]
        local gasInInv = GetAmountFluidInContainer(player:getInventory(), Fluid.Petrol)

        if gasInInv and reqItemNum and gasInInv >= reqItemNum then
            return true
        end
         
	else
        local reqItemFullType = playerGMD_Event[qStep]["reqItemFullName"]
		local itemList = {}
		GetItemsInContainer(player:getInventory(), itemList, reqItemFullType)

		local reqItemNum = playerGMD_Event[qStep]["reqItemNum"]
        if #itemList >= reqItemNum then
            return true
        end
	end
    --print("Client---IsEnoughRequestItems= ", false)
    return false
end

local function RemoveRequestItems(player, qStep)
	local playerGMD_Event = GetPlayerGlobalModDataEvent(player, qStep)
	if playerGMD_Event[qStep]["questType"] == "water" then
		local reqItemNum = playerGMD_Event[qStep]["reqWaterNum"]
        RemoveFluidKeepSource(player:getInventory(), Fluid.Water, reqItemNum)

	elseif playerGMD_Event[qStep]["questType"] == "foodItems" then
		local reqItemNum = playerGMD_Event[qStep]["reqReduceHungerNum"]
        RemoveFoodInContainer(player:getInventory(), reqItemNum)

	elseif playerGMD_Event[qStep]["questType"] == "gasoline" then
        local reqItemNum = playerGMD_Event[qStep]["reqGasNum"]
        RemoveFluidKeepSource(player:getInventory(), Fluid.Petrol, reqItemNum)
         
	else
        local reqItemFullType = playerGMD_Event[qStep]["reqItemFullName"]
		local reqItemNum = playerGMD_Event[qStep]["reqItemNum"]
        RemoveItemFromContainer(player:getInventory(), nil, reqItemFullType, reqItemNum)
	end
    --print("Client---RemoveRequestItems= ", playerGMD_Event[qStep]["questType"])
end 


--Sử dụng trong function VL_Quest_TalkToNPC_Interaction_UI:onReward1() | onReward2 | onReward3
--chooseReward: số lượng phần thưởng để chọn. PHẢI tương ứng với số lượng nút reward hiển thị
VLINTER.Rewards["freeNPC"] = function(player, qStep, args)   --(player, qStep, {chooseReward = 1})
    local playerGMD_Event = GetPlayerGlobalModDataEvent(player, qStep)
    local reqItemFullType = playerGMD_Event[qStep]["reqItemFullName"]
    local reqItemNum = playerGMD_Event[qStep]["reqItemNum"]
    local chooseReward = args.chooseReward or 1
    
    local zNPCList = GetNPCsByVarAndQStep("npcQuestIdle", qStep)
    if zNPCList and zNPCList[1] and IsCharExistAndAlive(zNPCList[1]) then        
        local zNPC = zNPCList[1]

        if IsEnoughRequestItems(player, qStep) then
            --Xóa items quest
            RemoveRequestItems(player, qStep)
            
            --Thêm item thưởng
            if chooseReward == 1 then
                local reward1FullType = playerGMD_Event[qStep]["rewardItem1FName"]
                local reward1Num = playerGMD_Event[qStep]["reward1Num"]
                AddItemToContainer(player:getInventory(), nil, reward1FullType, reward1Num)
            elseif  chooseReward == 2 then
                local reward2FullType = playerGMD_Event[qStep]["rewardItem2FName"]
                local reward2Num = playerGMD_Event[qStep]["reward2Num"]
                AddItemToContainer(player:getInventory(), nil, reward2FullType, reward2Num)
            elseif  chooseReward == 3 then
                local reward3FullType = playerGMD_Event[qStep]["rewardItem3FName"]
                local reward3Num = playerGMD_Event[qStep]["reward3Num"]
                AddItemToContainer(player:getInventory(), nil, reward3FullType, reward3Num)
            end
            
            --Xóa data nhiệm vụ
            ClearTablePlayerGMD(player, true, "Event", qStep)
            
            --Hiện khung chat tiếp --đặt dưới cùng để không bị hiển thị các nút khác khi data chưa cập nhật
            local _qStep = qStep
            if string.find(qStep, "freeNPC_") then
                _qStep = "freeNPC"
            end
            VLF.QuestUI.NPCInteractionWindow(player, qStep, getText("IGUI_VLQ_Event_Done_" .. _qStep), 800, 700, zNPC)
            player:getEmitter():playSound("questcompleted_1")
            
            --Xóa NPC
            RemoveNPCQuest(zNPCList[1])
            
			AddReputationPoint(player, 5)
            --print("Client---TradeWithFreeNPC---E.N.D")
        else
            HaloTextHelper.addBadText(player, getText("IGUI_VLQ_Notification_NotEnoughItemsQuest"))
        end
    else
        HaloTextHelper.addBadText(player, getText("IGUI_VLQ_Notification_NPCNotExist"))
    end
end

--Sử dụng trong function ActivateVisibleButtons  --file: vl_quest_talktonpc_interaction_ui.lua
--Chọn các button để hiển thị phụ thuộc vào các ModData của quest
VLINTER.SetButtons["freeNPC"] = function(player, qStep, buttonList)
    local playerGMD_Event = GetPlayerGlobalModDataEvent(player, qStep)

    if playerGMD_Event[qStep]["rewardItem1FName"] then
		buttonList["rewardButton1"] = true
    end
    if playerGMD_Event[qStep]["rewardItem2FName"] then
        buttonList["rewardButton2"] = true
    end
    if playerGMD_Event[qStep]["rewardItem3FName"] then
		buttonList["rewardButton3"] = true
    end
end







