
local HasTimePassedInHours = VLF.HasTimePassedInHours
local GetModDataCarpetBombingEvent = VLECB.GetModDataCarpetBombingEvent
local PlayBombEffect = VLECB.PlayBombEffect
local GetPlayerGMDCarpetBombing = VLECB.GetPlayerGMDCarpetBombing
local AddToCBQuestList = VLECB.AddToCBQuestList
local CaldistanceCoordinates = VLF.CaldistanceCoordinates
local CalculateDistanceXY = VLF.CalculateDistanceXY
local ShouldExplodeNow = VLECB.ShouldExplodeNow
local SetNormalGameSpeed = VLF.SetNormalGameSpeed
local PlaySound_B52Appeared = VLECB.PlaySound_B52Appeared
local BroadCastAboutCarpetBombing = VLECB.BroadCastAboutCarpetBombing
local RemoveDataBombs = VLECB.RemoveDataBombs
local UpdateDataBombsToPlan = VLECB.UpdateDataBombsToPlan
local ClearDataCarpetBombingEvent = VLECB.ClearDataCarpetBombingEvent
local RegisterCarpetBombingEvent = VLECB.RegisterCarpetBombingEvent
local HelicopterBombWarning = VLECB.HelicopterBombWarning

local displayCarpetBombingPlan = VLECB.displayCarpetBombingPlan
local needHoursToStartCBEvent = VLECB.needHoursToStartCBEvent
local notSpam = {}

local function GetHighestFloorSquare(x, y)
	for z = 29, 0, -1 do
		local sq = getCell():getGridSquare(x, y, z)
		if sq and sq:getFloor() then
			return sq
		end
	end
	return nil
end

local pTick = 1

local function OnPlayerUpdate_ECB(player)
	if not player then return end
	 
	if pTick % 30 == 0 then
		--Kiểm tra world đã tồn tại ít nhất 7 ngày
		if HasTimePassedInHours(needHoursToStartCBEvent) ~= true then return end
		
		--Hiển thị tất cả Bombing Plan đã nghe được tin tức
		for bombPlanCode, func in pairs(displayCarpetBombingPlan) do				
			func(player, bombPlanCode)
		end
		
		--Kiểm tra vị trí nổ bomb để yêu cầu server nổ bomb
		local questMD_Events_CarpetBombing = GetModDataCarpetBombingEvent()
		for bombPlanCode, data in pairs(questMD_Events_CarpetBombing["Plan"]) do
			--Nếu đang ở trong khoảng cách Check của area
			local px, py = player:getX(), player:getY()
			local distToAreaCentre = CaldistanceCoordinates(player:getX(), player:getY(), data.x, data.y)

			if distToAreaCentre <= data.distAreaCheck then
				--Kiểm tra kế hoạch thả bomb đã có chưa
				local bombs = data.bombs
				if bombs and type(bombs) == "table" then
					--Kiểm tra các vị trí thả bomb có được load không
					local gameTime = getGameTime()
					local currentMinute = gameTime:getMinutesStamp()
					local bombs = data.bombs
					
					for bombID, _data in pairs(bombs) do
						local explodeMinute = _data.explodeMinute

						if currentMinute >= explodeMinute then
							local x, y = _data.x, _data.y
							local sq = getCell():getGridSquare(x, y, 0)
							if sq then
								--khoảng cách từ player đến điểm nổ
								local distXY = CalculateDistanceXY(x, y, px, py)
								if distXY and distXY <= 60 then
									local explodeNow = false
									
									--Kiểm tra sq có floor tầng cao nhất
									local hiSq = GetHighestFloorSquare(x, y)
									local _x, _y, _z = hiSq:getX(), hiSq:getY(), hiSq:getZ()
									
									if _x and _y and _z then
										--request để server send player explode animation cho tất cả client
										if ShouldExplodeNow(explodeMinute) == true then
											--Set game speed = 1 NẾU là SinglePlayer
											SetNormalGameSpeed()
											
											explodeNow = true
											sendClientCommand(player, "Event_CarpetBombing", "RequestPlayBombEffect", {x = _x, y = _y, z = _z})
										end
										
										--yêu cầu server nổ vị trí hiSq
										local var = tostring(currentMinute) .. tostring(_x) .. tostring(_y) .. tostring(_z)
										if not notSpam[var] then
											--print("Client---OnPlayerUpdate_ECB---Request Bomb---bombPlanCode, bombID, _x, _y, _z= ", bombPlanCode, bombID, _x, _y, _z)
											--print("------- getPlayer():teleportTo("..tostring(_x)..","..tostring(_y)..",0)")
											notSpam[var] = true
											sendClientCommand(player, "Event_CarpetBombing", "RequestExplode", {bombPlanCode = bombPlanCode, bombID = bombID, x = _x, y = _y, z = _z, explodeNow = explodeNow, activateStartHour = data.activateStartHour})
										end
									end
								end
							end
						end
					end
				end
			end
		end
	end
	pTick = pTick + 1
end
Events.OnPlayerUpdate.Remove(OnPlayerUpdate_ECB)
Events.OnPlayerUpdate.Add(OnPlayerUpdate_ECB)


local function RemoveExplodeAnimItems()
    local player = getPlayer()
    if not player then return end
    local cell = getCell()
    if not cell then return end

    local radius = 65  -- bán kính ô xung quanh player
    local px, py = player:getX(), player:getY()

    local removedCount = 0

    -- duyệt tất cả ô vuông trong bán kính
	for dz = 0, 29 do
		for dx = -radius, radius do
			for dy = -radius, radius do
				local sx = math.floor(px + dx)
				local sy = math.floor(py + dy)

				-- Lấy square đã load
				local square = cell:getGridSquare(sx, sy, dz)
				if square then
					local worldObjects = square:getWorldObjects()
					if worldObjects then
						for i = worldObjects:size() - 1, 0, -1 do
							local wo = worldObjects:get(i)
							if wo then
								local item = wo:getItem()
								if item then
									local fullType = item:getFullType()
									if fullType and string.find(fullType, "VL_Explode_Anim_512_") then
										square:removeWorldObject(wo)
										wo:removeFromSquare()
										
										removedCount = removedCount + 1
									end
								end
							end
						end
					end
				end
			end
		end
	end
    --print("[VLF][SP] Removed Explode items:", removedCount)
end

--Khi login, nếu có playerGMD.Data["knewCarpetBombings"][bombPlanCode] == true thì add lại VLECB.displayCarpetBombingPlan[bombPlanCode] = AddToCBQuestList
local function OnGameStart_GetAllFuncBombPlanCode()
	local playerGMD_Data_knewCarpetBombings = GetPlayerGMDCarpetBombing(getPlayer())

	for bombPlanCode, data in pairs(playerGMD_Data_knewCarpetBombings) do
		if type(data) == "table" then
			--Tạo function theo bombPlanCode để show trên Quest List
			displayCarpetBombingPlan[bombPlanCode] = AddToCBQuestList
			--print("Client---OnGameStart_GetAllFuncSupplyID---bombPlanCode= ", bombPlanCode)
		end
	end
	
	--Nếu bomb đang ném và player đứng trong khu vực ném thì play lại sound máy bay
	local questMD_Events_CarpetBombing = GetModDataCarpetBombingEvent()
	for bombPlanCode, data in pairs(questMD_Events_CarpetBombing["Plan"]) do
		if data and data["dropped"] == true then
			local player = getPlayer()
			if player then
				local px, py = player:getX(), player:getY()
				local distToAreaCentre = CaldistanceCoordinates(player:getX(), player:getY(), data.x, data.y)
				
				if distToAreaCentre <= data.distAreaCheck then
					PlaySound_B52Appeared(player, bombPlanCode)
				end
			end
		end
	end
	
	--Xóa animation items Base.VL_Explode_Anim_512_ khi không được xóa lúc logout	--Singplayer only, multi thì anim items không transmit nên không cần
	if not isClient() then	--SP
		RemoveExplodeAnimItems()	
	end
end
Events.OnGameStart.Remove(OnGameStart_GetAllFuncBombPlanCode)
Events.OnGameStart.Add(OnGameStart_GetAllFuncBombPlanCode)


--================= ONSERVERCOMMAND =================--
VLOSC["Event_CarpetBombing_C"] = VLOSC["Event_CarpetBombing_C"] or {}

VLOSC["Event_CarpetBombing_C"]["RegisterDataStartEvent_C"] = function(args)	--{areaID = areaID, bombPlanCode = bombPlanCode, x = x, y = y, activateStartHour = activateStartHour, bombDropAfterHours = bombDropAfterHours, distAreaCheck = distAreaCheck}
	RegisterCarpetBombingEvent(args.areaID, args.x, args.y, args.bombPlanCode, args.activateStartHour, args.bombDropAfterHours, args.distAreaCheck)
end

VLOSC["Event_CarpetBombing_C"]["ClearDataEvent_C"] = function(args)	--{bombPlanCode = bombPlanCode}
	ClearDataCarpetBombingEvent(args.bombPlanCode)
end

VLOSC["Event_CarpetBombing_C"]["UpdateBombsData_C"] = function(args)	--{bombPlanCode = bombPlanCode, bombCount = bombCount, bombs = bombs, weatherCondition = weatherCondition, endBombingMinute = endBombingMinute}
	UpdateDataBombsToPlan(args.bombPlanCode, args.bombCount, args.bombs, args.weatherCondition, args.endBombingMinute)
end

VLOSC["Event_CarpetBombing_C"]["RemoveDataBombs_C"] = function(args)	--{bombPlanCode = bombPlanCode, bombID = bombID}
	RemoveDataBombs(args.bombPlanCode, args.bombID)
end

VLOSC["Event_CarpetBombing_C"]["BroadCastBombingPlan_C"] = function(args)	--{bombPlanCode = bombPlanCode}
	BroadCastAboutCarpetBombing(getPlayer(), args.bombPlanCode)
end

VLOSC["Event_CarpetBombing_C"]["RequestPlayBombEffect_C"] = function(args)	--{x = _x, y = _y, z = _z}
	PlayBombEffect(args.x, args.y, args.z)
end

VLOSC["Event_CarpetBombing_C"]["PlaySound_B52Appeared_C"] = function(args)	--{bombPlanCode = bombPlanCode}
	PlaySound_B52Appeared(getPlayer(), args.bombPlanCode)
end

VLOSC["Event_CarpetBombing_C"]["HelicopterBombWarning_C"] = function(args)	--{bombPlanCode = bombPlanCode}
	HelicopterBombWarning(getPlayer(), args.bombPlanCode)
end

