-- SlotMachine.lua – Z tengely, negatív irány (-30° lépés), közvetlen WAV betöltés Lua-ból
SlotMachine = {}
SlotMachine.MOD_NAME = g_currentModName

-- Konstansok a tárcsához
local STEPS = 12               -- 12 szimbólum / kör
local STEP_DEG = 30            -- 30° / lépés
local STEP_RAD = math.rad(STEP_DEG)

function SlotMachine.prerequisitesPresent(specializations)
    return true
end

function SlotMachine.initSpecialization()
end

function SlotMachine.registerFunctions(vehicleType)
    SpecializationUtil.registerFunction(vehicleType, "startSpin",  SlotMachine.startSpin)
    SpecializationUtil.registerFunction(vehicleType, "checkWinGrid", SlotMachine.checkWinGrid)
end

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

----------------------------------------------------------------
-- Segéd: minta betöltés (HungerSystem mintájára, 2D hang)
----------------------------------------------------------------
local function sm_createAndLoadSample(absPath, sampleName)
    local s = createSample(sampleName or "slotSample")
    local ok = loadSample(s, absPath, false) -- 2D
    if not ok then
        print(("[SlotMachine] Nem sikerült betölteni a hangot: %s"):format(tostring(absPath)))
        delete(s)
        return nil
    end
    return s
end

----------------------------------------------------------------
-- Szimbólumtérkép (a három tárcsa sorrendje 30°-onként, index 1 = 0°)
----------------------------------------------------------------
local REEL_MAP = {
    -- Bal (reel 1): 0°, -30°, -60° ... -330°
    {"Hetes","Citrom","Szőlő","Szilva","Cseresznye","Banán","Óra","Harang","Narancs","Dinnye","Csillag","Szív"},
    -- Középső (reel 2)
    {"Cseresznye","Óra","Szőlő","Narancs","Banán","Hetes","Szilva","Citrom","Szív","Harang","Dinnye","Csillag"},
    -- Jobb (reel 3)
    {"Cseresznye","Citrom","Csillag","Szív","Szőlő","Dinnye","Szilva","Óra","Harang","Hetes","Banán","Narancs"}
}

----------------------------------------------------------------
-- Szög ↔ index (Z tengely, negatív forgás; 0° => idx=1, -30° => idx=2, ... -330° => idx=12)
----------------------------------------------------------------
local function angleToIndexZNeg(angleRad)
    -- Használjunk nyers fokot (negatív is lehet), majd -deg-ből számolunk lépést
    local deg = math.deg(angleRad)        -- lehet negatív
    local idx = (math.floor(((-deg) + (STEP_DEG/2)) / STEP_DEG) % STEPS) + 1
    return idx
end

local function indexToAngleZNeg(idx)
    -- idx: 1..12  ->  0°, -30°, -60° ... -330°
    local k = idx - 1
    local deg = -(k * STEP_DEG)
    return math.rad(deg)
end

----------------------------------------------------------------
-- onLoad
----------------------------------------------------------------
function SlotMachine:onLoad(savegame)
    self.spec_slotMachine = {}
    local spec = self.spec_slotMachine

    -- Tárcsa node-ok: fix indexek (nem XML-ből olvasunk!)
    spec.reelNodes = {}
    spec.reelNodes[1] = I3DUtil.indexToObject(self.components, "0>8|0")
    spec.reelNodes[2] = I3DUtil.indexToObject(self.components, "0>8|1")
    spec.reelNodes[3] = I3DUtil.indexToObject(self.components, "0>8|2")

    -- Pörgetés állapot
    spec.isSpinning  = false
    spec.spinOrder   = 1                  -- opcionális sorrend (ha szekvenciálisan állítanád meg)
    spec.progress    = {0,0,0}
    spec.startZ      = {0,0,0}
    spec.targetZ     = {0,0,0}
    spec.targetIdx   = {1,1,1}
    spec.spinSpeed   = 0.004              -- lerp sebesség szorzó (dt-vel skálázva)

    -- 3×3 grid ideiglenes buffer (felső, középső, alsó sor)
    spec.grid = {{},{},{}}

    -- Hangok betöltése KÖZVETLEN Lua-ból (NEM XML!)
    local base = self.baseDirectory or ""
    spec.sampleSpin = sm_createAndLoadSample(base .. "sounds/push.wav", "slot_spin")
    spec.sampleWin  = sm_createAndLoadSample(base .. "sounds/win.wav",  "slot_win")

    -- Action events tároló
    spec.actionEvents = {}
end

function SlotMachine:onDelete()
    local spec = self.spec_slotMachine
    if spec.sampleSpin ~= nil then delete(spec.sampleSpin); spec.sampleSpin = nil end
    if spec.sampleWin  ~= nil then delete(spec.sampleWin);  spec.sampleWin  = nil end
end

----------------------------------------------------------------
-- B gomb: pörgetés indítás
----------------------------------------------------------------
function SlotMachine:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
    if self.isClient then
        local spec = self.spec_slotMachine
        self:clearActionEventsTable(spec.actionEvents)

        if isActiveForInput then
            local _, eventId = self:addActionEvent(
                spec.actionEvents,
                InputAction.IMPLEMENT_EXTRA,   -- B
                self,
                SlotMachine.startSpin,
                false, true, false, true, nil
            )
            g_inputBinding:setActionEventText(eventId, "Spin (B)")
        end
    end
end

function SlotMachine:startSpin()
    local spec = self.spec_slotMachine
    if spec.isSpinning then return end

    spec.isSpinning = true
    spec.spinOrder  = 3   -- egyszerre forogjon mindhárom (ha szekvenciálisan akarod: induljon 1 és nőjön 3-ig)

    for i=1,3 do
        -- kiinduló Z
        local _,_,rz = getRotation(spec.reelNodes[i])
        spec.startZ[i] = rz

        -- célszimbólum (1..12), negatív irányban, extra körökkel
        local targetIdx  = math.random(1, STEPS)
        spec.targetIdx[i] = targetIdx

        local extraTurns = math.random(2, 6) * 360  -- 2-6 teljes fordulat
        local targetDeg  = -(targetIdx-1)*STEP_DEG - extraTurns
        spec.targetZ[i]  = math.rad(targetDeg)

        spec.progress[i] = 0
    end

    -- Pörgetés hang
    if spec.sampleSpin ~= nil then
        playSample(spec.sampleSpin, 1, 1, 0, 0, 0)
    end
end

----------------------------------------------------------------
-- Update: lerp Z tengelyen, negatív irány, majd 30°-ra snap
----------------------------------------------------------------
function SlotMachine:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
    local spec = self.spec_slotMachine
    if not spec.isSpinning then return end

    local allDone = true
    local speed = spec.spinSpeed * dt

    for i=1,3 do
        if i <= spec.spinOrder then
            if spec.progress[i] < 1 then
                spec.progress[i] = math.min(1, spec.progress[i] + speed)
                local z = MathUtil.lerp(spec.startZ[i], spec.targetZ[i], spec.progress[i])
                -- Forgatás Z tengelyen, negatív irány felé (lerp már azt követi)
                setRotation(spec.reelNodes[i], 0, 0, z)
                allDone = false
            end
        end
    end

    -- Ha szekvenciálisan szeretnél állítani: itt növelheted a spinOrder-t, ha az aktuális elérte az 1-et
    if spec.progress[spec.spinOrder] >= 1 and spec.spinOrder < 3 then
        spec.spinOrder = spec.spinOrder + 1
        allDone = false
    end

    if allDone then
        spec.isSpinning = false

        -- Snap pontos 30°-ra + 3×3 rács felépítése (felső, középső, alsó)
        for i=1,3 do
            local _,_,rz = getRotation(spec.reelNodes[i])

            -- Számoljuk ki a középső indexet a végső szögből
            local idxMid = angleToIndexZNeg(rz)

            -- Snap (állítsuk be precízen a 30°-os pozícióra)
            local snappedZ = indexToAngleZNeg(idxMid)
            setRotation(spec.reelNodes[i], 0, 0, snappedZ)

            -- 3×3 grid: középső sor = idxMid, felső = előző, alsó = következő
            local prev = ((idxMid - 2 + STEPS) % STEPS) + 1 -- előző (vizuálisan felső)
            local next = ((idxMid) % STEPS) + 1             -- következő (vizuálisan alsó)

            spec.grid[1][i] = REEL_MAP[i][prev]
            spec.grid[2][i] = REEL_MAP[i][idxMid]
            spec.grid[3][i] = REEL_MAP[i][next]
        end

        -- Nyerővonal ellenőrzés (3 vízszintes + 2 átló)
        local won, symbol = self:checkWinGrid(spec.grid)
        if won then
            if spec.sampleWin ~= nil then
                playSample(spec.sampleWin, 1, 1, 0, 0, 0)
            end
            local txt = "NYERTÉL!"
            if symbol ~= nil then txt = txt .. " (" .. tostring(symbol) .. ")" end
            g_currentMission:showBlinkingWarning(txt, 3000)
        else
            g_currentMission:showBlinkingWarning("Nem nyertél!", 1500)
        end
    end
end

----------------------------------------------------------------
-- 3 vízszintes + 2 átló ellenőrzése
----------------------------------------------------------------
function SlotMachine:checkWinGrid(grid)
    -- vízszintes sorok
    for r=1,3 do
        if grid[r][1] == grid[r][2] and grid[r][2] == grid[r][3] then
            return true, grid[r][1]
        end
    end
    -- két átló
    if grid[1][1] == grid[2][2] and grid[2][2] == grid[3][3] then
        return true, grid[1][1]
    end
    if grid[1][3] == grid[2][2] and grid[2][2] == grid[3][1] then
        return true, grid[1][3]
    end
    return false, nil
end
