function displayDialougeLine(player_name, text)
    minetest.chat_send_player(player_name, "⌠ " .. text .. " ⌡")
    minetest.sound_play("dialouge", {
        to_player = player_name,
        gain = 1.0,
    })
end
function displayGlobalDialougeLine(text)
    minetest.chat_send_all("⌠ " .. text .. " ⌡")
    minetest.sound_play("dialouge", {
        gain = 1.0,
    })
end

-- id: gettingstarted
local function agettingstarted(player_name)
    displayDialougeLine(player_name, "Welcome, player.")

    minetest.after(1, function() 
        displayDialougeLine(player_name, "This is the guide speaking, if this is your first time playing, I will walk you through the first steps.")
    end)

    minetest.after(2, function() 
        displayDialougeLine(player_name, "If you prefer tinkering around, taking in the atmosphere, you already know the game or something else entirely you can disable me using /noprogression")
    end)

    minetest.after(3, function() 
        displayDialougeLine(player_name, "Now, why don't you check out what's below you? That's the core. It's the source of all progression in this game.")
    end)

    minetest.after(4, function() 
        displayDialougeLine(player_name, "Try punching it, maybe?")
    end)
end

-- id: biggerplatform
local function abiggerplatform(player_name)
    displayDialougeLine(player_name, "You found the core. Amazing.")

    minetest.after(1, function() 
        displayDialougeLine(player_name, "But, isn't it a bit crammed?")
    end)

    minetest.after(2, function() 
        displayDialougeLine(player_name, "I know right? We have to do something about this!")
    end)

    minetest.after(3, function() 
        displayDialougeLine(player_name, "I've got just the thing for you!")
    end)

    minetest.after(4, function() 
        displayDialougeLine(player_name, "Punch the Core a little more. With nine 'Matter Dust', you can craft yourself a 'Matter Blob'.")
    end)

    minetest.after(5, function() 
        displayDialougeLine(player_name, "I'll report back when you're done.")
    end)
end

local function aantimatter(player_name)
    displayDialougeLine(player_name, "You're a quick learner, huh.")

    minetest.after(1, function() 
        displayDialougeLine(player_name, "Unfortunately, you dont seem to be strong enough to destroy that node once you place it.")
    end)

    minetest.after(2, function() 
        displayDialougeLine(player_name, "That kind of sucks, so let's change it.")
    end)

    minetest.after(3, function() 
        displayDialougeLine(player_name, "Craft some 'Antimatter Dust', we'll need it later.")
    end)

    minetest.after(4, function() 
        displayDialougeLine(player_name, "It's made by mixing 'Matter Dust' and 'Core Dust'. Let's see you figure this out, smart one.")
    end)
end

local function aannihilator(player_name)
    displayDialougeLine(player_name, "Does it feel weird to be holding antimatter?")

    minetest.after(2, function() 
        displayDialougeLine(player_name, "Anyways, go, move on to crafting a 'Matter Annihilator'")
    end)

    minetest.after(3, function() 
        displayDialougeLine(player_name, "You'll need these items:")
    end)

    minetest.after(4, function() 
        displayDialougeLine(player_name, "1x 'Antimatter Dust'")
        displayDialougeLine(player_name, "1x 'Charged Particle'")
        displayDialougeLine(player_name, "3x 'Matter Blob'")
    end)

    minetest.after(5, function() 
        displayDialougeLine(player_name, "Make sure the 'Charged Particle' is properly enclosed in matter, or it'll escape.")
    end)
end

local function asetupchargedfield(player_name)
    displayDialougeLine(player_name, "Impressive!")

    minetest.after(1, function() 
        displayDialougeLine(player_name, "Now, then. We have one more thing to do before we can start automating. Can you guess what it is?")
    end)

    minetest.after(3, function() 
        displayDialougeLine(player_name, "That's right! We need power generation.")
    end)

    minetest.after(4, function() 
        displayDialougeLine(player_name, "Using nine 'Charged Particle', you can craft yourself a 'Simple Charged Field'")
    end)

    minetest.after(5, function() 
        displayDialougeLine(player_name, "But listen up! Charged Fields decay over time. Since you are using a 'Simple Charged Field', it should last you a couple of minutes of power generation.")
    end)

    minetest.after(6, function() 
        displayDialougeLine(player_name, "Yeah, it uses energy even when there's nothing connected to it. Since resources are infinite here, time is your resource.")
    end)

    minetest.after(7, function() 
        displayDialougeLine(player_name, "Anyways, I talked a lot, didn't I? Maybe too much. Let's get automating.")
    end)
end

local function aautomation(player_name)
    displayDialougeLine(player_name, "I can tell what you're thinking.")

    minetest.after(1, function() 
        displayDialougeLine(player_name, "You're probably thinking: 'Finally! Automation!'; and yeah, let's get on that!")
    end)

    minetest.after(2, function() 
        displayDialougeLine(player_name, "Here's what you'll need, but this time I won't tell you how to assemble it.")
    end)

    minetest.after(3, function() 
        displayDialougeLine(player_name, "1x 'Matter Annihilator'")
        displayDialougeLine(player_name, "4x 'Matter Blob'")
        displayDialougeLine(player_name, "4x 'Core Dust'")
    end)

    minetest.after(2, function() 
        displayDialougeLine(player_name, "Tip: Machines without power occasionally emit red particles.")
    end)
end

local function aadvancedextractors(player_name)
    displayDialougeLine(player_name, "Wow, that's a shiny new machine you've got there!")

    minetest.after(1, function() 
        displayDialougeLine(player_name, "Do you also want to increase production?")
    end)
    minetest.after(2, function() 
        displayDialougeLine(player_name, "Sure you do.")
    end)
    minetest.after(3, function() 
        displayDialougeLine(player_name, "Here's the materials required, I trust you figure it out ^^")
    end)
    minetest.after(4, function() 
        displayDialougeLine(player_name, "1x 'Simple Matter Extractor'")
        displayDialougeLine(player_name, "4x 'Matter Blob'")
        displayDialougeLine(player_name, "4x 'Matter Annihilator'")
    end)

end

function new_quest(player_name, achievement_id)
    if is_achievement_unlocked(player_name, achievement_id) then return end

    if achievement_id == "advancedextractors" then
        aadvancedextractors(player_name)
        return
    end
end

local function achievements_progress(player_name)
    if is_achievement_unlocked(player_name, "noprogression") then return end -- skip

    if not is_achievement_unlocked(player_name, "gettingstarted") then
        agettingstarted(player_name)
        return
    end

    if not is_achievement_unlocked(player_name, "biggerplatform") then
        abiggerplatform(player_name)
        return
    end

    if not is_achievement_unlocked(player_name, "antimatter") then
        aantimatter(player_name)
        return
    end

    if not is_achievement_unlocked(player_name, "annihilator") then
        aannihilator(player_name)
        return
    end

    if not is_achievement_unlocked(player_name, "setupchargedfield") then
        asetupchargedfield(player_name)
        return
    end

    if not is_achievement_unlocked(player_name, "automation") then
        aautomation(player_name)
        return
    end

    displayDialougeLine(player_name, "That's the end of the questline for now. You will occasionally encounter side-challenges or goals. Enjoy tinkering!")
end 

minetest.register_chatcommand("noprogression", {
    description = "Skip the guide and progression system.",
    privs = {},
    func = function(name, param)
        unlock_achievement(name, "noprogression")
        displayDialougeLine(name, "Progression has been disabled. Use /progression to enable it again.")
    end,
})
minetest.register_chatcommand("progression", {
    description = "Enable the guide and progression system again.",
    privs = {},
    func = function(name, param)
        revoke_achievement(name, "noprogression")
        displayDialougeLine(name, "Progression has been enabled. Use /noprogression to disable it.")
    end,
})

minetest.register_on_joinplayer(function(player) 
    local player_name = player:get_player_name()

    -- after 1s, start progression
    minetest.after(1, function() 
        achievements_progress(player_name)
    end)
end)

minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
    if itemstack:get_name() == "sbz_resources:matter_blob" then
        unlock_achievement(player:get_player_name(), "biggerplatform")
    elseif itemstack:get_name() == "sbz_resources:antimatter_dust" then
        unlock_achievement(player:get_player_name(), "antimatter")

    elseif itemstack:get_name() == "sbz_resources:matter_annihilator" then
        unlock_achievement(player:get_player_name(), "annihilator")

    elseif itemstack:get_name() == "sbz_resources:simple_charged_field" then
        unlock_achievement(player:get_player_name(), "setupchargedfield")

    elseif itemstack:get_name() == "sbz_resources:simple_matter_extractor" then
        unlock_achievement(player:get_player_name(), "automation")

    end
end)

function unlock_achievement(player_name, achievement_id)
    local player = minetest.get_player_by_name(player_name)
    if not player then
        return
    end
    
    local meta = player:get_meta()
    if not is_achievement_unlocked(player_name, achievement_id) then
        meta:set_string(achievement_id, "true")
        
        minetest.chat_send_player(player_name, "Achievement unlocked: " .. achievement_id)
        
        achievements_progress(player_name)
    end
end

function revoke_achievement(player_name, achievement_id)
    local player = minetest.get_player_by_name(player_name)
    if not player then
        return
    end
    
    local meta = player:get_meta()
    if is_achievement_unlocked(player_name, achievement_id) then
        meta:set_string(achievement_id, "")
        
        minetest.chat_send_player(player_name, "Achievement revoked: " .. achievement_id)
        
        achievements_progress(player_name)
    end
end

function is_achievement_unlocked(player_name, achievement_id)
    local player = minetest.get_player_by_name(player_name)
    if not player then
        return false
    end

    local meta = player:get_meta()
    if meta then
        return meta:get_string(achievement_id) == "true"
    else
        return false
    end
end