local S = minetest.get_translator(minetest.get_current_modname())

---Poison Arrow Effects
---@param tick integer|number
---@param time integer|number
---@param time_left integer|number
---@param arrow_obj ObjectRef
---@param target_obj ObjectRef
---@param old_damage_texture_modifier string
---@param punch_def table
local function poison_effect(tick, time, time_left, arrow_obj, target_obj, old_damage_texture_modifier, punch_def)
    if not arrow_obj or target_obj:get_hp() <= 0 then
        return
    end

    target_obj:set_properties({ damage_texture_modifier = '^[colorize:#00FF0050' })

    time_left = time_left + tick

    if time_left <= time then
        minetest.after(
            tick,
            function(v_tick, v_time, v_time_left, v_arrow_obj, v_target_obj, v_old_damage_texture_modifier, v_punch_def)
                poison_effect(
                    v_tick,
                    v_time,
                    v_time_left,
                    v_arrow_obj,
                    v_target_obj,
                    v_old_damage_texture_modifier,
                    v_punch_def
                )
            end,
            tick,
            time,
            time_left,
            arrow_obj,
            target_obj,
            old_damage_texture_modifier,
            punch_def
        )
    elseif target_obj:is_player() then
        if minetest.get_modpath('hbhunger') then
            -- Reset HUD bar color
            hb.change_hudbar(target_obj, 'health', nil, nil, 'hudbars_icon_health.png', nil, 'hudbars_bar_health.png')
        end

        if old_damage_texture_modifier then
            target_obj:set_properties({ damage_texture_modifier = old_damage_texture_modifier })
        end

        -- return
    else
        -- local lua_ent = target_obj:get_luaentity()

        -- if not lua_ent then
        -- 	return
        -- end

        -- lua_ent[arrow_obj.arrow .. '_active'] = false


        if old_damage_texture_modifier then
            target_obj:set_properties({ damage_texture_modifier = old_damage_texture_modifier })
        end
        -- return
    end

    local _damage = punch_def.tool_capabilities.damage_groups.fleshy
    if target_obj:get_hp() - _damage > 0 then
        target_obj:punch(
            punch_def.puncher,
            punch_def.time_from_last_punch,
            punch_def.tool_capabilities
        )

        local target_obj_pos = target_obj:get_pos()

        if target_obj_pos then
            minetest.add_particlespawner({
                amount = 5,
                time = 1,
                minpos = vector.add(target_obj_pos, { x = -0.5, y = -0.5, z = -0.5 }),
                maxpos = vector.add(target_obj_pos, { x = 0.5, y = 0.5, z = 0.5 }),
                minexptime = 0.4,
                maxexptime = 0.8,
                minvel = { x = -0.4, y = 0.4, z = -0.4 },
                maxvel = { x = 0.4, y = 0.6, z = 0.4 },
                minacc = { x = 0.2, y = 0.4, z = 0.2 },
                maxacc = { x = 0.4, y = 0.6, z = 0.4 },
                minsize = 4,
                maxsize = 6,
                texture = 'x_bows_extras_arrow_tipped_particle.png^[colorize:#008000:127',
                animation = {
                    type = 'vertical_frames',
                    aspect_w = 8,
                    aspect_h = 8,
                    length = 1,
                },
                glow = 1
            })
        end
    end
end

local function on_hit_object(self, pointed_thing)
    -- already dead (player)
    if pointed_thing.ref:get_hp() <= 0 then
        if minetest.get_modpath('hbhunger') then
            -- Reset HUD bar color
            hb.change_hudbar(
                pointed_thing.ref,
                'health',
                nil,
                nil,
                'hudbars_icon_health.png',
                nil,
                'hudbars_bar_health.png'
            )
        end
        return
    end

    local _caused_damage = self._caused_damage
    local _caused_knockback = self._caused_knockback

    -- poison arrow
    local old_damage_texture_modifier = pointed_thing.ref:get_properties().damage_texture_modifier
    local punch_def = {}
    punch_def.puncher = self.object
    punch_def.time_from_last_punch = self._tflp
    punch_def.tool_capabilities = {
        full_punch_interval = self._tool_capabilities.full_punch_interval,
        damage_groups = { fleshy = _caused_damage, knockback = _caused_knockback }
    }

    if pointed_thing.ref:is_player() then
        -- @TODO missing `active` posion arrow check for player (see lua_ent below)
        if minetest.get_modpath('hbhunger') then
            -- Set poison bar
            hb.change_hudbar(
                pointed_thing.ref,
                'health',
                nil,
                nil,
                'hbhunger_icon_health_poison.png',
                nil,
                'hbhunger_bar_health_poison.png'
            )
        end

        poison_effect(1, 5, 0, self, pointed_thing.ref, old_damage_texture_modifier, punch_def)
    else
        -- local lua_ent = pointed_thing.ref:get_luaentity()
        -- if not lua_ent[self.arrow .. '_active'] or lua_ent[self.arrow .. '_active'] == 'false' then
        -- lua_ent[self.arrow .. '_active'] = true
        poison_effect(1, 5, 0, self, pointed_thing.ref, old_damage_texture_modifier, punch_def)
        -- end
    end
end

XBows:register_arrow('arrow_diamond_tipped_poison', {
    description = S('Arrow Diamond Tipped Poison (0:05)'),
    short_description = S('Arrow Diamond Tipped Poison'),
    inventory_image = 'x_bows_extras_arrow_diamond_poison.png',
    wield_image = 'x_bows_extras_arrow_diamond_poison.png',
    custom = {
        recipe = {
            { '', '', '' },
            { '', 'default:marram_grass_1', '' },
            { '', 'x_bows:arrow_diamond', '' }
        },
        tool_capabilities = {
            full_punch_interval = 0.7,
            max_drop_level = 1,
            damage_groups = { fleshy = 8 }
        },
        recipe_count = 1,
        mod_name = 'x_bows_extras',
        on_hit_player = function(self, pointed_thing)
            on_hit_object(self, pointed_thing)
        end,
        on_hit_entity = function(self, pointed_thing)
            on_hit_object(self, pointed_thing)
        end
    }
})
