local _, ns = ...

local MAX_REASONABLE_COOLDOWN_SECONDS = 60 * 60 * 24 * 35

local ProfessionCooldowns = ns.ProfessionCooldowns or {}
ns.ProfessionCooldowns = ProfessionCooldowns

local function plainNumber(value)
    local numberValue = tonumber(value)
    if not numberValue then
        return nil
    end

    return numberValue
end

local function parseRecipeCooldown(recipeID)
    recipeID = tonumber(recipeID)
    if not recipeID then
        return nil
    end

    local now = time()
    local remainingSeconds
    local durationSeconds
    local currentCharges
    local maxCharges
    local isDayCooldown = false

    if C_TradeSkillUI and type(C_TradeSkillUI.GetRecipeCooldown) == "function" then
        local ok, cooldownSeconds, dayCooldown, apiCurrentCharges, apiMaxCharges = pcall(C_TradeSkillUI.GetRecipeCooldown, recipeID)
        if ok then
            remainingSeconds = plainNumber(cooldownSeconds)
            isDayCooldown = dayCooldown == true
            currentCharges = plainNumber(apiCurrentCharges)
            maxCharges = plainNumber(apiMaxCharges)
        end
    end

    if C_Spell and type(C_Spell.GetSpellCharges) == "function" then
        local ok, chargeInfo = pcall(C_Spell.GetSpellCharges, recipeID)
        if ok and type(chargeInfo) == "table" then
            currentCharges = currentCharges or plainNumber(chargeInfo.currentCharges)
            maxCharges = maxCharges or plainNumber(chargeInfo.maxCharges)

            local chargeStart = plainNumber(chargeInfo.cooldownStartTime or chargeInfo.startTime)
            local chargeDuration = plainNumber(chargeInfo.cooldownDuration or chargeInfo.duration)
            if chargeStart and chargeDuration and chargeDuration > 0 then
                durationSeconds = durationSeconds or chargeDuration
                local chargeRemaining = math.max(0, (chargeStart + chargeDuration) - now)
                if chargeRemaining > 0 then
                    remainingSeconds = math.max(plainNumber(remainingSeconds) or 0, chargeRemaining)
                end
            end
        end
    end

    if C_Spell and type(C_Spell.GetSpellCooldown) == "function" then
        local ok, spellCooldown = pcall(C_Spell.GetSpellCooldown, recipeID)
        if ok and type(spellCooldown) == "table" then
            local cooldownStart = plainNumber(spellCooldown.startTime or spellCooldown.cooldownStartTime)
            local cooldownDuration = plainNumber(spellCooldown.duration or spellCooldown.cooldownDuration)
            if cooldownStart and cooldownDuration and cooldownDuration > 0 then
                durationSeconds = durationSeconds or cooldownDuration
                local spellRemaining = math.max(0, (cooldownStart + cooldownDuration) - now)
                if spellRemaining > 0 then
                    remainingSeconds = math.max(plainNumber(remainingSeconds) or 0, spellRemaining)
                end
            end
        end
    end

    remainingSeconds = math.max(0, plainNumber(remainingSeconds) or 0)
    if remainingSeconds > MAX_REASONABLE_COOLDOWN_SECONDS then
        remainingSeconds = 0
    end

    durationSeconds = math.max(0, plainNumber(durationSeconds) or remainingSeconds or 0)
    if durationSeconds > MAX_REASONABLE_COOLDOWN_SECONDS then
        durationSeconds = 0
    end

    maxCharges = maxCharges and math.max(0, math.floor(maxCharges + 0.5)) or nil
    currentCharges = currentCharges and math.max(0, math.floor(currentCharges + 0.5)) or nil
    if maxCharges and maxCharges <= 0 then
        maxCharges = nil
    end
    if currentCharges and maxCharges and currentCharges > maxCharges then
        currentCharges = maxCharges
    end
    if maxCharges and not currentCharges then
        currentCharges = remainingSeconds > 0 and math.max(0, maxCharges - 1) or maxCharges
    end

    local hasCooldownCapability = isDayCooldown == true or (maxCharges and maxCharges > 0) or remainingSeconds > 0
    local readyTime = remainingSeconds > 0 and (now + remainingSeconds) or 0
    local startTime = 0
    if readyTime > 0 and durationSeconds > 0 then
        startTime = math.max(0, readyTime - durationSeconds)
    elseif readyTime > 0 then
        startTime = now
    end

    return {
        hasCooldownCapability = hasCooldownCapability,
        remainingSeconds = remainingSeconds,
        durationSeconds = durationSeconds,
        currentCharges = currentCharges,
        maxCharges = maxCharges,
        isDayCooldown = isDayCooldown,
        startTime = startTime,
        readyTime = readyTime,
    }
end

ProfessionCooldowns.ParseRecipeCooldown = parseRecipeCooldown
