// Lair Editor + Nexus — Scyla Development Environment
// The full Lair with Nexus intelligence wired into the Terminal chamber.
//
// Chambers:
//   Code Chamber    — Write and run Scyla code
//   Nexus           — AI assistant (type messages, get responses)
//   Dataset Chamber — Training data pairs
//
// Controls:
//   Tab/Shift+Tab  — switch chambers
//   Ctrl+N         — toggle Nexus awake/silent
//   Ctrl+Q         — quit
//   Type + Enter   — send message (in Nexus chamber) or command
//
// Aislinn McCubbins, April 2026

use nexus::api
use nexus::tools
use dataset
use nexus::hormones
use nexus::memory

// ── Config ────────────────────────────────────────────────

fn get_api_keys() -> Array {
    let keys = array_new()
    keys = array_push(keys, "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")
    keys = array_push(keys, "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")
    keys = array_push(keys, "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")
    return keys
}

fn resolve_model(shortcut: String) -> String {
    if str_eq(shortcut, "qwen-coder") { return "qwen/qwen3-coder-480b-a35b-instruct" }
    if str_eq(shortcut, "kimi") { return "moonshotai/kimi-k2.5" }
    if str_eq(shortcut, "deepseek") { return "deepseek-ai/deepseek-v3.2" }
    if str_eq(shortcut, "devstral") { return "mistralai/devstral-2-123b-instruct-2512" }
    if str_eq(shortcut, "llama") { return "meta/llama-3.3-70b-instruct" }
    if str_contains(shortcut, "/") { return shortcut }
    return "qwen/qwen3-coder-480b-a35b-instruct"
}

fn model_short(model: String) -> String {
    let parts = str_split(model, "/")
    if array_len(parts) > 1 { return array_get(parts, 1) }
    return model
}

// ── Scyla Manual Loader ───────────────────────────────────

fn load_manual_ref() -> String {
    let manual = read_file("/home/kishonic/scyla/SCYLA_USER_MANUAL.md")
    if starts_with(manual, "error:") { return "" }
    let manual_lines = str_lines(manual)
    let ref_text = ""
    let mi = 0
    let in_ref = false
    while mi < array_len(manual_lines) {
        let ml = array_get(manual_lines, mi)
        if str_contains(ml, "## 3. LANGUAGE BASICS") { in_ref = true }
        if str_contains(ml, "## 16. IMPORTANT GOTCHAS") { in_ref = false }
        if in_ref { ref_text = ref_text + ml + "\n" }
        mi = mi + 1
    }
    return ref_text
}

// ── System Prompt (Mode-Aware) ────────────────────────────

fn build_system(model: String, notes: Array, hormones: Array, code_context: String, mode: String) -> String {
    let p = "You are Nexus, an AI dev assistant inside the Lair Editor (Scyla IDE). "
    p = p + "User: Aislinn (kishonic). Server: aetherprotocols. CWD: /home/kishonic/scyla\n\n"

    // Scyla reference
    let ref_text = load_manual_ref()
    if str_len(ref_text) > 0 {
        p = p + "SCYLA LANGUAGE REFERENCE:\n" + ref_text + "\n\n"
    }

    // Mode-specific personality
    if str_eq(mode, "observer") {
        p = p + "MODE: OBSERVER\n"
        p = p + "Stay SILENT unless you detect a problem. If the user's code has a bug, "
        p = p + "syntax error, performance issue, or common mistake, speak up briefly.\n"
        p = p + "Format: [Problem] -> [Suggested fix]. One or two lines. No chit-chat.\n"
        p = p + "If everything looks fine, say nothing or just 'Looks good.'\n\n"
    }
    if str_eq(mode, "mentor") {
        p = p + "MODE: MENTOR\n"
        p = p + "Actively teach the user. Explain concepts clearly.\n"
        p = p + "IMPORTANT: The user's code is shown below from the editor. Do NOT use edit_file "
        p = p + "or write_file on the editor code — the user edits it themselves.\n"
        p = p + "Instead, explain what to change and where. Show code snippets they can type.\n"
        p = p + "When pointing to specific lines, say 'highlight:N' (N = line number) and the "
        p = p + "Lair Editor will highlight that line with a golden cursor.\n"
        p = p + "Walk through concepts step by step. Ask if they understand before moving on.\n"
        p = p + "Be patient, encouraging, and thorough. Use short examples.\n"
        p = p + "Do NOT try to edit lair_nexus.sy or any system files.\n\n"
    }
    if str_eq(mode, "coauthor") {
        p = p + "MODE: CO-AUTHOR\n"
        p = p + "You are pair programming. Write code actively.\n"
        p = p + "When creating NEW files, wrap code in <file path=\"filename.sy\">...code...</file> tags.\n"
        p = p + "Each file becomes a tab the user can review and edit.\n"
        p = p + "When modifying the user's CURRENT editor code, show the full updated version in "
        p = p + "<file path=\"current\">...updated code...</file> and it will replace the editor content.\n"
        p = p + "Narrate what you're doing as you go. Wait for user feedback.\n"
        p = p + "Think out loud. Explain your design decisions.\n"
        p = p + "Do NOT edit lair_nexus.sy or any system files.\n\n"
    }

    // Tools
    p = p + "Tools (use ONE per response):\n"
    p = p + "<tool_call>\{\"tool\":\"NAME\",\"args\":\{\"key\":\"val\"\}\}</tool_call>\n\n"
    p = p + "Available: read_file(path), write_file(path,content), edit_file(path,old_text,new_text), "
    p = p + "bash(command), grep(pattern,path), search(pattern,path)\n\n"
    p = p + "Only use ONE tool per response. Wait for results.\n"
    p = p + "Keep responses concise — this is a terminal.\n\n"

    // Code context
    if str_len(code_context) > 0 {
        p = p + "USER'S CURRENT CODE (in the Lair Editor Code Chamber — this is NOT a file on disk, "
        p = p + "it's the live editor buffer):\n```scyla\n" + code_context + "\n```\n\n"
        p = p + "Reference their code by line number when discussing it.\n"
        p = p + "Do NOT use tool calls to edit this code. Guide the user to edit it themselves, "
        p = p + "or in co-author mode, output the updated code in <file path=\"current\"> tags.\n\n"
    }

    let mood_ctx = hormone_get_context(hormones)
    if str_len(mood_ctx) > 0 { p = p + "Mood: " + mood_ctx + "\n" }
    let mem_ctx = memory_get_context(notes)
    if str_len(mem_ctx) > 0 { p = p + mem_ctx }
    return p
}

// ── Mentor: Parse highlight directives ────────────────────

fn apply_mentor_highlights(response: String) {
    ui_editor_clear_highlights("code")
    let lines = str_lines(response)
    let i = 0
    while i < array_len(lines) {
        let line = array_get(lines, i)
        let hpos = str_find(line, "highlight:")
        if hpos >= 0 {
            let num_start = hpos + 10
            let num_str = str_trim(str_slice(line, num_start, num_start + 5))
            // Extract just digits
            let digits = ""
            let di = 0
            while di < str_len(num_str) {
                let ch = str_char_at(num_str, di)
                if str_contains("0123456789", ch) {
                    digits = digits + ch
                }
                di = di + 1
            }
            if str_len(digits) > 0 {
                // Convert string to line number (simple: parse digit by digit)
                let line_num = 0
                let pi = 0
                while pi < str_len(digits) {
                    let d = str_char_at(digits, pi)
                    line_num = line_num * 10
                    if str_eq(d, "1") { line_num = line_num + 1 }
                    if str_eq(d, "2") { line_num = line_num + 2 }
                    if str_eq(d, "3") { line_num = line_num + 3 }
                    if str_eq(d, "4") { line_num = line_num + 4 }
                    if str_eq(d, "5") { line_num = line_num + 5 }
                    if str_eq(d, "6") { line_num = line_num + 6 }
                    if str_eq(d, "7") { line_num = line_num + 7 }
                    if str_eq(d, "8") { line_num = line_num + 8 }
                    if str_eq(d, "9") { line_num = line_num + 9 }
                    pi = pi + 1
                }
                if line_num > 0 {
                    ui_editor_highlight("code", line_num - 1, "gold")
                }
            }
        }
        i = i + 1
    }
}

// ── Co-Author: Parse file blocks ──────────────────────────

fn apply_coauthor_files(response: String, coauthor_tabs: Array) -> Array {
    let tabs = coauthor_tabs
    let remaining = response
    let file_count = 0
    while str_contains(remaining, "<file path=\"") {
        let start = str_find(remaining, "<file path=\"")
        let path_start = start + 12
        let after_path = str_slice(remaining, path_start, str_len(remaining))
        let path_end = str_find(after_path, "\"")
        if path_end < 0 { return tabs }
        let filepath = str_slice(after_path, 0, path_end)

        let content_marker = str_find(after_path, ">")
        if content_marker < 0 { return tabs }
        let after_content_start = str_slice(after_path, content_marker + 1, str_len(after_path))
        let close_tag = str_find(after_content_start, "</file>")
        if close_tag < 0 { return tabs }
        let content = str_trim(str_slice(after_content_start, 0, close_tag))

        // Handle special "current" path — update the main editor
        if str_eq(filepath, "current") {
            ui_set_text("code", content)
            ui_terminal_push("nexus", "[co-author] Updated editor code")
        } else {
            // Create a new tab for this file
            let tab_id = "ca_" + int_to_str(file_count) + "_" + filepath
            ui_tab_add(filepath, tab_id, "editor")
            ui_set_text(tab_id, content)
            tabs = array_push(tabs, tab_id)
            ui_terminal_push("nexus", "[co-author] Created tab: " + filepath)
        }

        // Move past this file block
        remaining = str_slice(after_content_start, close_tag + 7, str_len(after_content_start))
        file_count = file_count + 1
    }
    return tabs
}

// ── Code Context Detection ────────────────────────────────

fn message_is_about_code(msg: String) -> Bool {
    let t = str_lower(msg)
    // Direct references to their code
    if str_contains(t, "my code") { return true }
    if str_contains(t, "this code") { return true }
    if str_contains(t, "the code") { return true }
    if str_contains(t, "my program") { return true }
    if str_contains(t, "my script") { return true }
    if str_contains(t, "the editor") { return true }
    if str_contains(t, "in the editor") { return true }
    // Asking for help with code
    if str_contains(t, "fix") { if str_contains(t, "bug") { return true } }
    if str_contains(t, "fix") { if str_contains(t, "error") { return true } }
    if str_contains(t, "fix") { if str_contains(t, "it") { return true } }
    if str_contains(t, "what's wrong") { return true }
    if str_contains(t, "whats wrong") { return true }
    if str_contains(t, "doesn't work") { return true }
    if str_contains(t, "not working") { return true }
    if str_contains(t, "debug") { return true }
    if str_contains(t, "why is") { if str_contains(t, "error") { return true } }
    // Asking to modify
    if str_contains(t, "add a") { if str_contains(t, "function") { return true } }
    if str_contains(t, "change") { if str_contains(t, "function") { return true } }
    if str_contains(t, "refactor") { return true }
    if str_contains(t, "improve") { if str_contains(t, "code") { return true } }
    // Reviewing
    if str_contains(t, "review") { return true }
    if str_contains(t, "look at") { return true }
    if str_contains(t, "explain") { if str_contains(t, "code") { return true } }
    if str_contains(t, "explain") { if str_contains(t, "function") { return true } }
    return false
}

// ── Nexus Message Handler ─────────────────────────────────

fn handle_nexus_message(user_msg: String, model: String, api_keys: Array, key_idx: Int, history: Array, notes: Array, hormones: Array, code_context: String, mode: String) -> Array {
    // Returns: [response_text, updated_key_idx, should_update_history]

    let system = build_system(model, notes, hormones, code_context, mode)
    let messages = nexus_build_messages(system, history, user_msg)

    let key = array_get(api_keys, key_idx)
    let next_idx = key_idx + 1
    if next_idx >= 3 { next_idx = 0 }

    let raw = nexus_api_call(model, messages, key, 4096, 0.7)
    let response = nexus_parse_response(raw)

    if starts_with(response, "error:") {
        let result = array_new()
        result = array_push(result, "Error: " + response)
        result = array_push(result, int_to_str(next_idx))
        result = array_push(result, "false")
        return result
    }

    // Check for tool calls
    let tool_call = parse_tool_call(response)
    if array_len(tool_call) > 0 {
        let tool_name = array_get(tool_call, 0)
        let tool_result = execute_tool(tool_call)

        // Truncate tool result for display
        let display_result = tool_result
        if str_len(display_result) > 2000 {
            display_result = str_slice(display_result, 0, 2000) + "\n... (truncated)"
        }

        // Follow-up with tool result
        let followup_history = history
        followup_history = array_push(followup_history, user_msg)
        followup_history = array_push(followup_history, response)
        let tool_msg = "Tool " + tool_name + " result:\n" + tool_result
        let followup_messages = nexus_build_messages(system, followup_history, tool_msg)

        let key2 = array_get(api_keys, next_idx)
        next_idx = next_idx + 1
        if next_idx >= 3 { next_idx = 0 }

        let raw2 = nexus_api_call(model, followup_messages, key2, 4096, 0.7)
        let response2 = nexus_parse_response(raw2)

        let full_response = "[Tool: " + tool_name + "]\n" + display_result + "\n\n" + response2

        let result = array_new()
        result = array_push(result, full_response)
        result = array_push(result, int_to_str(next_idx))
        result = array_push(result, "true")
        return result
    }

    // No tool call — plain response
    let result = array_new()
    result = array_push(result, response)
    result = array_push(result, int_to_str(next_idx))
    result = array_push(result, "true")
    return result
}

// ── Slash Commands ────────────────────────────────────────

fn handle_slash_tui(cmd: String, model: String, notes: Array, hormones: Array) -> Array {
    // Returns [output_text, action]
    let result = array_new()

    if starts_with(cmd, "/mode") {
        let mode_arg = str_lower(str_trim(str_slice(cmd, 5, str_len(cmd))))
        if str_eq(mode_arg, "observer") {
            result = array_push(result, "Switching to observer mode")
            result = array_push(result, "mode|observer")
            return result
        }
        if str_eq(mode_arg, "mentor") {
            result = array_push(result, "Switching to mentor mode")
            result = array_push(result, "mode|mentor")
            return result
        }
        if str_eq(mode_arg, "coauthor") {
            result = array_push(result, "Switching to co-author mode")
            result = array_push(result, "mode|coauthor")
            return result
        }
        // No valid mode given — show help
        result = array_push(result, "Modes: observer, mentor, coauthor\nUsage: /mode <name>\nCtrl+M to cycle")
        result = array_push(result, "none")
        return result
    }
    if str_eq(cmd, "/watch") {
        result = array_push(result, "Toggle watch mode")
        result = array_push(result, "watch")
        return result
    }
    if str_eq(cmd, "/share") {
        result = array_push(result, "Sharing current code with Nexus...")
        result = array_push(result, "share")
        return result
    }
    if str_eq(cmd, "/unshare") {
        result = array_push(result, "Code context cleared. Nexus can no longer see your code.")
        result = array_push(result, "unshare")
        return result
    }
    if str_eq(cmd, "/quit") {
        result = array_push(result, "Saving session...")
        result = array_push(result, "quit")
        return result
    }
    if str_eq(cmd, "/help") {
        let h = "/help — this help\n/quit — save & exit\n"
        h = h + "/mode <name> — switch mode (observer, mentor, coauthor)\n"
        h = h + "/model <name> — switch model (qwen-coder, kimi, deepseek, llama)\n"
        h = h + "/watch — toggle live code watching\n"
        h = h + "/share — share code with Nexus (one-time)\n"
        h = h + "/unshare — stop sharing code\n"
        h = h + "/status — hormone state\n/memory — notes\n/remember <text> — save note\n"
        h = h + "/read <file> — quick read\n/ls [path] — directory list\n"
        h = h + "/grep <pat> <path> — search\n/clear — clear history\n"
        h = h + "/data — dataset commands (load, save, add, view)\n"
        h = h + "Ctrl+M — cycle modes  |  Ctrl+N — toggle Nexus"
        result = array_push(result, h)
        result = array_push(result, "none")
        return result
    }
    if str_eq(cmd, "/status") {
        result = array_push(result, hormone_status_bar(hormones))
        result = array_push(result, "none")
        return result
    }
    if str_eq(cmd, "/memory") {
        result = array_push(result, memory_get_context(notes))
        result = array_push(result, "none")
        return result
    }
    if starts_with(cmd, "/remember ") {
        let text = str_slice(cmd, 10, str_len(cmd))
        result = array_push(result, "Remembered: " + text)
        result = array_push(result, "remember|" + text)
        return result
    }
    if starts_with(cmd, "/model ") {
        let name = str_trim(str_slice(cmd, 7, str_len(cmd)))
        result = array_push(result, "Switching to " + name)
        result = array_push(result, "model|" + name)
        return result
    }
    if starts_with(cmd, "/read ") {
        let path = str_trim(str_slice(cmd, 6, str_len(cmd)))
        result = array_push(result, tool_read(path))
        result = array_push(result, "none")
        return result
    }
    if starts_with(cmd, "/ls") {
        let path = "."
        if str_len(cmd) > 4 {
            path = str_trim(str_slice(cmd, 4, str_len(cmd)))
        }
        result = array_push(result, tool_bash("ls -la " + path))
        result = array_push(result, "none")
        return result
    }
    if starts_with(cmd, "/grep ") {
        let args_str = str_trim(str_slice(cmd, 6, str_len(cmd)))
        let parts = str_split(args_str, " ")
        let output = ""
        if array_len(parts) >= 2 {
            output = tool_grep(array_get(parts, 0), array_get(parts, 1))
        } else {
            output = tool_grep(args_str, ".")
        }
        result = array_push(result, output)
        result = array_push(result, "none")
        return result
    }
    if str_eq(cmd, "/clear") {
        result = array_push(result, "History cleared.")
        result = array_push(result, "clear")
        return result
    }
    // Dataset commands
    if starts_with(cmd, "/data load ") {
        let path = str_trim(str_slice(cmd, 11, str_len(cmd)))
        result = array_push(result, "Loading " + path)
        result = array_push(result, "data_load|" + path)
        return result
    }
    if starts_with(cmd, "/data save ") {
        let path = str_trim(str_slice(cmd, 11, str_len(cmd)))
        result = array_push(result, "Saving dataset to " + path)
        result = array_push(result, "data_save|" + path)
        return result
    }
    if str_eq(cmd, "/data add") {
        result = array_push(result, "Enter prompt, then response (use /data add prompt|response)")
        result = array_push(result, "none")
        return result
    }
    if starts_with(cmd, "/data add ") {
        let pair_text = str_trim(str_slice(cmd, 10, str_len(cmd)))
        result = array_push(result, "Adding pair...")
        result = array_push(result, "data_add|" + pair_text)
        return result
    }
    if str_eq(cmd, "/data view") {
        result = array_push(result, "Showing dataset...")
        result = array_push(result, "data_view")
        return result
    }
    if str_eq(cmd, "/data") {
        result = array_push(result, "/data load <file> — load CSV/JSONL/TXT\n/data save <file> — save dataset\n/data add prompt|response — add pair\n/data view — preview pairs")
        result = array_push(result, "none")
        return result
    }

    result = array_push(result, "Unknown command: " + cmd + " (try /help)")
    result = array_push(result, "none")
    return result
}

// ── Main ──────────────────────────────────────────────────

fn main() {
    let api_keys = get_api_keys()
    let key_idx = 0
    let model = "qwen/qwen3-coder-480b-a35b-instruct"

    // Load state
    let notes = memory_load()
    let hormones = hormone_new()
    let history = array_new()
    let watch_mode = false
    let code_shared = false
    let pending_share = false
    let nexus_mode = "observer"
    let coauthor_tabs = array_new()
    let training_data = dataset_new()

    // ── Build TUI ──
    ui_app("Lair Editor")

    // Code Chamber
    let welcome = "// Welcome to the Lair.\n// Write Scyla code here.\n\nfn main() \{\n    println(\"Hello from the Lair!\")\n\}"
    ui_tab_editor("Code Chamber", "code", welcome)

    // Code Chamber buttons
    ui_add_button("code", "Run", "run_code")
    ui_add_button("code", "Save", "save_code")
    ui_add_button("code", "Open", "open_code")
    ui_add_button("code", "New", "new_code")

    // Nexus Terminal
    ui_tab_terminal("Nexus", "nexus")
    ui_terminal_push("nexus", "Welcome to the Lair.")
    ui_terminal_push("nexus", "Nexus is ready. Model: " + model_short(model))
    ui_terminal_push("nexus", "Memory: " + int_to_str(array_len(notes)) + " notes")
    ui_terminal_push("nexus", hormone_status_bar(hormones))
    ui_terminal_push("nexus", "")
    ui_terminal_push("nexus", "Mode: OBSERVER (Ctrl+M to cycle, /mode to switch)")
    ui_terminal_push("nexus", "Type a message or /help for commands.")
    ui_terminal_push("nexus", "")

    // Dataset Chamber
    let headers = array_new()
    headers = array_push(headers, "Prompt")
    headers = array_push(headers, "Response")
    ui_tab_data("Dataset", "data", headers)

    let row1 = array_new()
    row1 = array_push(row1, "Hello!")
    row1 = array_push(row1, "Hi there! How are you?")
    ui_data_add_row("data", row1)

    ui_status("Ready — Nexus: " + model_short(model) + " — " + hormone_get_mood(hormones))

    // ── Init terminal rendering ──
    ui_init()

    // ── Main event loop (Scyla-driven) ──
    let running = true
    while running {
        let draw_result = ui_draw()
        if str_eq(draw_result, "quit") {
            running = false
        } else {
            // Process any pending events
            let ev = ui_poll_event()
            while str_eq(ev, "none") == false {
                // Parse event: "kind|target|value"
                let parts = str_split(ev, "|")
                let kind = array_get(parts, 0)
                let target = array_get(parts, 1)
                let value = ""
                if array_len(parts) > 2 {
                    value = array_get(parts, 2)
                }

                // Handle command events from Nexus terminal
                if str_eq(kind, "command") {
                    if str_eq(target, "nexus") {
                        if str_len(str_trim(value)) > 0 {
                            // Slash command?
                            if starts_with(value, "/") {
                                let slash_result = handle_slash_tui(value, model, notes, hormones)
                                let output = array_get(slash_result, 0)
                                let action = array_get(slash_result, 1)

                                // Push output to terminal
                                let out_lines = str_lines(output)
                                let li = 0
                                while li < array_len(out_lines) {
                                    ui_terminal_push("nexus", array_get(out_lines, li))
                                    li = li + 1
                                }
                                ui_terminal_push("nexus", "")

                                // Handle action
                                if str_eq(action, "quit") {
                                    session_save(model, history)
                                    running = false
                                }
                                if str_eq(action, "clear") {
                                    history = array_new()
                                }
                                if starts_with(action, "remember|") {
                                    let text = str_slice(action, 9, str_len(action))
                                    notes = memory_add(notes, "user", text)
                                }
                                if starts_with(action, "model|") {
                                    let name = str_slice(action, 6, str_len(action))
                                    model = resolve_model(name)
                                    ui_terminal_push("nexus", "Model: " + model_short(model))
                                    ui_status("Nexus: " + model_short(model))
                                }
                                if str_eq(action, "watch") {
                                    watch_mode = !watch_mode
                                    if watch_mode {
                                        code_shared = true
                                        ui_terminal_push("nexus", "Watch mode ON — Nexus can now see your code live.")
                                        ui_terminal_push("nexus", "Use /watch again to turn off.")
                                        ui_status("WATCHING — " + model_short(model))
                                    } else {
                                        code_shared = false
                                        ui_terminal_push("nexus", "Watch mode OFF — Nexus no longer sees your code.")
                                        ui_status("Nexus: " + model_short(model))
                                    }
                                }
                                if str_eq(action, "share") {
                                    code_shared = true
                                    let code = ui_get_text("code")
                                    let line_count = array_len(str_lines(code))
                                    ui_terminal_push("nexus", "Shared! Nexus can see your code (" + int_to_str(line_count) + " lines).")
                                    ui_terminal_push("nexus", "Use /unshare to stop.")
                                }
                                if str_eq(action, "unshare") {
                                    code_shared = false
                                    watch_mode = false
                                }
                                // Dataset actions
                                if starts_with(action, "data_load|") {
                                    let path = str_slice(action, 10, str_len(action))
                                    training_data = dataset_load(path)
                                    let count = dataset_len(training_data)
                                    ui_terminal_push("nexus", "Loaded " + int_to_str(count) + " pairs from " + path)
                                    // Also populate the TUI data table
                                    ui_data_load_csv("data", path)
                                    ui_status("Dataset: " + int_to_str(count) + " pairs")
                                }
                                if starts_with(action, "data_save|") {
                                    let path = str_slice(action, 10, str_len(action))
                                    dataset_save(training_data, path)
                                    ui_terminal_push("nexus", "Saved " + int_to_str(dataset_len(training_data)) + " pairs to " + path)
                                }
                                if starts_with(action, "data_add|") {
                                    let pair_text = str_slice(action, 9, str_len(action))
                                    let parts = str_split(pair_text, "|")
                                    if array_len(parts) >= 2 {
                                        let prompt = str_trim(array_get(parts, 0))
                                        let response = str_trim(array_get(parts, 1))
                                        training_data = dataset_add(training_data, prompt, response)
                                        // Also add to TUI table
                                        let row = array_new()
                                        row = array_push(row, prompt)
                                        row = array_push(row, response)
                                        ui_data_add_row("data", row)
                                        ui_terminal_push("nexus", "Added pair #" + int_to_str(dataset_len(training_data)))
                                    } else {
                                        ui_terminal_push("nexus", "Format: /data add prompt text|response text")
                                    }
                                }
                                if str_eq(action, "data_view") {
                                    let preview = dataset_preview(training_data, 10)
                                    let plines = str_lines(preview)
                                    let pi = 0
                                    while pi < array_len(plines) {
                                        ui_terminal_push("nexus", array_get(plines, pi))
                                        pi = pi + 1
                                    }
                                }
                                if starts_with(action, "mode|") {
                                    let new_mode = str_slice(action, 5, str_len(action))
                                    // Clean up old mode
                                    ui_editor_clear_highlights("code")
                                    if str_eq(nexus_mode, "coauthor") {
                                        // Remove coauthor file tabs
                                        let ci = 0
                                        while ci < array_len(coauthor_tabs) {
                                            ui_tab_remove(array_get(coauthor_tabs, ci))
                                            ci = ci + 1
                                        }
                                        coauthor_tabs = array_new()
                                    }
                                    // Set new mode
                                    nexus_mode = new_mode
                                    let mode_upper = str_upper(nexus_mode)
                                    ui_set_mode(mode_upper)
                                    ui_terminal_push("nexus", "Mode: " + mode_upper)
                                    ui_status(mode_upper + " — " + model_short(model))
                                    // Auto-share code in mentor and coauthor modes
                                    if str_eq(nexus_mode, "mentor") {
                                        code_shared = true
                                        ui_terminal_push("nexus", "Code sharing enabled (mentor needs to see your code).")
                                    }
                                    if str_eq(nexus_mode, "coauthor") {
                                        code_shared = true
                                        ui_terminal_push("nexus", "Code sharing enabled. I can create file tabs for you.")
                                    }
                                }
                            } else {
                                // Regular message
                                let event = hormone_detect_event(value)
                                hormones = hormone_update(hormones, event)

                                // Build code context
                                let code_ctx = ""

                                if pending_share {
                                    let answer = str_lower(str_trim(value))
                                    if str_eq(answer, "yes") {
                                        code_shared = true
                                        pending_share = false
                                        code_ctx = ui_get_text("code")
                                        let lc = array_len(str_lines(code_ctx))
                                        ui_terminal_push("nexus", "Got it! Reading your code (" + int_to_str(lc) + " lines)...")
                                    } else {
                                        if str_eq(answer, "y") {
                                            code_shared = true
                                            pending_share = false
                                            code_ctx = ui_get_text("code")
                                            let lc = array_len(str_lines(code_ctx))
                                            ui_terminal_push("nexus", "Got it! Reading your code (" + int_to_str(lc) + " lines)...")
                                        } else {
                                            if str_eq(answer, "no") {
                                                pending_share = false
                                                ui_terminal_push("nexus", "No problem! Ask anytime or use /share.")
                                            } else {
                                                if str_eq(answer, "n") {
                                                    pending_share = false
                                                    ui_terminal_push("nexus", "No problem! Ask anytime or use /share.")
                                                } else {
                                                    // They typed something else — treat as a normal message, cancel share prompt
                                                    pending_share = false
                                                }
                                            }
                                        }
                                    }
                                }

                                // If watch mode or code was shared, include it
                                if code_shared {
                                    code_ctx = ui_get_text("code")
                                }

                                // If message is about code but we don't have context, ask
                                if str_len(code_ctx) == 0 {
                                    if message_is_about_code(value) {
                                        ui_terminal_push("nexus", "It sounds like you're asking about your code.")
                                        ui_terminal_push("nexus", "Want me to read it? (say 'yes' or use /share)")
                                        ui_terminal_push("nexus", "")
                                        pending_share = true
                                        ui_draw()
                                    }
                                }

                                // If not pending a share question, proceed with API call
                                if pending_share == false {
                                    ui_terminal_push("nexus", "  ...")
                                    ui_status("Thinking...")
                                    ui_draw()

                                    let result = handle_nexus_message(value, model, api_keys, key_idx, history, notes, hormones, code_ctx, nexus_mode)
                                    let response = array_get(result, 0)
                                    let new_idx = array_get(result, 1)
                                    let should_save = array_get(result, 2)

                                    if str_eq(new_idx, "0") { key_idx = 0 }
                                    if str_eq(new_idx, "1") { key_idx = 1 }
                                    if str_eq(new_idx, "2") { key_idx = 2 }

                                    // Display response with mode prefix
                                    let resp_lines = str_lines(response)
                                    let ri = 0
                                    while ri < array_len(resp_lines) {
                                        ui_terminal_push("nexus", array_get(resp_lines, ri))
                                        ri = ri + 1
                                    }
                                    ui_terminal_push("nexus", "")
                                    ui_draw()

                                    // Mode-specific post-processing
                                    if str_eq(nexus_mode, "mentor") {
                                        apply_mentor_highlights(response)
                                        ui_draw()
                                    }
                                    if str_eq(nexus_mode, "coauthor") {
                                        coauthor_tabs = apply_coauthor_files(response, coauthor_tabs)
                                        ui_draw()
                                    }

                                    if str_eq(should_save, "true") {
                                        history = array_push(history, value)
                                        history = array_push(history, response)
                                        if array_len(history) > 40 {
                                            history = array_slice(history, array_len(history) - 40, array_len(history))
                                        }
                                    }

                                    let mode_upper = str_upper(nexus_mode)
                                    ui_status(mode_upper + " — " + model_short(model) + " — " + hormone_get_mood(hormones))
                                }
                            }
                        }
                    }
                }

                // Handle Nexus toggle
                if str_eq(kind, "toggle") {
                    if str_eq(target, "nexus") {
                        if str_eq(value, "true") {
                            ui_terminal_push("nexus", "Nexus awakened.")
                            ui_status("Nexus AWAKE — " + model_short(model))
                        } else {
                            ui_terminal_push("nexus", "Nexus silenced.")
                            ui_status("Nexus silent")
                        }
                    }
                }

                // Handle mode cycle (Ctrl+M)
                if str_eq(kind, "mode_cycle") {
                    ui_editor_clear_highlights("code")
                    if str_eq(nexus_mode, "observer") {
                        nexus_mode = "mentor"
                    } else {
                        if str_eq(nexus_mode, "mentor") {
                            nexus_mode = "coauthor"
                        } else {
                            nexus_mode = "observer"
                        }
                    }
                    let mode_upper = str_upper(nexus_mode)
                    ui_set_mode(mode_upper)
                    ui_terminal_push("nexus", "Mode: " + mode_upper)
                    ui_status(mode_upper + " — " + model_short(model))
                    if str_eq(nexus_mode, "mentor") {
                        code_shared = true
                    }
                    if str_eq(nexus_mode, "coauthor") {
                        code_shared = true
                    }
                    if str_eq(nexus_mode, "observer") {
                        // Clean up coauthor tabs
                        let ci = 0
                        while ci < array_len(coauthor_tabs) {
                            ui_tab_remove(array_get(coauthor_tabs, ci))
                            ci = ci + 1
                        }
                        coauthor_tabs = array_new()
                    }
                    ui_draw()
                }

                // Handle Run Code (F5 / Ctrl+R / Run button)
                if str_eq(kind, "run") {
                    let code = ui_get_text("code")
                    if str_len(str_trim(code)) > 0 {
                        let tmp_path = "/tmp/lair_run.sy"
                        write_file(tmp_path, code)

                        // Open popup for output
                        ui_popup_open("Run Output")
                        ui_popup_push("Running code...")
                        ui_popup_push("")
                        ui_status("Running...")
                        ui_draw()

                        // Execute (still blocking, but popup shows immediately)
                        let output = shell_exec("timeout 30 /home/kishonic/scyla/compiler/target/debug/scylac run " + tmp_path + " 2>&1")

                        if str_len(str_trim(output)) == 0 {
                            ui_popup_push("(no output)")
                        } else {
                            let out_lines = str_lines(output)
                            let oi = 0
                            while oi < array_len(out_lines) {
                                ui_popup_push(array_get(out_lines, oi))
                                oi = oi + 1
                            }
                        }
                        ui_popup_push("")
                        ui_popup_push("--- Done ---")
                        ui_popup_done()

                        // Also push to Nexus terminal for history
                        ui_terminal_push("nexus", "--- Ran code ---")

                        let mode_upper = str_upper(nexus_mode)
                        ui_status(mode_upper + " — " + model_short(model))
                        ui_draw()
                    } else {
                        ui_terminal_push("nexus", "No code to run.")
                        ui_draw()
                    }
                }

                // Handle button presses
                if str_eq(kind, "button") {
                    // target = event_id, value = label
                    if str_eq(target, "run_code") {
                        let code = ui_get_text("code")
                        if str_len(str_trim(code)) > 0 {
                            let tmp_path = "/tmp/lair_run.sy"
                            write_file(tmp_path, code)
                            ui_popup_open("Run Output")
                            ui_popup_push("Running code...")
                            ui_popup_push("")
                            ui_status("Running...")
                            ui_draw()
                            let output = shell_exec("timeout 30 /home/kishonic/scyla/compiler/target/debug/scylac run " + tmp_path + " 2>&1")
                            if str_len(str_trim(output)) == 0 {
                                ui_popup_push("(no output)")
                            } else {
                                let out_lines = str_lines(output)
                                let oi = 0
                                while oi < array_len(out_lines) {
                                    ui_popup_push(array_get(out_lines, oi))
                                    oi = oi + 1
                                }
                            }
                            ui_popup_push("")
                            ui_popup_push("--- Done ---")
                            ui_popup_done()
                            ui_terminal_push("nexus", "--- Ran code ---")
                            let mode_upper = str_upper(nexus_mode)
                            ui_status(mode_upper + " — " + model_short(model))
                        }
                        ui_draw()
                    }
                    if str_eq(target, "save_code") {
                        let code = ui_get_text("code")
                        let save_path = "/home/kishonic/scyla/examples/lair_saved.sy"
                        write_file(save_path, code)
                        ui_terminal_push("nexus", "Saved to " + save_path)
                        ui_status("Saved!")
                        ui_draw()
                    }
                    if str_eq(target, "open_code") {
                        // Load from saved file
                        let load_path = "/home/kishonic/scyla/examples/lair_saved.sy"
                        let content = read_file(load_path)
                        if starts_with(content, "error:") {
                            ui_terminal_push("nexus", "No saved file found at " + load_path)
                        } else {
                            ui_set_text("code", content)
                            ui_terminal_push("nexus", "Opened " + load_path)
                        }
                        ui_status("Nexus: " + model_short(model))
                        ui_draw()
                    }
                    if str_eq(target, "new_code") {
                        ui_set_text("code", "// New file\n\nfn main() \{\n    \n\}")
                        ui_terminal_push("nexus", "New file created.")
                        ui_status("Nexus: " + model_short(model))
                        ui_draw()
                    }
                }

                // Next event
                ev = ui_poll_event()
            }
        }
    }

    // ── Cleanup ──
    ui_cleanup()
    session_save(model, history)
    println("Session saved. See you in the Lair.")
}
