HuntingRifle = {}

function HuntingRifle.registerXMLPaths(xmlSchema)
    xmlSchema:setXMLSpecializationType("HuntingRifle")
    xmlSchema:register(XMLValueType.NODE_INDEX, "handTool.huntingRifle#raycastNode", "A sugár kiindulási pontja", "0|0")
    xmlSchema:register(XMLValueType.FLOAT, "handTool.huntingRifle#distance", "Lőtávolság", 300.0) 
    SoundManager.registerSampleXMLPaths(xmlSchema, "handTool.huntingRifle.sounds", "kill")
    xmlSchema:setXMLSpecializationType()
end

function HuntingRifle.prerequisitesPresent(specializations)
    return true
end

function HuntingRifle.registerEventListeners(vehicleType)
    SpecializationUtil.registerEventListener(vehicleType, "onLoad", HuntingRifle)
    SpecializationUtil.registerEventListener(vehicleType, "onDelete", HuntingRifle)
    SpecializationUtil.registerEventListener(vehicleType, "onUpdate", HuntingRifle)
    SpecializationUtil.registerEventListener(vehicleType, "onDraw", HuntingRifle)
    SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", HuntingRifle)
end

function HuntingRifle.registerFunctions(vehicleType)
    SpecializationUtil.registerFunction(vehicleType, "onShootInput", HuntingRifle.onShootInput)
    SpecializationUtil.registerFunction(vehicleType, "raycastCallback", HuntingRifle.raycastCallback)
end

-- === 1. BETÖLTÉS ÉS HANGOK ===
function HuntingRifle:onLoad(xmlFile)
    self.spec_huntingRifle = {}
    local spec = self.spec_huntingRifle

    spec.raycastNode = xmlFile:getValue("handTool.huntingRifle#raycastNode", "0|0", self.components, self.i3dMappings)
    spec.distance = xmlFile:getValue("handTool.huntingRifle#distance", 300.0)
    
    if self.isClient then
        spec.killSample = g_soundManager:loadSampleFromXML(xmlFile, "handTool.huntingRifle.sounds", "kill", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self)
        
        if spec.killSample ~= nil then
            spec.killSample.loops = 1
            spec.killSample.loopCount = 1
        end
    end

    spec.targetNodeId = 0
    spec.animalNameHU = ""
    spec.animalTypeId = "" 
    spec.animalReward = 0  
    spec.isTargetValid = false
    
    spec.lastShotTime = 0
    spec.cooldown = 1000 
end

function HuntingRifle:onDelete()
    local spec = self.spec_huntingRifle
    if spec.killSample ~= nil then
        g_soundManager:deleteSample(spec.killSample)
    end
end

-- === 2. LÖVÉS GOMB KEZELÉSE ÉS KLIENS OLDALI ELTÜNTETÉS ===
function HuntingRifle:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
    if self:getIsActiveForInput(true) then
        g_inputBinding:removeActionEventsByTarget(self)
        self.actionEvents = {} 
        local _, eventId = self:addActionEvent(InputAction.ACTIVATE_HANDTOOL, self, HuntingRifle.onShootInput, true, true, false, true)
        g_inputBinding:setActionEventTextPriority(eventId, GS_PRIO_VERY_HIGH)
        g_inputBinding:setActionEventText(eventId, "Lövés")
    end
end

function HuntingRifle:onShootInput(actionName, inputValue)
    if inputValue > 0 then
        local spec = self.spec_huntingRifle
        local currentTime = g_currentMission.time
        
        if currentTime > (spec.lastShotTime + spec.cooldown) then
            spec.lastShotTime = currentTime 
            
            if spec.targetNodeId ~= 0 and spec.isTargetValid then
                
                if self.isClient and spec.killSample ~= nil then
                    g_soundManager:stopSample(spec.killSample) 
                    g_soundManager:playSample(spec.killSample)
                end

                print("[HuntingRifle] Sikeres találat! Állat: " .. spec.animalNameHU)
                
                -- JAVÍTÁS: Állat eltüntetése AZONNAL a kliensnél (a lövő játékosnál)
                if entityExists(spec.targetNodeId) then
                    local rootToHide = spec.targetNodeId
                    local parent = getParent(rootToHide)
                    
                    -- Megkeressük a fő csomópontot
                    while parent ~= 0 and parent ~= getRootNode() do
                        local parentName = string.lower(getName(parent) or "")
                        if parentName == "wildlife" or parentName == "animals" or parentName == "scenegraph" then
                            break
                        end
                        rootToHide = parent
                        parent = getParent(rootToHide)
                    end
                    
                    -- Fizika és grafika megszüntetése lokálisan
                    setVisibility(rootToHide, false)
                    removeFromPhysics(rootToHide)
                    setTranslation(rootToHide, 0, -5000, 0)
                    print("[HuntingRifle] Az állat kliens oldalon sikeresen száműzve!")
                end
                
                -- Lekérjük az aktuális játékos farm azonosítóját
                local playerFarmId = g_currentMission:getFarmId()
                
                -- ÚJ ESEMÉNY KÜLDÉSE: Csak a pénzt intézzük a szerveren
                HuntingRifleMoneyEvent.sendEvent(playerFarmId, spec.animalTypeId)
                
                -- Változók alaphelyzetbe állítása
                spec.targetNodeId = 0
                spec.isTargetValid = false
                spec.animalNameHU = ""
                spec.animalTypeId = ""
                spec.animalReward = 0
            end
        end
    end
end

-- === 3. CÉLZÁS ÉS KERESÉS (RAYCAST) ===
function HuntingRifle:onUpdate(dt)
    if self:getCarryingPlayer() == nil or not self.isClient then return end
    
    local spec = self.spec_huntingRifle
    spec.targetNodeId = 0
    spec.isTargetValid = false
    spec.animalNameHU = ""
    spec.animalTypeId = ""
    spec.animalReward = 0

    local startNode = spec.raycastNode
    if startNode == nil then startNode = self.rootNode end

    local x, y, z = getWorldTranslation(startNode)
    local dirX, dirY, dirZ = localDirectionToWorld(startNode, 0, 0, 1)

    local mask = 4294967295 
    raycastClosest(x, y, z, dirX, dirY, dirZ, spec.distance, "raycastCallback", self, mask)
end

function HuntingRifle:raycastCallback(hitObjectId)
    local spec = self.spec_huntingRifle

    if hitObjectId ~= 0 then
        local currentNode = hitObjectId
        local depth = 0
        
        while currentNode ~= 0 and depth < 3 do
            local nodeName = string.lower(getName(currentNode) or "")
            local isAnimal = false
            local huName = ""
            local typeId = ""
            local potentialReward = 0
            
            if string.find(nodeName, "boar") then isAnimal = true; huName = "vaddisznót"; typeId = "boar"; potentialReward = 200
            elseif string.find(nodeName, "deer2") then isAnimal = true; huName = "szarvast (2)"; typeId = "deer2"; potentialReward = 400
            elseif string.find(nodeName, "deer") then isAnimal = true; huName = "szarvast"; typeId = "deer"; potentialReward = 300
            elseif string.find(nodeName, "fox") then isAnimal = true; huName = "rókát"; typeId = "fox"; potentialReward = 50
            elseif string.find(nodeName, "wolf") then isAnimal = true; huName = "farkast"; typeId = "wolf"; potentialReward = 250
            end

            if isAnimal then
                spec.targetNodeId = currentNode 
                spec.isTargetValid = true
                spec.animalNameHU = huName
                spec.animalTypeId = typeId
                spec.animalReward = potentialReward
                return false 
            end
            
            currentNode = getParent(currentNode)
            depth = depth + 1
        end
    end
    
    return true 
end

-- === 4. HUD (CÉLKERESZT) ===
function HuntingRifle:onDraw()
    local spec = self.spec_huntingRifle
    setTextAlignment(RenderText.ALIGN_CENTER) 
    setTextBold(true)
    
    if spec.targetNodeId ~= 0 and spec.isTargetValid then
        setTextColor(1, 0, 0, 1) 
        renderText(0.5, 0.5, 0.04, "( + )")

        renderText(0.5, 0.45, 0.030, "Célba vettél egy " .. spec.animalNameHU .. "! (" .. tostring(spec.animalReward) .. " €)")
        setTextColor(1, 0.8, 0, 1)
        renderText(0.5, 0.41, 0.025, "[Bal Klikk -> LÖVÉS]")
    else
        setTextColor(1, 1, 1, 0.5)
        renderText(0.5, 0.5, 0.04, "+")
    end
    
    setTextBold(false) 
    setTextAlignment(RenderText.ALIGN_LEFT)
    setTextColor(1, 1, 1, 1)
end

-- === 5. SZERVER ESEMÉNY (CSAK A PÉNZ JÓVÁÍRÁSÁRA) ===
HuntingRifleMoneyEvent = {}
local HuntingRifleMoneyEvent_mt = Class(HuntingRifleMoneyEvent, Event)
InitEventClass(HuntingRifleMoneyEvent, "HuntingRifleMoneyEvent")

function HuntingRifleMoneyEvent.emptyNew() return Event.new(HuntingRifleMoneyEvent_mt) end

function HuntingRifleMoneyEvent.new(farmId, animalType)
    local self = HuntingRifleMoneyEvent.emptyNew()
    self.farmId = farmId
    self.animalType = animalType
    return self
end

function HuntingRifleMoneyEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, self.farmId)
    streamWriteString(streamId, self.animalType)
end

function HuntingRifleMoneyEvent:readStream(streamId, connection)
    self.farmId = streamReadInt32(streamId)
    self.animalType = streamReadString(streamId)
    self:run(connection)
end

function HuntingRifleMoneyEvent:run(connection)
    -- Ez a rész csak a szerveren fog lefutni
    if not connection:getIsServer() then
        -- Létrehozunk egy helyi árlistát a szerveren
        local rewards = {
            boar = 200,
            deer = 300,
            deer2 = 400,
            fox = 50,
            wolf = 250
        }
        
        -- Megkeressük a jutalmat
        local rewardAmount = rewards[self.animalType] or 0
        
        if rewardAmount > 0 and self.farmId ~= nil and self.farmId ~= 0 then
            -- g_currentMission:addMoney(összeg, farm_azonosító, pénztípus, hud_kijelzés, tranzakció)
            g_currentMission:addMoney(rewardAmount, self.farmId, MoneyType.OTHER, true, true)
            print("[HuntingRifle Server] Jutalmazás: " .. tostring(rewardAmount) .. " EUR a " .. tostring(self.farmId) .. " farmnak.")
        end
    end
end

function HuntingRifleMoneyEvent.sendEvent(farmId, animalType)
    if g_client ~= nil then
        g_client:getServerConnection():sendEvent(HuntingRifleMoneyEvent.new(farmId, animalType))
    end
end