local LT = require("LOVELyTree") ---@module "LOVElyTree"

local function CustomWaitAction(duration)
    local action = {}
    action.timer = 0
    action.name = "WaitAction (" .. duration .. "s)"

    function action:update(dt)
        self.timer = self.timer + dt
        return (self.timer >= duration) and LT.RESULT.SUCCESS or LT.RESULT.RUNNING
    end

    function action:reset()
        self.timer = 0
    end

    return action
end

local WaitActionWrapped = LT.WrapAction(CustomWaitAction)

local function CustomSuccessAction()
    local action = {}
    action.name = "CustomSuccessAction"
    function action:update(dt)
        self.status = LT.RESULT.SUCCESS
        return self.status
    end

    return action
end

local function CustomFailAction()
    local action = {}
    action.name = "CustomFailAction"
    function action:update(dt)
        self.status = LT.RESULT.FAILURE
        return self.status
    end

    return action
end

local CustomSuccessWrapped = LT.WrapAction(CustomSuccessAction)
local CustomFailWrapped = LT.WrapAction(CustomFailAction)

local function advanced_tree()
    local branch1 = LT.Compositors.Sequence({
        LT.Decorators.Retry(WaitActionWrapped(1.5), 2),
        LT.Decorators.Invert(CustomFailWrapped()),
        LT.Decorators.AlwaysSuccess(WaitActionWrapped(1))
    })

    local branch2 = LT.Compositors.ParallelSelector({
        LT.Compositors.RandomOnce({
            CustomSuccessWrapped(),
            LT.Decorators.AlwaysFail(WaitActionWrapped(2))
        }),
        LT.Decorators.TimeLimit(CustomFailWrapped(), 1.5)
    })

    local branch3 = LT.Decorators.AlwaysFail(LT.Compositors.ParallelSelector({
        branch1,
        branch2,
        LT.Decorators.UntilSuccess(CustomSuccessWrapped())
    }))

    local root = LT.Compositors.Selector({ branch3, LT.Actions.Wait(2) })
    return LT.BehaviorTree(root)
end

return advanced_tree
