-- womb.lua
-- LuaComponent on the player (execute_every_n_frame=0).
-- Digestive-Alchemy-style GuiCreate / GuiImage / GuiTooltip panel.
--
-- Phase 3: reads detailed parasite state (timers, type) and pregnancies,
-- displaying everything in the womb tooltip. Parasites and pregnancies
-- no longer have their own UIIconComponents.

dofile_once("mods/lewd_noita/files/womb/womb_utils.lua")

-----------------------------------------------------------------------------------------
-- CONSTANTS
-----------------------------------------------------------------------------------------
local CUM_MAX = 2000

local CUM_DISPLAY_NAMES = {
    ln_cum          = "Cum",
    ln_cum_potent   = "Potent Cum",
    ln_cum_toxic    = "Toxic Cum",
    ln_cum_lava     = "Lava Cum",
    ln_cum_cursed   = "Cursed Cum",
    fungi           = "Fungal Spores",
    ln_gas_horny    = "Aphrodisiac Gas",
    gold_molten     = "Molten Gold",
}

-- Material colors (R, G, B) for GUI display
local CUM_COLORS = {
    ["Cum"]              = { 0.90, 0.90, 0.95 },
    ["Potent Cum"]       = { 1.00, 0.65, 0.80 },
    ["Toxic Cum"]        = { 0.40, 0.90, 0.20 },
    ["Lava Cum"]         = { 1.00, 0.40, 0.10 },
    ["Cursed Cum"]       = { 0.70, 0.30, 0.90 },
    ["Fungal Spores"]    = { 0.30, 0.80, 0.55 },
    ["Aphrodisiac Gas"]  = { 1.00, 0.45, 0.65 },
    ["Molten Gold"]      = { 1.00, 0.85, 0.15 },
}

-- Parasite metadata: display name, type ("spawner" has timer, "effect" is always-on)
local PARASITE_META = {
    parasite_firebug        = { name = "Tulikärpänen Brood",    kind = "spawner" },
    parasite_fly            = { name = "Lennokki Swarm", kind = "spawner" },
    parasite_spider         = { name = "Hämähäkki Brood",       kind = "spawner" },
    parasite_rat            = { name = "Rotta Infestation",     kind = "spawner" },
    parasite_ant            = { name = "Murkku Colony",         kind = "spawner" },
    parasite_longleg        = { name = "Hämis Brood",          kind = "spawner" },
    parasite_fungus         = { name = "Sieni Infection",       kind = "effect"  },
    parasite_hornygasflower = { name = "Kukinta Infection",     kind = "effect"  },
}

-- In-game display names keyed by entity filename stem
local PREGNANCY_NAMES = {
    -- Vanilla enemies (Finnish in-game names)
    ["acidshooter"]      = "Happonuljaska",
    ["ant"]              = "Murkku",
    ["bat"]              = "Lepakko",
    ["bigfirebug"]       = "Iso Tulikärpänen",
    ["blob"]             = "Lima",
    ["chest_mimic"]      = "Arkku",
    ["firebug"]          = "Tulikärpänen",
    ["fly"]              = "Lennokki",
    ["flyswarm"]         = "Lennokkiparvi",
    ["frog"]             = "Sammakko",
    ["fungus"]           = "Sieni",
    ["ghoul"]            = "Märkiäinen",
    ["giantsnail"]       = "Jättiläisetana",
    ["longleg"]          = "Hämis",
    ["longleg_double"]   = "Hämis",
    ["maggot_1"]         = "Valkoinen toukka",
    ["maggot_2"]         = "Tulikärpäsen Toukka",
    ["maggot_3"]         = "Kulta tulikärpänen toukka",
    ["maggot_4"]         = "Hämähäkin Toukka",
    ["phantom_a"]        = "Kummitus",
    ["phantom_b"]        = "Kummitus",
    ["rat"]              = "Rotta",
    ["rat_alt"]          = "Rotta",
    ["rat_alt_double"]   = "Rotta",
    ["rat_double"]       = "Rotta",
    ["shooterflower"]    = "Ampujakukka",
    ["skullrat"]         = "Kalliorotta",
    ["slimeshooter"]     = "Limanuljaska",
    ["tentacler"]        = "Tentaakkeli",
    ["tentacler_small"]  = "Pieni Tentaakkeli",
    ["worm_tiny_head"]   = "Liero",
    -- Mod custom enemies
    ["hellhound"]        = "Helvetinkoira",
    ["hornygasflower"]   = "Kukinta",
    ["webspider"]        = "Hämähäkki",
    ["wolf_cyber"]       = "Kybersusi",
}

local ICON_PATH = "mods/lewd_noita/files/status_effects/leak_cum.png"
local GUI_X = 600
local GUI_Y = 214

-----------------------------------------------------------------------------------------
-- SETUP
-----------------------------------------------------------------------------------------
local entity = GetUpdatedEntityID()  -- the player
local frame  = GameGetFrameNum()

-----------------------------------------------------------------------------------------
-- SETTINGS
-----------------------------------------------------------------------------------------
local extreme_enabled  = ModSettingGet("lewd_noita.extreme_content_enabled")
if extreme_enabled == nil then extreme_enabled = true end

-----------------------------------------------------------------------------------------
-- GATHER: cum from womb MIC
-----------------------------------------------------------------------------------------
local cum_entries = {}
local cum_total   = 0

local womb = getWombEntity(entity)
if womb ~= nil then
    local materials = getWombMaterialsList(womb)
    for _, entry in ipairs(materials) do
        local mat_name = entry[1]
        local amount   = entry[2]
        if amount > 0 then
            local display = CUM_DISPLAY_NAMES[mat_name] or mat_name
            table.insert(cum_entries, { display, amount })
            cum_total = cum_total + amount
        end
    end
end

-----------------------------------------------------------------------------------------
-- GATHER: pregnancies  (children named "ln_pregnancy" or "effect_pregnancy")
-----------------------------------------------------------------------------------------
local pregnancies = {}

for _, child in ipairs(EntityGetAllChildren(entity) or {}) do
    if EntityGetName(child) == "ln_pregnancy" or EntityGetName(child) == "effect_pregnancy" then
        local vsc = EntityGetFirstComponent(child, "VariableStorageComponent")
        if vsc ~= nil then
            local enemy_file    = ComponentGetValue2(vsc, "value_string") or "unknown"
            local creation_frame = tonumber(ComponentGetValue2(vsc, "value_int")) or 0

            local short = enemy_file:match("([^/]+)%.xml$") or enemy_file
            local display = PREGNANCY_NAMES[short] or short

            -- Read birth timer from LuaComponent execute_every_n_frame
            local lua_comp = EntityGetFirstComponent(child, "LuaComponent")
            local is_ready = (lua_comp == nil)
            local remaining_sec = 0
            local elapsed_sec = 0

            if lua_comp ~= nil and creation_frame > 0 then
                local total_dur = tonumber(ComponentGetValue2(lua_comp, "execute_every_n_frame")) or 0
                if total_dur > 0 then
                    local elapsed_frames = frame - creation_frame
                    elapsed_sec = math.floor(elapsed_frames / 60)
                    local remaining_frames = math.max(0, total_dur - elapsed_frames)
                    remaining_sec = math.ceil(remaining_frames / 60)
                    is_ready = remaining_frames <= 0
                end
            end

            table.insert(pregnancies, { display, elapsed_sec, remaining_sec, is_ready })
        end
    end
end

-----------------------------------------------------------------------------------------
-- GATHER: parasites  (children named "parasite_*")
-----------------------------------------------------------------------------------------
dofile_once("mods/lewd_noita/files/status_effects/parasite_utils.lua")
local parasites = {}  -- { {display_name, status_string}, ... }

for _, child in ipairs(EntityGetAllChildren(entity) or {}) do
    local cname = EntityGetName(child) or ""
    if cname:sub(1, 9) == "parasite_" then
        local meta = PARASITE_META[cname]
        local stage = get_parasite_stage(child)
        local stage_str = " " .. get_stage_label(stage)

        if meta == nil then
            table.insert(parasites, { cname .. stage_str, "Active" })
        elseif meta.kind == "effect" then
            table.insert(parasites, { meta.name .. stage_str, "Active" })
        elseif meta.kind == "spawner" then
            -- Read the timer VSC to show seconds until next spawn
            local vsc = get_parasite_timer_vsc(child)
            local status = "Gestating"
            if vsc ~= nil then
                local last_spawn    = tonumber(ComponentGetValue2(vsc, "value_string")) or 0
                local next_interval = tonumber(ComponentGetValue2(vsc, "value_int")) or 0
                if next_interval > 0 and last_spawn > 0 then
                    local remaining_frames = (last_spawn + next_interval) - frame
                    if remaining_frames > 0 then
                        local remaining_sec = math.ceil(remaining_frames / 60)
                        status = remaining_sec .. "s"
                    else
                        status = "Imminent"
                    end
                end
            end
            table.insert(parasites, { meta.name .. stage_str, status })
        end
    end
end

-----------------------------------------------------------------------------------------
-- FILL PERCENTAGE  &  FULLNESS STAGE
-----------------------------------------------------------------------------------------
local pct        = 0
local womb_stage = 0
local overfilled = false
if cum_total > 0 then
    pct        = math.floor((cum_total / CUM_MAX) * 100 + 0.5)
    womb_stage = getWombStage(cum_total)
    overfilled = isWombOverfilled(cum_total)
end

-----------------------------------------------------------------------------------------
-- BUILD DISPLAY DATA
-----------------------------------------------------------------------------------------
local body_knowledge = GameHasFlagRun("PERK_PICKED_LN_BODY_KNOWLEDGE")

-- Title + subtitle
local title_text = "WOMB"
local subtitle_text = ""
local stage_text = ""

if #cum_entries > 0 then
    local stage_labels = { [0]="Empty", [1]="Barely full", [2]="Filling up", [3]="Full",
                            [4]="Very full", [5]="Sickly full", [6]="Dangerously full" }
    stage_text = (stage_labels[womb_stage] or "Full")
    if overfilled then stage_text = "OVERFILLED" end
    -- Exact pct only with perk; without perk show stage label alone
    if body_knowledge then
        stage_text = stage_text .. " (" .. pct .. "%)"
    end

    subtitle_text = getWombFullnessDescription(cum_total)
end

-- Column data: { {text, r, g, b}, ... }
local col_contents = { {text="CONTENTS", r=0.75, g=0.75, b=0.75} }
local col_preg     = { {text="PREGNANCIES", r=0.75, g=0.75, b=0.75} }
local col_para     = { {text="INFESTATIONS", r=0.75, g=0.75, b=0.75} }

-- Contents column
if #cum_entries > 0 then
    for _, entry in ipairs(cum_entries) do
        local c = CUM_COLORS[entry[1]] or { 0.90, 0.90, 0.90 }
        local label
        if body_knowledge then
            label = entry[1] .. " (" .. entry[2] .. "ml)"
        else
            -- Vague: qualitative descriptor only
            local amt = entry[2]
            local qual = amt < 50 and "traces of" or amt < 200 and "some" or amt < 400 and "a fair amount of" or "a lot of"
            label = qual .. " " .. entry[1]:lower()
        end
        table.insert(col_contents, { text=label, r=c[1], g=c[2], b=c[3] })
    end
else
    table.insert(col_contents, {text="(empty)", r=0.5, g=0.5, b=0.5})
end

-- Pregnancy column
if #pregnancies > 0 then
    for _, p in ipairs(pregnancies) do
        local label
        local color_r, color_g, color_b = 0.95, 0.75, 0.65
        if body_knowledge then
            if p[4] then  -- is_ready
                label = p[1] .. " [ready!]"
                color_r, color_g, color_b = 1.0, 0.4, 0.4
            else
                label = p[1] .. " [in " .. p[3] .. "s]"
            end
        else
            if p[4] then
                label = p[1] .. " [imminent]"
                color_r, color_g, color_b = 1.0, 0.4, 0.4
            else
                label = p[1] .. " [gestating]"
            end
        end
        table.insert(col_preg, {text=label, r=color_r, g=color_g, b=color_b})
    end
else
    table.insert(col_preg, {text="(none)", r=0.5, g=0.5, b=0.5})
end

-- Parasite column
if #parasites > 0 then
    for _, p in ipairs(parasites) do
        local color_r, color_g, color_b = 0.85, 0.35, 0.35
        local label
        if p[2] == "Active" then
            color_r, color_g, color_b = 0.90, 0.55, 0.25
            label = p[1] .. " [Active]"
        elseif p[2] == "Imminent" then
            color_r, color_g, color_b = 1.00, 0.25, 0.25
            label = p[1] .. " [Imminent]"
        else
            -- spawner with timer
            if body_knowledge then
                label = p[1] .. " [" .. p[2] .. "]"
            else
                label = p[1] .. " [brewing...]"
            end
        end
        table.insert(col_para, {text=label, r=color_r, g=color_g, b=color_b})
    end
else
    table.insert(col_para, {text="(none)", r=0.5, g=0.5, b=0.5})
end

-----------------------------------------------------------------------------------------
-- DRAW GUI
-----------------------------------------------------------------------------------------
womb_gui = womb_gui or GuiCreate()
GuiStartFrame(womb_gui)

if cum_total > 0 or #pregnancies > 0 or #parasites > 0 then
    -- Status icon + percentage
    GuiImage(womb_gui, 3, GUI_X, GUI_Y, ICON_PATH, 1, 1, 1, 0, 0, "")

    local pct_text   = pct .. "%      "
    local pct_offset = GuiGetTextDimensions(womb_gui, pct_text, 1, 2)
    GuiText(womb_gui, GUI_X + 20 - pct_offset, GUI_Y, pct_text)

    -- Detect hover on icon area for custom panel
    local _, _, hovered = GuiGetPreviousWidgetInfo(womb_gui)

    if hovered then
        local col_w   = 130          -- column width — widened to prevent overflow
        local row_h   = 11
        local pad     = 8

        -- With extreme content disabled, parasites are off — drop the
        -- infestations column instead of leaving a large empty gap; cum
        -- contents and pregnancies still apply regardless of this setting.
        local columns = extreme_enabled and { col_contents, col_preg, col_para } or { col_contents, col_preg }
        local num_cols = #columns
        local max_rows = 0
        for _, col in ipairs(columns) do
            if #col > max_rows then max_rows = #col end
        end

        -- Header area: title + stage + description (word-wrapped)
        local header_lines = 1  -- title
        if stage_text ~= "" then header_lines = header_lines + 1 end

        -- Word-wrap subtitle to panel width (narrower when infestations column hidden)
        local subtitle_lines = {}
        if subtitle_text ~= "" then
            local max_chars = (num_cols >= 3) and 55 or 38
            local remaining = subtitle_text
            while #remaining > 0 do
                if #remaining <= max_chars then
                    table.insert(subtitle_lines, remaining)
                    remaining = ""
                else
                    local cut = max_chars
                    while cut > 1 and remaining:sub(cut, cut) ~= " " do cut = cut - 1 end
                    if cut <= 1 then cut = max_chars end
                    table.insert(subtitle_lines, remaining:sub(1, cut))
                    remaining = remaining:sub(cut + 1)
                end
            end
        end

        local header_h   = (header_lines + #subtitle_lines) * row_h + 6
        local panel_w    = (col_w * num_cols) + (pad * 2) + 10
        local panel_h    = header_h + (max_rows * row_h) + (pad * 2) + 4

        local screen_w, screen_h = GuiGetScreenDimensions(womb_gui)
        local panel_x = math.floor((screen_w - panel_w) * 0.5)
        local panel_y = math.floor((screen_h - panel_h) * 0.5)

        -- Background panel (z behind text)
        local wid = 1000
        GuiZSetForNextWidget(womb_gui, 10)
        GuiImageNinePiece(womb_gui, wid, panel_x, panel_y, panel_w, panel_h, 1,
            "data/ui_gfx/decorations/9piece0_gray.png",
            "data/ui_gfx/decorations/9piece0_gray.png")
        wid = wid + 1

        -- Title: "WOMB" centered
        local title_w = GuiGetTextDimensions(womb_gui, title_text, 1, 2)
        GuiColorSetForNextWidget(womb_gui, 0.85, 0.75, 0.55, 1.0)
        GuiZSetForNextWidget(womb_gui, 1)
        GuiText(womb_gui, panel_x + (panel_w - title_w) * 0.5, panel_y + pad, title_text)

        -- Stage text centered below title
        local cur_y = panel_y + pad + row_h
        if stage_text ~= "" then
            local stage_w = GuiGetTextDimensions(womb_gui, stage_text, 1, 2)
            local sr, sg, sb = 0.9, 0.9, 0.9
            if overfilled then sr, sg, sb = 1.0, 0.2, 0.2
            elseif womb_stage >= 5 then sr, sg, sb = 1.0, 0.5, 0.3
            elseif womb_stage >= 4 then sr, sg, sb = 1.0, 0.75, 0.4 end
            GuiColorSetForNextWidget(womb_gui, sr, sg, sb, 1.0)
            GuiZSetForNextWidget(womb_gui, 1)
            GuiText(womb_gui, panel_x + (panel_w - stage_w) * 0.5, cur_y, stage_text)
            cur_y = cur_y + row_h
        end

        -- Subtitle / description lines centered
        for _, line in ipairs(subtitle_lines) do
            local lw = GuiGetTextDimensions(womb_gui, line, 1, 2)
            GuiColorSetForNextWidget(womb_gui, 0.60, 0.60, 0.60, 1.0)
            GuiZSetForNextWidget(womb_gui, 1)
            GuiText(womb_gui, panel_x + (panel_w - lw) * 0.5, cur_y, line)
            cur_y = cur_y + row_h
        end

        cur_y = cur_y + 6  -- gap before columns

        -- Column rendering
        local col_starts = {}
        for ci = 1, num_cols do
            col_starts[ci] = panel_x + pad + (col_w + 5) * (ci - 1)
        end

        for ci, col in ipairs(columns) do
            local cx = col_starts[ci]
            for ri, entry in ipairs(col) do
                local ry = cur_y + ((ri - 1) * row_h)
                GuiColorSetForNextWidget(womb_gui, entry.r, entry.g, entry.b, 1.0)
                GuiZSetForNextWidget(womb_gui, 1)
                GuiText(womb_gui, cx, ry, entry.text)
            end
        end
    end
end

-- Body Knowledge perk descriptions (exact number display)
local function format_pregnancy(name, elapsed, remaining, is_ready)
    if is_ready then
        return name .. " [READY]"
    else
        return name .. " [" .. remaining .. "s]"
    end
end
