-- =============================================================================
-- Dialogue: Sequential Dialogue with Coroutines
-- =============================================================================
-- This example demonstrates how to create sequential, branching dialogue
-- using Lua coroutines. This is the most practical approach for story-driven
-- dialogue where you need to wait for player input between lines.
--
-- The pattern:
--   1. Show dialogue with choices
--   2. Wait for player to select a choice (via callback or polling)
--   3. React and show next dialogue based on the choice
--   4. Repeat until the conversation ends
--
-- Note: DialogueSystem is now a singleton. No ECS entity/component needed.
-- =============================================================================

-- ---------------------------------------------------------------------------
-- 1. Dialogue Queue System
-- ---------------------------------------------------------------------------
-- A simple queue that lets you chain dialogue lines and wait for player
-- input between each one.

local DialogueQueue = {}
local dialogue_queue_active = false
local dialogue_queue_pending = false
local dialogue_queue_choice = 0
local dialogue_queue_choice_text = ""

-- Since choice selection is handled via C++ callbacks, in a real game
-- you'd wire those callbacks to set these variables. For this example,
-- we demonstrate the pattern using polling.

-- ---------------------------------------------------------------------------
-- 2. Helper: Show dialogue and wait for player response
-- ---------------------------------------------------------------------------

--- Show a line of dialogue and wait for the player to respond.
--- @param text string The narration text
--- @param speaker string|nil Optional speaker name
--- @param choices table|nil Array of choice label strings (nil = click to dismiss)
--- @return number choice_index (0 if dismissed, 1+ for choices)
function show_and_wait(text, speaker, choices)
    -- Show dialogue via the singleton API
    ecs.dialogue.show(text, choices or {}, speaker or "")

    -- Wait for player response
    dialogue_queue_pending = true
    dialogue_queue_choice = 0

    -- Busy-wait loop (in a real coroutine-based system, you'd yield here)
    -- This is a simplified version; see the coroutine example below.
    local timeout = 1000
    while dialogue_queue_pending and timeout > 0 do
        -- In a real game loop, this would be a coroutine yield.
        -- For this example, we simulate with a counter.
        if not ecs.dialogue.is_active() then
            dialogue_queue_pending = false
        end
        timeout = timeout - 1
        if timeout <= 0 then
            dialogue_queue_pending = false
            print("WARNING: Dialogue wait timed out!")
        end
    end

    return dialogue_queue_choice
end

-- ---------------------------------------------------------------------------
-- 3. Example: Simple linear conversation
-- ---------------------------------------------------------------------------

function simple_conversation()
    print("=== Simple Conversation ===")

    -- Line 1: Narration with no choices (click to continue)
    ecs.dialogue.show(
        "The old man sits by the fire, staring into the flames.",
        {},
        "Narrator"
    )

    -- In a real game, you'd wait for the dismiss event here.
    -- For this example, we just show the pattern.

    -- Line 2: NPC speaks with choices
    ecs.dialogue.show(
        "I've been expecting you. The darkness grows stronger each day.",
        { "Tell me more", "How can I help?", "I must go" },
        "Old Man"
    )

    print("  (Player would now see choices and pick one)")
end

-- ---------------------------------------------------------------------------
-- 4. Example: Branching conversation tree
-- ---------------------------------------------------------------------------

-- Define a conversation tree as a table of nodes
local conversations = {
    village_elder = {
        greeting = {
            text = "Welcome to our village, stranger. What brings you here?",
            speaker = "Elder Marcus",
            choices = {
                { text = "I seek adventure",     next = "adventure" },
                { text = "Just passing through",  next = "passing" },
                { text = "I need a place to stay", next = "lodging" }
            }
        },
        adventure = {
            text = "Adventure, you say? The old ruins to the east have been stirring.",
            speaker = "Elder Marcus",
            choices = {
                { text = "Tell me about the ruins", next = "ruins" },
                { text = "I'll check them out",     next = "goodbye_adventure" },
                { text = "Maybe another time",      next = "goodbye" }
            }
        },
        passing = {
            text = "Safe travels! The road north is clear, but beware the forest at night.",
            speaker = "Elder Marcus",
            choices = {
                { text = "Thank you for the warning", next = "goodbye" },
                { text = "What's in the forest?",     next = "forest" }
            }
        },
        lodging = {
            text = "The inn is just down the road. Tell them Marcus sent you.",
            speaker = "Elder Marcus",
            choices = {
                { text = "Thank you, elder", next = "goodbye" },
                { text = "Is there work in town?", next = "work" }
            }
        },
        ruins = {
            text = "Ancient ruins, full of traps and treasure. Several have entered, few returned.",
            speaker = "Elder Marcus",
            choices = {
                { text = "I'm not afraid",          next = "goodbye_adventure" },
                { text = "Sounds too dangerous",    next = "goodbye" }
            }
        },
        forest = {
            text = "Strange creatures have been seen. Wolves the size of horses!",
            speaker = "Elder Marcus",
            choices = {
                { text = "I'll be careful",  next = "goodbye" },
                { text = "I can handle it",  next = "goodbye_adventure" }
            }
        },
        work = {
            text = "The blacksmith needs an apprentice. Ask for Henrik.",
            speaker = "Elder Marcus",
            choices = {
                { text = "I'll visit the blacksmith", next = "goodbye" },
                { text = "Thanks, but I'll move on",  next = "goodbye" }
            }
        },
        goodbye_adventure = {
            text = "Good luck, brave one. You'll need it.",
            speaker = "Elder Marcus",
            choices = {
                { text = "Farewell!", next = nil }
            }
        },
        goodbye = {
            text = "May the winds guide you safely.",
            speaker = "Elder Marcus",
            choices = {
                { text = "Farewell!", next = nil }
            }
        }
    }
}

--- Walk through a conversation tree.
--- @param tree table The conversation tree definition
--- @param start_node string The starting node name
function run_conversation(tree, start_node)
    print("=== Starting Conversation ===")

    local current_node_name = start_node
    local max_steps = 20
    local step = 0

    while current_node_name and step < max_steps do
        step = step + 1
        local node = tree[current_node_name]
        if not node then
            print("ERROR: Unknown conversation node: " .. current_node_name)
            break
        end

        -- Build choices table from the node's choices
        local choices = {}
        local choice_map = {}
        if node.choices then
            for i, choice in ipairs(node.choices) do
                table.insert(choices, choice.text)
                choice_map[i] = choice
            end
        end

        -- Show the dialogue via singleton API
        ecs.dialogue.show(node.text, choices, node.speaker or "")

        -- In a real game, you'd wait for the player's choice here.
        -- For this example, we simulate by picking the first choice.
        print("  [Node: " .. current_node_name .. "] " .. node.speaker .. ": \"" .. node.text .. "\"")

        -- Simulate picking a choice (in real game, wait for player input)
        if node.choices and #node.choices > 0 then
            local chosen = node.choices[1]  -- Simulate picking first choice
            print("  [Player chose: " .. chosen.text .. "]")
            current_node_name = chosen.next
        else
            current_node_name = nil
        end
    end

    print("=== Conversation Ended ===")
end

-- Run the conversation tree
run_conversation(conversations.village_elder, "greeting")

-- ---------------------------------------------------------------------------
-- 5. Example: NPC dialogue with state tracking
-- ---------------------------------------------------------------------------

-- Track NPC dialogue state
local npc_state = {
    marcus_met = false,
    marcus_friendship = 0,
    quest_active = false,
    quest_completed = false
}

function talk_to_elder_marcus()
    if not npc_state.marcus_met then
        -- First meeting
        npc_state.marcus_met = true
        npc_state.marcus_friendship = 10

        ecs.dialogue.show(
            "Ah, a new face! I am Elder Marcus, keeper of this village.\nIt's been so long since we had visitors.",
            { "Pleasure to meet you", "I've heard stories about you", "Hello" },
            "Elder Marcus"
        )
    elseif npc_state.quest_active and npc_state.quest_completed then
        -- Quest completed
        npc_state.marcus_friendship = npc_state.marcus_friendship + 50

        ecs.dialogue.show(
            "You did it! The village is safe thanks to you.\nPlease, take this reward.",
            { "Thank you, elder", "I was happy to help" },
            "Elder Marcus"
        )
    elseif npc_state.quest_active then
        -- Quest in progress
        ecs.dialogue.show(
            "Have you dealt with those bandits yet?\nThe villagers are growing anxious.",
            { "I'm working on it", "I need more information", "Not yet" },
            "Elder Marcus"
        )
    else
        -- Regular greeting
        ecs.dialogue.show(
            "Welcome back, friend. The village is peaceful today.",
            { "Any news?", "I need supplies", "Goodbye" },
            "Elder Marcus"
        )
    end
end

-- Simulate talking to Marcus a few times
print("=== NPC State Tracking ===")
talk_to_elder_marcus()  -- First meeting
npc_state.quest_active = true
talk_to_elder_marcus()  -- Quest active
npc_state.quest_completed = true
talk_to_elder_marcus()  -- Quest completed

-- =============================================================================
-- Summary
-- =============================================================================
-- For sequential dialogue:
--   1. Use ecs.dialogue.show() to display each line
--   2. Wait for player input between lines (callback or polling)
--   3. Use conversation trees for branching narratives
--   4. Track NPC state to change dialogue based on game progress
--   5. No ECS entity needed — DialogueSystem is a singleton
-- =============================================================================

print("Dialogue sequence examples completed!")
