--SỬ DỤNG:
-- 1. quest id: 1, 2

require "npc/vl_quest_npc_client"
require "questui/vl_quest_introwindow_ui"
require "questui/vl_quest_markers"
require "questui/vl_quest_popup_ui"
--require "mainquest1/vl_quest1_playerglobalmoddata"

assert(VLPL, "Stack trace: Missing dependency: VLPL - vl_quest1_questupdate.lua")
assert(VLZB, "Stack trace: Missing dependency: VLZB - vl_quest1_questupdate.lua")
assert(VLIT, "Stack trace: Missing dependency: VLIT - vl_quest1_questupdate.lua")

local ActiveQuestIntro_Centre = VLF.ActiveQuestIntro_Centre
local ActiveQuestIntro_Free = VLF.ActiveQuestIntro_Free
local MarkerList_Remove = VLF.MarkerList_Remove
local SetNPCStateInQueueSpawnList = VLZB.SetNPCStateInQueueSpawnList
local IsPlayerInArea = VLPL.IsPlayerInArea
local GetPlayerGlobalModDataQ1 = VLGMD.GetPlayerGlobalModDataQ1
local QuestUpdatedPopIn = VLF.QuestUpdatedPopIn
local GetQuestGlobalModData = VLGMD.GetQuestGlobalModData
local GetZombieID = VLZB.GetZombieID
local SetNewZombieStats = VLZB.SetNewZombieStats
local AddObjectToSquare = VLF.AddObjectToSquare
local RemoveObjectOnSquare = VLF.RemoveObjectOnSquare
local GetZombieOnlineIDorUID = VLZB.GetZombieOnlineIDorUID
local GetPlayerModDataQuest = VLPL.GetPlayerModDataQuest
local GetObjectOnSquare = VLF.GetObjectOnSquare
local GetOrCreateSquare = VLF.GetOrCreateSquare
local AddOrRepairGenerator = VLF.AddOrRepairGenerator
local GetZombieModDataQuest = VLZB.GetZombieModDataQuest
local SetPlayerGMD_Q1 = VLGMD.SetPlayerGMD_Q1
local IsPlayerCanSeeNPC = VLPL.IsPlayerCanSeeNPC

local localVar = {}

--Lấy thời gian đã sống sót của nhân vật
local function GetSurvivedTime(player)
	if player then
		local hours = player:getHoursSurvived()
		local days = math.floor(hours / 24)
		local remainHours = math.floor(hours % 24)
		local minutes = math.floor((hours * 60) % 60)
		--print(string.format("Survived time: %d days, %d hours, %d minutes", days, remainHours, minutes))
		return hours, days, remainHours
	end
end

--Cập nhật quest step : true, false hoặc "done" 
local function SetQuestStepStateC(player, args) --SetQuestStepStateC(player, {qStep = "q1s001", active = true})
	local qStep = args.qStep
	local active = args.active
	if qStep then
		local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, qStep)
		--if not playerGMD_Quest_Q1[qStep] then playerGMD_Quest_Q1[qStep] = {} end
		playerGMD_Quest_Q1[qStep].active = active
		sendClientCommand(player, "MainQuest1", "UpdateQuestStep", {qStep = qStep, active = active})
	end
end

local function SetIsNPCqStep(player, args) --SetIsNPCqStep(player, {qStep = "q1s003"})
	local qStep = args.qStep
	if qStep then
		local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, qStep)
		if not playerGMD_Quest_Q1[qStep].isNPC then
			playerGMD_Quest_Q1[qStep].isNPC = true
			sendClientCommand(player, "MainQuest1", "UpdateQuestStep", {qStep_isNPC = qStep, active_isNPC = playerGMD_Quest_Q1[qStep].isNPC})
		end
	end
end
	 
--Cập nhật quest step + cập nhật quest ở trong bảng nhiệm vụ chính + Hiển thị thông báo Quest Updated
function VLF.DoQuestStepActive(player, args) --VLF.DoQuestStepActive(player, {npcTalk = true, introWindow = true, isPopIn = true, qStep = "q1s001", active = "done", qStep_Next = "q1s002", active_Next = true, isNPC_Next = false, qID = 1})
	local qStep, active = args.qStep, args.active
	local qStep_Next, active_Next = args.qStep_Next, args.active_Next
	local isPopIn = args.isPopIn or false
	local isNPC_Next = args.isNPC_Next or false
	local introWindow = args.introWindow or false
	local npcTalk = args.npcTalk or false
	local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, qStep)
	
	--print("Client-----------DoQuestStepActive= ", playerGMD_Quest_Q1[qStep].isNPC)
	--cập nhật qStep trước đó hoàn thành == "done"
	if qStep then
		SetQuestStepStateC(player, {qStep = qStep, active = active})
	end
	
	--nếu qStep trước đó có NPC thì
	if qStep and playerGMD_Quest_Q1[qStep] and playerGMD_Quest_Q1[qStep].isNPC == true then
		--xóa NPC khỏi danh sách chờ spawn
		SetNPCStateInQueueSpawnList({qStep = qStep, active = nil})
		--xóa ModData isNPC
		playerGMD_Quest_Q1[qStep].isNPC = nil
		sendClientCommand(player, "MainQuest1", "UpdateQuestStep", {qStep_isNPC = qStep, active_isNPC = nil})
	end	
	
	--kích hoạt qStep tiếp theo = true
	if qStep_Next then
		SetQuestStepStateC(player, {qStep = qStep_Next, active = active_Next})
	end
	
	--nếu qStep tiếp theo có NPC thì
	if isNPC_Next and isNPC_Next == true then
		--cập nhật ModData isNPC = true
		SetIsNPCqStep(player, {qStep = qStep_Next})
		--yêu cầu server thêm NPC vào danh sách chờ spawn
		SetNPCStateInQueueSpawnList({qStep = qStep_Next, active = true})
	end
	
	--hiện bảng thông báo cập nhật quest
	if isPopIn and isPopIn == true then
		QuestUpdatedPopIn()
	end
	
	--hiện bảng nội dung nhiệm vụ qStep tiếp theo
	if introWindow and introWindow == true then
		local qID = args.qID or 1
		ActiveQuestIntro_Centre(getText("IGUI_VLQ_"..tostring(qID).."_Desc_"..tostring(qStep_Next)), 800, 500, false, "")
	end
	
	--hiện bảng nội dung nhiệm vụ qStep tiếp theo
	if npcTalk and npcTalk == true then
		local qID = args.qID or 1
		ActiveQuestIntro_Centre(getText("IGUI_VLQ_"..tostring(qID).."_NPCTalk_"..tostring(qStep)), 800, 500, false, "")
	end
	
	--xóa marker nếu có
	MarkerList_Remove(qStep)
end
local DoQuestStepActive = VLF.DoQuestStepActive

--Xóa nhiệm vụ trong bảng quest --text là label của addItem, sẽ là "Q" .. qID
function VLF.QuestList_RemoveItem(text) --QuestList_RemoveItem("Q1") --1 là qID
    if not text then return end
    if VLF.QuestListShowOnUI[text] then
        VLF.QuestListShowOnUI[text] = nil
    end
end
local QuestList_RemoveItem = VLF.QuestList_RemoveItem

--Event Zombie update kích hoạt khi player đến gần khu vực này - 5537,12403 - 5589,12510 - z: 14 - 17
local function OnZombieUpdateq1s006(zombie)
	--local zData = zombie:getModData()
	local zData = GetZombieModDataQuest(zombie)
	if not zData.UID then zData.UID = zombie:getUID() return end
	
	--Kiểm tra zombie có nằm trong khu vực cần update không
	if not zData.inArea_q1s006 then
		local x, y, z = zombie:getX(), zombie:getY(), zombie:getZ()
		--print("Client-----------OnZombieUpdateq1s006= ", x, y, z)
		if ((z >= -17) and (z <= -14)) and ((x > 5537) and (x < 5589)) and ((y > 12403) and (y < 12510)) then
			zData.inArea_q1s006 = true
		else zData.inArea_q1s006 = "skip"
		end
	end
	
	--Nếu nằm trong khu vực update
	if zData.inArea_q1s006 == true then
		local zID = GetZombieID(zombie)
		--Kiểm tra zombie ID nào cần update
		if not zData.needUpdate_q1s006 then 	
			if zID % 20 == 0 then
				zData.needUpdate_q1s006 = true
				--print("Client-----------OnZombieUpdateq1s006: 2222222222")
			else zData.needUpdate_q1s006 = "skip"
			end
		end
		
		if zData.needUpdate_q1s006 == true then
			--print("Client-----------OnZombieUpdateq1s006: 333333333")
			SetNewZombieStats(zombie, {speed = 1, strength = 1, toughness = 1})
			zData.inArea_q1s006 = "updated"
		end
	end			
end
--Events.OnZombieUpdate.Remove(OnZombieUpdateq1s006)
--Events.OnZombieUpdate.Add(OnZombieUpdateq1s006)	

--q1s000
--THÔNG BÁO BẮT ĐẦU TẬN THẾ XÁC SỐNG
local function OnStartQuestQ1()
	local player = getPlayer()
	local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, nil)
	if not playerGMD_Quest_Q1.q1s000 then playerGMD_Quest_Q1.q1s000 = {} end
	--print("OnStartQuestQ1-------------= ", playerGMD_Quest_Q1.q1s000.CreQStepMD, playerGMD_Quest_Q1.q1s000.active)
	
	--KHỞI TẠO PLAYER GLOBAL MODDATA CHO TẤT CẢ QUEST STEP
	if not playerGMD_Quest_Q1.q1s000.CreQStepMD then
		local maxStep = VLF.var.Q1MaxStep
		local step = "q1s"
		for i = 0, maxStep do
			local qStep = ""
			if i < 10 then qStep = step.."00"..tostring(i)
			elseif i >= 10 and i <= 99 then qStep = step.."0"..tostring(i)
			else qStep = step..tostring(i) end
			
			if not playerGMD_Quest_Q1[qStep] then playerGMD_Quest_Q1[qStep] = {} end
		end
		sendClientCommand(player, "MainQuest1", "CreAllQuestStepMD", nil)
		playerGMD_Quest_Q1.q1s000.CreQStepMD = true
	end
	
	--HIỂN THỊ POP UP INTRO VÀ BẮT ĐẦU NHIỆM VỤ	
	if not playerGMD_Quest_Q1.q1s000.active then
		 --nếu thời gian sống sót lớn hơn 12 thì không cần hiện pop up start intro
		local hours = select(1, GetSurvivedTime(player))
		if hours < 12 then
			ActiveQuestIntro_Centre(getText("IGUI_VLQ_1_Desc_q1s001"), 800, 500, false, "")
		end	
		local active = true
		sendClientCommand(player, "MainQuest1", "UpdateQuestStep", {qStep = "q1s000", active = active})
		playerGMD_Quest_Q1.q1s000.active = active
	end
end
Events.OnGameStart.Remove(OnStartQuestQ1)
Events.OnGameStart.Add(OnStartQuestQ1)

local pTick = 1
local delay = 20

--MAIN FUNC --Chạy các qStep đang active
local function OnPlayerUpdate_Q1(player)
    if not player or player:isDead() then return end
	if pTick % delay == 0 then
		if not VLQS or not VLQS.Q1Steps then return end
		
		local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, nil)
		local activeQStepTab = {}
		for qStep, data in pairs(playerGMD_Quest_Q1) do
			if data.active == true then
				table.insert(activeQStepTab, qStep)
			end
		end
		
		for i = 1, #activeQStepTab do
			local func = VLQS.Q1Steps[activeQStepTab[i]]
			if func then
				func(player)
			end
		end
	end

	if pTick == 1000 then pTick = 0 end
	pTick = pTick + 1
end
Events.OnPlayerUpdate.Remove(OnPlayerUpdate_Q1)
Events.OnPlayerUpdate.Add(OnPlayerUpdate_Q1)


local p2Tick = 1
 
--Chạy các sự kiện liên quan Player có trong Quest
local function OnPlayerUpdate_EventQ1(player)
	if not player or player:isDead() then return end
	if p2Tick % 29 == 0 then
	
		--Zombie update khi ở Military Research Facility
		if IsPlayerInArea(player, 5537, 12456, 5589, 12510, nil) then
			if not localVar["addEvent006"] then
				--print("Client-----------Try-Active Event OnZombieUpdateq1s006: 222222222")
				Events.OnZombieUpdate.Remove(OnZombieUpdateq1s006)
				Events.OnZombieUpdate.Add(OnZombieUpdateq1s006)
				localVar["addEvent006"] = true
			end
		end
		
		--Cửa xuống phòng thí nghiệm của tiến sĩ luôn bị bịt lại, chỉ mở khi qStep q1s011 == true hoặc "done" 
		--update Generator
		local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, "q1s039")
		if not playerGMD_Quest_Q1["q1s039"]["deactiveLabRoom"] then
			if IsPlayerInArea(player, 10585, 10354, 10705, 10474, nil) then
				if not localVar["doorq1s011"] then
					local cell = getCell()
					local square1 = cell:getGridSquare(10645, 10414, 0)
					local square2 = cell:getGridSquare(10646, 10414, 0)
					local square3 = cell:getGridSquare(10647, 10414, 0)
					
					if square1 and square2 and square3 then
						local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, "q1s011")
						local spriteName = "floors_interior_tilesandwood_01_14"
						
						if not playerGMD_Quest_Q1.q1s011.active then
							--add obj mà không transmit để chỉ client này mới có tác dụng
							AddObjectToSquare(nil, spriteName, {isTransmit = false, needSqIsFree = false, needFloor = false, x = 10645, y = 10414, z = 0, objType = "IsoObject"})
							AddObjectToSquare(nil, spriteName, {isTransmit = false, needSqIsFree = false, needFloor = false, x = 10646, y = 10414, z = 0, objType = "IsoObject"})
							AddObjectToSquare(nil, spriteName, {isTransmit = false, needSqIsFree = false, needFloor = false, x = 10647, y = 10414, z = 0, objType = "IsoObject"})
						else
							--Mở cửa xuống khi q1s011 == true hoặc "done"
							RemoveObjectOnSquare(square1, spriteName, false, false)
							RemoveObjectOnSquare(square2, spriteName, false, false)
							RemoveObjectOnSquare(square3, spriteName, false, false)
							
							--print("Client-----------RemoveObjectOnSquare")
						end
						--Xóa zombie trong phòng thí nghiệm
						sendClientCommand(player, "NPCQuestCM", "RemoveZombiesInAreaExceptNPC", {x1 = 10630, y1 = 10394, x2 = 10651, y2 = 10415, z = -1})
						
						--Nếu đã mất điện thì Add Generator hoặc update Generator
							if not getWorld():isHydroPowerOn() then
								local x, y, z = 10647, 10398, -2
								AddOrRepairGenerator(true, "Base.Generator", x, y, z)
							end	
						
						localVar["doorq1s011"] = true
					end
				end
			else 
				if localVar["doorq1s011"] ~= false then localVar["doorq1s011"] = false end 
			end
		end
		 
		--Khi đến được phòng thí nghiệm của tiến sĩ thì update qStep q1s012 == true		--q1s011
		if IsPlayerInArea(player, 10630, 10394, 10651, 10415, -1) then
			if not localVar["upQStep011"] then
				--update qStep
				local qStep = "q1s011"
				local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, qStep)
				
				if not playerGMD_Quest_Q1[qStep]["activeQStepEvent"] then
					DoQuestStepActive(player, {introWindow = false, isPopIn = true, qStep = "q1s011", active = true, qStep_Next = "q1s012", active_Next = true, isNPC_Next = true})
					ActiveQuestIntro_Free(getText("IGUI_VLQ_2_Desc_q1s012"), (getCore():getScreenWidth() - 800) / 2, (getCore():getScreenHeight() - 200) / 6, 800, 250, false, "")
					playerGMD_Quest_Q1[qStep]["activeQStepEvent"] = true
					--sendClientCommand(player, "MainQuest1", "UpdateAllPlayerGMD", playerGMD_Quest_Q1)
					sendClientCommand(player, "MainQuest1", "UpdatePlayerGMD", {qStep = qStep, key = "activeQStepEvent", val = true})
					--print("Client-----------playerGMD_Quest_Q1[q1s011].activeQStepEvent", playerGMD_Quest_Q1[qStep].activeQStepEvent)
				end
				localVar["upQStep011"] = true
			end
		else 
			if localVar["upQStep011"] ~= false then localVar["upQStep011"] = false end 	
		end

		--Khi đến BunkerLab --q1s041
		if IsPlayerInArea(player, 12469, 11210, 12589, 11330, nil) then
			local qStep = "q1s041"
			if not localVar["bunkerLab041"] then
				local x, y, z = 12529, 11270, 0 --tọa độ x, y, z khởi tạo bunker room
				--Xóa zombie xung quanh khu vực bunker
				sendClientCommand(player, "NPCQuestCM", "RemoveZombiesInAreaExceptNPC", {x1 = x - 18, y1 = y - 18, x2 = x + 23, y2 = y + 25, z = 0})
				sendClientCommand(player, "NPCQuestCM", "RemoveZombiesInAreaExceptNPC", {x1 = x - 18, y1 = y - 18, x2 = x + 23, y2 = y + 25, z = -1})
				
				--Nếu đã mất điện thì Add Generator hoặc update Generator
				--FIXME: dừng update máy phát điện này khi BunkerLab không còn ai hoặc bị hủy
				if not getWorld():isHydroPowerOn() then
					local x, y, z = 12526, 11270, -2
					AddOrRepairGenerator(true, "Base.Generator", x, y, z)
				end	
				
				localVar["bunkerLab041"] = true
			end
			
			--Khi ở dưới BunkerLab và nhìn thấy em trai
			if IsPlayerInArea(player, 12520, 11262, 12534, 11277, -1) then
				local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, qStep)
				if IsPlayerCanSeeNPC(player, nil, "npcQuestIdle", "q1s041_3") then
					if not playerGMD_Quest_Q1[qStep]["metBrother"] then
						ActiveQuestIntro_Free(getText("IGUI_VLQ_2_Notification1_q1s041"), (getCore():getScreenWidth() - 800) / 2, (getCore():getScreenHeight() - 200) / 6, 800, 250, false, "")
				
						--set tất cả qStep từ q1s001 -> q1s011 thành done
						for i = 1, 11 do
							local step = i < 10 and "0" .. tostring(i) or tostring(i)
							SetQuestStepStateC(player, {qStep = "q1s0" .. step, active = "done"})
						end
						
						SetPlayerGMD_Q1(player, qStep, "metBrother", true)
						--playerGMD_Quest_Q1[qStep]["metBrother"] = true
						
						DoQuestStepActive(player, {npcTalk = nil, isPopIn = true, qStep = "q1s041", active = "done", qStep_Next = "q1s042", active_Next = true, isNPC_Next = false, qID = 1})
						
						--xóa hiển thị Quest qID 2 trong danh sách quest
						QuestList_RemoveItem("Q2")
						--QuestUpdatedPopIn()
					end
				end
			end 
		else 
			if localVar["bunkerLab041"] ~= false then localVar["bunkerLab041"] = false end 
		end
	end
	if p2Tick == 1000 then p2Tick = 1 end
	p2Tick = p2Tick + 1
end
Events.OnPlayerUpdate.Remove(OnPlayerUpdate_EventQ1)
Events.OnPlayerUpdate.Add(OnPlayerUpdate_EventQ1)









