-- @author DoomTero 2026
-- @copyright 2026 DoomTero - ZomboRut original work. ref:1bc151e6
-- @license Proprietary. Not licensed for reuse, redistribution or derivative works without written permission from DoomTero. Ask - permission is obtainable. See ZomboRut/LICENSE.txt

require "ISUI/ISUIElement"

ZR_StruggleUI = ZR_StruggleUI or {}

local DEBUG = true
local function log(fmt, ...)
	if DEBUG then DebugLog.log("[ZR StruggleUI] " .. string.format(fmt, ...)) end
end

local PANEL_W = 230
local PANEL_H = 96

local FEET_OFFSET_Y = 192

local Panel = ISUIElement:derive("ZRStrugglePanel")

function Panel:box(x, y, w, h, a, r, g, b)
	if w <= 0 or h <= 0 then return end
	self:drawRect(x, y, w, h, a or 1, r or 1, g or 1, b or 1)
end

function Panel:text(str, x, y, r, g, b, a, centred, font)
	if not str then return end
	font = font or UIFont.Small
	local dx = x
	if centred then
		local ok, w = pcall(function()
			return getTextManager():MeasureStringX(font, str)
		end)
		if ok and w then dx = x - w * 0.5 end
	end
	self:drawText(str, dx, y, r or 1, g or 1, b or 1, a or 1, font)
end

function Panel:prerender()
	local x = getPlayerScreenLeft(0) + (getPlayerScreenWidth(0) - PANEL_W) * 0.5
	local y = getPlayerScreenTop(0) + getPlayerScreenHeight(0) * 0.5 + FEET_OFFSET_Y
	if x ~= self:getX() then self:setX(x) end
	if y ~= self:getY() then self:setY(y) end
end

function Panel:render()
	local run = self.run
	if not run then return end

	self.panelW = PANEL_W
	self.panelH = PANEL_H

	local mode = run.mode
	local pipN = run.stageCount or 1

	local pw, pg = 14, 5
	local ptot = pipN * pw + (pipN - 1) * pg
	for i = 1, pipN do
		local done = i < run.stageIdx
		local cur  = i == run.stageIdx
		local a    = done and 0.95 or (cur and 0.7 or 0.25)
		local r, g, b = 1, 1, 1
		if done then r, g, b = 0.35, 0.95, 0.45 end
		self:box((PANEL_W - ptot) * 0.5 + (i - 1) * (pw + pg), PANEL_H - 10,
		         pw, 4, a, r, g, b)
	end

	if run.leadIn then
		if mode and mode.hint then
			self:box(0, 22, PANEL_W, 40, 0.5, 0, 0, 0)
			self:text(mode.hint, PANEL_W * 0.5, 30, 1, 1, 1, 0.95, true)
		end
		local span = run.leadInMs or 900
		local left = math.max(0, (run.gapUntil or 0) - run.nowMs)
		self:box((PANEL_W - 120) * 0.5, 68, 120 * (1 - left / span), 4,
		         0.9, 1, 0.85, 0.3)
		return
	end

	if run.gapUntil then return end

	if mode and mode.draw then
		local sd = mode.stages[run.stageIdx]
		if sd then pcall(mode.draw, self, run, sd) end
	end

	if run.result then
		local win = run.result == "win"
		self:box((PANEL_W - ptot) * 0.5, PANEL_H - 4, ptot, 3, 0.85,
		         win and 0.35 or 0.95, win and 0.95 or 0.3, win and 0.45 or 0.28)
	end
end

local panel = nil

local function ensurePanel()
	if panel then return panel end
	local o = ISUIElement:new(0, 0, PANEL_W, PANEL_H)
	setmetatable(o, Panel)
	Panel.__index = Panel
	o.backgroundColor = { r = 0, g = 0, b = 0, a = 0 }
	o.borderColor     = { r = 0, g = 0, b = 0, a = 0 }
	o:initialise()
	o.keepOnScreen = false
	o.panelW = PANEL_W
	o.panelH = PANEL_H
	panel = o
	return panel
end

function ZR_StruggleUI.show(run)
	local p = ensurePanel()
	p.run = run
	if not p.shown then
		p:addToUIManager()
		p.shown = true
		log("shown (mode=%s)", tostring(run and run.mode and run.mode.name))
	end
end

function ZR_StruggleUI.hide()
	if panel and panel.shown then
		pcall(function() panel:removeFromUIManager() end)
		panel.shown = false
		panel.run = nil
		log("hidden")
	end
end

Events.OnPlayerDeath.Add(function()
	ZR_StruggleUI.hide()
end)

return ZR_StruggleUI
