local easing = require "lib.utils.easing"
--- @class ShadowcasterBehavior : Behavior
local behavior = {}
behavior.id = "shadowcaster"
behavior.__index = behavior

function behavior.new() return setmetatable({}, behavior) end

function behavior:draw()
    local sprite = self.owner:has(Tree.behaviors.sprite)
    local positioned = self.owner:has(Tree.behaviors.positioned)
    if not positioned then return end
    if not sprite then return end

    local ppm = Tree.level.camera.pixelsPerMeter
    local position = positioned.position + Vec3 { 0.5, 0.5 }

    local lightIds = Tree.level.lightGrid:query(position, 5)
    --- @type Character[]
    local lights = {}
    for _, id in ipairs(lightIds) do
        table.insert(lights, Tree.level.characters[id])
    end

    -- 1. Эллипс тени
    Tree.level.render:enqueue(Tree.level.render.LAYERS.SHADOW, position.y, function()
        love.graphics.push()
        love.graphics.setColor(0, 0, 0, 1)
        love.graphics.translate(position.x, position.y)
        love.graphics.ellipse("fill", 0, 0, sprite.manifest.size / 2, sprite.manifest.size / 2 * math.cos(math.pi / 4))
        love.graphics.pop()
    end)

    -- 2. Свет на спрайте
    if #lights > 0 then
        Tree.level.render:enqueue(Tree.level.render.LAYERS.SPRITE_LIGHT, position.y, function()
            love.graphics.setBlendMode("add")
            for _, light in ipairs(lights) do
                local lightPos = light:has(Tree.behaviors.positioned).position
                local lightVec = lightPos - position

                local lightColor = light:has(Tree.behaviors.light).color
                if lightPos.y > position.y then
                    love.graphics.setColor(lightColor.x, lightColor.y, lightColor.z,
                        1 - 0.3 * lightVec:length())
                elseif position.y - lightPos.y < 3 then
                    love.graphics.setColor(lightColor.x, lightColor.y, lightColor.z,
                        (1 - easing.easeInSine((position.y - lightPos.y))) - 0.3 * lightVec:length())
                end

                sprite.animationTable[sprite.state]:draw(sprite.sheets[sprite.state],
                    position.x,
                    position.y, nil, 1 / ppm * sprite.side, 1 / ppm, sprite.manifest.base.x, sprite.manifest.base.y)
            end
            love.graphics.setBlendMode("alpha")
            love.graphics.setColor(1, 1, 1)
        end)
    end
end

return behavior
