/*
 * DWN - Desktop Window Manager
 * retoor <retoor@molodetz.nl>
 * Demo mode - automated feature showcase
 */

#include "demo.h"
#include "dwn.h"
#include "notifications.h"
#include "workspace.h"
#include "client.h"
#include "layout.h"
#include "keys.h"
#include "ai.h"
#include "news.h"
#include "util.h"
#include "panel.h"
#include "config.h"

#include <string.h>

typedef struct {
    bool active;
    DemoPhase phase;
    int step;
    long phase_start_time;
    long step_start_time;
    uint32_t current_notification;
    Window demo_window;
    int demo_workspace_start;
    LayoutType original_layout;

    DemoWaitCondition wait_condition;
    long wait_timeout;
    long wait_started;

    AIRequest *pending_ai_request;
    ExaRequest *pending_exa_request;
    bool ai_demo_completed;
    bool exa_demo_completed;
    char ai_response_buffer[1024];
    char exa_response_buffer[1024];
} DemoState;

static DemoState demo = {0};

static void demo_notify(const char *title, const char *body, int timeout)
{
    if (demo.current_notification > 0) {
        notification_close(demo.current_notification);
    }
    demo.current_notification = notification_show("DWN Demo", title, body, NULL, timeout);
}

static int demo_get_step_delay(void)
{
    if (dwn != NULL && dwn->config != NULL) {
        return dwn->config->demo_step_delay_ms;
    }
    return 4000;
}

static int demo_get_ai_timeout(void)
{
    if (dwn != NULL && dwn->config != NULL) {
        return dwn->config->demo_ai_timeout_ms;
    }
    return 15000;
}

static void demo_wait_for(DemoWaitCondition condition, int timeout_ms)
{
    demo.wait_condition = condition;
    demo.wait_timeout = timeout_ms;
    demo.wait_started = get_time_ms();
}

static bool demo_check_wait_complete(void)
{
    if (demo.wait_condition == DEMO_WAIT_NONE) {
        return true;
    }

    long elapsed = get_time_ms() - demo.wait_started;

    switch (demo.wait_condition) {
    case DEMO_WAIT_NONE:
        return true;

    case DEMO_WAIT_TIME:
        if (elapsed >= demo.wait_timeout) {
            demo.wait_condition = DEMO_WAIT_NONE;
            return true;
        }
        return false;

    case DEMO_WAIT_WINDOW_SPAWN:
        if (demo.demo_window != None) {
            Client *c = client_find_by_window(demo.demo_window);
            if (c != NULL) {
                demo.wait_condition = DEMO_WAIT_NONE;
                return true;
            }
        }
        if (elapsed >= demo.wait_timeout) {
            demo.wait_condition = DEMO_WAIT_NONE;
            return true;
        }
        return false;

    case DEMO_WAIT_AI_RESPONSE:
        if (demo.ai_demo_completed) {
            demo.wait_condition = DEMO_WAIT_NONE;
            return true;
        }
        if (elapsed >= demo.wait_timeout) {
            demo_notify("AI Timeout", "AI request timed out. Continuing demo...", 2000);
            demo.wait_condition = DEMO_WAIT_NONE;
            if (demo.pending_ai_request != NULL) {
                ai_cancel_request(demo.pending_ai_request);
                demo.pending_ai_request = NULL;
            }
            return true;
        }
        return false;

    case DEMO_WAIT_EXA_RESPONSE:
        if (demo.exa_demo_completed) {
            demo.wait_condition = DEMO_WAIT_NONE;
            return true;
        }
        if (elapsed >= demo.wait_timeout) {
            demo_notify("Search Timeout", "Exa search timed out. Continuing demo...", 2000);
            demo.wait_condition = DEMO_WAIT_NONE;
            demo.pending_exa_request = NULL;
            return true;
        }
        return false;
    }

    return true;
}

static void demo_ai_callback(AIRequest *req)
{
    if (req == NULL || !demo.active) {
        return;
    }

    demo.pending_ai_request = NULL;
    demo.ai_demo_completed = true;

    if (req->state == AI_STATE_COMPLETED && req->response != NULL) {
        size_t resp_len = strlen(req->response);
        snprintf(demo.ai_response_buffer, sizeof(demo.ai_response_buffer),
                 "%s", req->response);

        char display_buf[512];
        snprintf(display_buf, sizeof(display_buf),
                 "AI Response:\n\n%.400s%s",
                 demo.ai_response_buffer,
                 resp_len > 400 ? "..." : "");
        demo_notify("AI Query Complete", display_buf, 6000);
    } else {
        snprintf(demo.ai_response_buffer, sizeof(demo.ai_response_buffer),
                 "Error: Failed to get response");
        demo_notify("AI Error", "Failed to get AI response", 3000);
    }
}

static void demo_exa_callback(ExaRequest *req)
{
    if (req == NULL || !demo.active) {
        return;
    }

    demo.pending_exa_request = NULL;
    demo.exa_demo_completed = true;

    if (req->state == AI_STATE_COMPLETED && req->result_count > 0) {
        char results_buf[800];
        size_t offset = 0;

        offset += snprintf(results_buf + offset, sizeof(results_buf) - offset,
                          "Found %d results:\n\n", req->result_count);

        for (int i = 0; i < req->result_count && i < 3; i++) {
            offset += snprintf(results_buf + offset, sizeof(results_buf) - offset,
                              "%d. %s\n", i + 1, req->results[i].title);
            if (offset >= sizeof(results_buf) - 50) break;
        }

        if (req->result_count > 3) {
            snprintf(results_buf + offset, sizeof(results_buf) - offset,
                    "\n... and %d more", req->result_count - 3);
        }

        snprintf(demo.exa_response_buffer, sizeof(demo.exa_response_buffer),
                 "%s", results_buf);
        demo_notify("Exa Search Complete", results_buf, 6000);
    } else {
        snprintf(demo.exa_response_buffer, sizeof(demo.exa_response_buffer),
                 "No results found");
        demo_notify("Exa Search", "No results found for query", 3000);
    }
}

static void demo_execute_snap_left(void)
{
    Workspace *ws = workspace_get_current();
    if (ws != NULL && ws->focused != NULL) {
        key_snap_left();
        demo_notify("Snap Left", "Window snapped to left half (50% width)", 2000);
    }
}

static void demo_execute_snap_right(void)
{
    Workspace *ws = workspace_get_current();
    if (ws != NULL && ws->focused != NULL) {
        key_snap_right();
        demo_notify("Snap Right", "Window snapped to right half (50% width)", 2000);
    }
}

static void demo_execute_ai_query(void)
{
    if (!ai_is_available()) {
        demo.ai_demo_completed = true;
        demo_notify("AI Unavailable",
                    "AI is not configured.\n\n"
                    "Set OPENROUTER_API_KEY to enable.", 3000);
        return;
    }

    demo.ai_demo_completed = false;
    demo.ai_response_buffer[0] = '\0';

    ai_update_context();

    Workspace *ws = workspace_get_current();
    char prompt[512];

    if (ws != NULL && ws->focused != NULL) {
        snprintf(prompt, sizeof(prompt),
                 "Describe what I'm working on based on this context: "
                 "Current window: %s, Window class: %s. "
                 "Keep the response brief (2-3 sentences).",
                 ws->focused->title, ws->focused->class);
    } else {
        snprintf(prompt, sizeof(prompt),
                 "I'm using a Linux window manager called DWN. "
                 "Describe what a typical desktop workspace looks like. "
                 "Keep the response brief (2-3 sentences).");
    }

    demo_notify("AI Query", "Asking AI: \"Describe my current workspace\"\n\nWaiting for response...", 0);
    demo.pending_ai_request = ai_send_request(prompt, demo_ai_callback);

    if (demo.pending_ai_request == NULL) {
        demo.ai_demo_completed = true;
        demo_notify("AI Error", "Failed to send AI request", 3000);
    }
}

static void demo_execute_exa_search(void)
{
    if (!exa_is_available()) {
        demo.exa_demo_completed = true;
        demo_notify("Exa Unavailable",
                    "Exa search is not configured.\n\n"
                    "Set EXA_API_KEY to enable semantic search.", 3000);
        return;
    }

    demo.exa_demo_completed = false;
    demo.exa_response_buffer[0] = '\0';

    demo_notify("Exa Search", "Searching: \"What does molodetz mean?\"\n\nWaiting for results...", 0);
    demo.pending_exa_request = exa_search("What does molodetz mean?", demo_exa_callback);

    if (demo.pending_exa_request == NULL) {
        demo.exa_demo_completed = true;
        demo_notify("Exa Error", "Failed to send search request", 3000);
    }
}

static void demo_next_phase(void)
{
    demo.phase++;
    demo.step = 0;
    demo.phase_start_time = get_time_ms();
    demo.step_start_time = demo.phase_start_time;
}

static void demo_next_step(void)
{
    demo.step++;
    demo.step_start_time = get_time_ms();
}

static void demo_phase_intro(void)
{
    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        demo_notify("Welcome to DWN",
            "DWN is a modern X11 window manager with:\n\n"
            "- Tiling, floating, and monocle layouts\n"
            "- 9 virtual workspaces\n"
            "- AI-powered command palette\n"
            "- News ticker with sentiment analysis\n"
            "- System tray and notifications\n\n"
            "This demo will showcase all features.\n"
            "Press Super+Shift+D to stop at any time.", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay() + 2000);
        demo_next_step();
        break;
    case 1:
        demo_next_phase();
        break;
    }
}

static void demo_phase_window_mgmt(void)
{
    Client *c;
    Workspace *ws;

    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        demo_notify("Window Management",
            "DWN provides complete window management:\n\n"
            "- Alt+F4: Close window\n"
            "- Alt+F9: Minimize/restore\n"
            "- Alt+F10: Maximize\n"
            "- Alt+F11: Fullscreen\n"
            "- Alt+Tab: Cycle windows\n\n"
            "Let's open a terminal...", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 1:
        spawn_async("xterm -title 'Demo Terminal' -e 'echo DWN Demo Terminal; sleep 60' &");
        demo_wait_for(DEMO_WAIT_TIME, 2000);
        demo_next_step();
        break;
    case 2:
        demo_notify("Window Created",
            "A terminal window was spawned.\n\n"
            "Windows can be moved by dragging the title bar\n"
            "or resized by dragging edges.\n\n"
            "Let's try minimizing...", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 3:
        ws = workspace_get_current();
        if (ws != NULL && ws->focused != NULL) {
            demo.demo_window = ws->focused->window;
            client_minimize(ws->focused);
            demo_notify("Window Minimized",
                "The window is now minimized.\n\n"
                "Look at the taskbar - minimized windows\n"
                "appear in [brackets] with a gray background.\n\n"
                "Click it or press Alt+F9 to restore.", 0);
        }
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 4:
        c = client_find_by_window(demo.demo_window);
        if (c != NULL) {
            client_restore(c);
            demo_notify("Window Restored",
                "The window is restored from the taskbar.\n\n"
                "This is how minimize/restore works in DWN.", 0);
        }
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 5:
        c = client_find_by_window(demo.demo_window);
        if (c != NULL) {
            client_close(c);
        }
        demo.demo_window = None;
        demo_next_phase();
        break;
    }
}

static void demo_phase_workspaces(void)
{
    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        demo.demo_workspace_start = dwn->current_workspace;
        demo_notify("Virtual Workspaces",
            "DWN provides 9 virtual workspaces:\n\n"
            "- F1 to F9: Switch workspace\n"
            "- Shift+F1-F9: Move window to workspace\n"
            "- Ctrl+Alt+Left/Right: Navigate\n"
            "- Super+Shift+Left/Right: Move window\n\n"
            "Watch the workspace indicators in the panel...", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 1:
        workspace_switch(1);
        demo_notify("Workspace 2", "Switched to workspace 2", 1500);
        demo_wait_for(DEMO_WAIT_TIME, 2000);
        demo_next_step();
        break;
    case 2:
        workspace_switch(2);
        demo_notify("Workspace 3", "Switched to workspace 3", 1500);
        demo_wait_for(DEMO_WAIT_TIME, 2000);
        demo_next_step();
        break;
    case 3:
        workspace_switch(3);
        demo_notify("Workspace 4", "Switched to workspace 4", 1500);
        demo_wait_for(DEMO_WAIT_TIME, 2000);
        demo_next_step();
        break;
    case 4:
        workspace_switch(demo.demo_workspace_start);
        demo_notify("Workspaces Complete",
            "Returned to the original workspace.\n\n"
            "Each workspace maintains its own:\n"
            "- Window layout and positions\n"
            "- Focused window\n"
            "- Layout mode (tiling/floating/monocle)", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 5:
        demo_next_phase();
        break;
    }
}

static void demo_phase_layouts(void)
{
    Workspace *ws = workspace_get_current();

    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        demo_notify("Layout Modes",
            "DWN supports 3 layout modes:\n\n"
            "1. Tiling: Windows auto-arrange without overlap\n"
            "2. Floating: Free positioning like traditional WMs\n"
            "3. Monocle: One window fullscreen at a time\n\n"
            "Press Super+Space to cycle layouts.", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 1:
        if (ws != NULL) {
            ws->layout = LAYOUT_TILING;
            workspace_arrange_current();
        }
        demo_notify("Tiling Layout",
            "In tiling mode, windows are automatically\n"
            "arranged in a main + stack pattern.\n\n"
            "- Super+H/L: Resize main area\n"
            "- Super+I/D: Add/remove from main\n\n"
            "No overlapping windows - efficient use of space.", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 2:
        if (ws != NULL) {
            ws->layout = LAYOUT_FLOATING;
            workspace_arrange_current();
        }
        demo_notify("Floating Layout",
            "In floating mode, windows can be freely\n"
            "positioned and resized anywhere.\n\n"
            "This is the traditional desktop behavior\n"
            "familiar from Windows and macOS.", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 3:
        if (ws != NULL) {
            ws->layout = LAYOUT_MONOCLE;
            workspace_arrange_current();
        }
        demo_notify("Monocle Layout",
            "In monocle mode, each window takes\n"
            "the full screen.\n\n"
            "Use Alt+Tab to switch between windows.\n"
            "Great for focused, single-task work.", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 4:
        if (ws != NULL) {
            ws->layout = demo.original_layout;
            workspace_arrange_current();
        }
        demo_next_phase();
        break;
    }
}

static void demo_phase_snapping(void)
{
    Workspace *ws;

    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        ws = workspace_get_current();
        if (ws == NULL || ws->focused == NULL) {
            demo_notify("Window Snapping",
                "Snapping requires a window to demonstrate.\n\n"
                "Spawning a demo terminal...", 0);
            spawn_async("xterm -title 'Snap Demo' -e 'sleep 60' &");
            demo_wait_for(DEMO_WAIT_TIME, 2000);
        }
        demo_next_step();
        break;
    case 1:
        demo_notify("Window Snapping",
            "Quickly arrange windows with snapping:\n\n"
            "- Super+Left: Snap to left half (50%)\n"
            "- Super+Right: Snap to right half (50%)\n\n"
            "Watch the focused window snap to the left...", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 2:
        demo_execute_snap_left();
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 3:
        demo_notify("Snap Right",
            "Now snapping the window to the right half...", 0);
        demo_wait_for(DEMO_WAIT_TIME, 1500);
        demo_next_step();
        break;
    case 4:
        demo_execute_snap_right();
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 5:
        demo_notify("Snapping Complete",
            "Window snapping allows quick side-by-side layouts.\n\n"
            "Perfect for comparing documents, coding with\n"
            "documentation open, or multitasking.", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 6:
        demo_next_phase();
        break;
    }
}

static void demo_phase_panels(void)
{
    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        demo_notify("Panel System",
            "DWN has two configurable panels:\n\n"
            "TOP PANEL (left to right):\n"
            "- Workspace indicators (click to switch)\n"
            "- Layout mode indicator (T/F/M)\n"
            "- Taskbar with window titles\n"
            "- AI status indicator\n"
            "- System tray icons", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay() + 1000);
        demo_next_step();
        break;
    case 1:
        demo_notify("Taskbar Features",
            "The taskbar shows all windows on the workspace:\n\n"
            "- Click a window title to focus it\n"
            "- Minimized windows shown in [brackets]\n"
            "- Focused window is highlighted\n"
            "- Right-click for window menu", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 2:
        demo_notify("System Tray",
            "The system tray supports XEmbed protocol:\n\n"
            "- Battery indicator (color-coded by level)\n"
            "- WiFi status (click for network list)\n"
            "- Volume control (scroll to adjust)\n"
            "- External app icons (Telegram, nm-applet, etc.)\n\n"
            "Applications can dock their status icons here.", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay() + 1000);
        demo_next_step();
        break;
    case 3:
        demo_notify("Bottom Panel",
            "BOTTOM PANEL contains:\n\n"
            "- Clock with current time and date\n"
            "- News ticker with scrolling headlines\n\n"
            "Headlines are color-coded by sentiment:\n"
            "  Green = Positive news\n"
            "  Red = Negative news\n"
            "  White = Neutral", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 4:
        demo_next_phase();
        break;
    }
}

static void demo_phase_ai(void)
{
    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        demo_notify("AI Integration",
            "DWN includes AI-powered features:\n\n"
            "COMMAND PALETTE (Super+Shift+A):\n"
            "- Ask AI to launch apps: 'open firefox'\n"
            "- Get answers: 'what time is it'\n"
            "- Execute commands naturally\n\n"
            "CONTEXT ANALYSIS (Super+A):\n"
            "- See what you're working on\n"
            "- Get AI suggestions based on context", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay() + 1000);
        demo_next_step();
        break;
    case 1:
        demo_notify("Live AI Demo",
            "Let's try a live AI query...\n\n"
            "Asking: \"Describe my current workspace\"", 0);
        demo_wait_for(DEMO_WAIT_TIME, 2000);
        demo_next_step();
        break;
    case 2:
        demo_execute_ai_query();
        if (ai_is_available()) {
            demo_wait_for(DEMO_WAIT_AI_RESPONSE, demo_get_ai_timeout());
        } else {
            demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        }
        demo_next_step();
        break;
    case 3:
        demo_notify("Exa Semantic Search",
            "DWN also includes Exa semantic search:\n\n"
            "EXA SEARCH (Super+Shift+E):\n"
            "- Search the web by meaning, not just keywords\n"
            "- Find relevant documentation and articles\n"
            "- Results open in your default browser", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 4:
        demo_notify("Live Exa Demo",
            "Let's try a live Exa search...\n\n"
            "Searching: \"What does molodetz mean?\"", 0);
        demo_wait_for(DEMO_WAIT_TIME, 2000);
        demo_next_step();
        break;
    case 5:
        demo_execute_exa_search();
        if (exa_is_available()) {
            demo_wait_for(DEMO_WAIT_EXA_RESPONSE, demo_get_ai_timeout());
        } else {
            demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        }
        demo_next_step();
        break;
    case 6:
        if (ai_is_available() || exa_is_available()) {
            demo_notify("AI Features Complete",
                "AI integration provides intelligent assistance\n"
                "directly within your window manager.\n\n"
                "No need to switch to a browser or separate app\n"
                "to get quick answers or find information.", 0);
        } else {
            demo_notify("AI Features",
                "To enable AI features, configure API keys:\n\n"
                "OPENROUTER_API_KEY=sk-or-v1-your-key\n"
                "EXA_API_KEY=your-exa-key\n\n"
                "Add to ~/.config/dwn/config or set as\n"
                "environment variables, then restart DWN.", 0);
        }
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 7:
        demo_next_phase();
        break;
    }
}

static void demo_phase_news(void)
{
    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        demo_notify("News Ticker",
            "The bottom panel includes a news ticker:\n\n"
            "- Headlines scroll automatically\n"
            "- Color-coded by sentiment:\n"
            "  Green = Positive\n"
            "  Red = Negative\n"
            "  White = Neutral\n\n"
            "CONTROLS:\n"
            "- Super+Down: Next article\n"
            "- Super+Up: Previous article\n"
            "- Super+Return: Open in browser", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay());
        demo_next_step();
        break;
    case 1:
        news_next_article();
        demo_notify("News Navigation", "Moved to next article", 1500);
        demo_wait_for(DEMO_WAIT_TIME, 2000);
        demo_next_step();
        break;
    case 2:
        news_next_article();
        demo_notify("News Navigation", "Moved to next article", 1500);
        demo_wait_for(DEMO_WAIT_TIME, 2000);
        demo_next_step();
        break;
    case 3:
        news_prev_article();
        demo_notify("News Navigation", "Moved to previous article", 1500);
        demo_wait_for(DEMO_WAIT_TIME, 2000);
        demo_next_step();
        break;
    case 4:
        demo_next_phase();
        break;
    }
}

static void demo_phase_shortcuts(void)
{
    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        demo_notify("Quick Reference",
            "ESSENTIAL SHORTCUTS:\n\n"
            "Ctrl+Alt+T    Open terminal\n"
            "Super         App launcher\n"
            "Alt+F4        Close window\n"
            "Alt+Tab       Cycle windows\n"
            "Super+Space   Cycle layouts\n\n"
            "WORKSPACES:\n"
            "F1-F9         Switch workspace\n"
            "Shift+F1-F9   Move window\n\n"
            "WINDOW CONTROL:\n"
            "Alt+F9        Minimize/restore\n"
            "Alt+F10       Maximize\n"
            "Alt+F11       Fullscreen\n"
            "Super+Left    Snap left\n"
            "Super+Right   Snap right\n\n"
            "Press Super+S anytime to see all shortcuts.", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay() * 2);
        demo_next_step();
        break;
    case 1:
        demo_next_phase();
        break;
    }
}

static void demo_phase_complete(void)
{
    if (!demo_check_wait_complete()) {
        return;
    }

    switch (demo.step) {
    case 0:
        demo_notify("Demo Complete",
            "Thank you for watching the DWN demo!\n\n"
            "NEXT STEPS:\n"
            "- Super+T: Start interactive tutorial\n"
            "- Super+S: View all shortcuts\n"
            "- Super+Shift+D: Run this demo again\n\n"
            "CONFIGURATION:\n"
            "Edit ~/.config/dwn/config to customize\n"
            "colors, fonts, keybindings, and more.\n\n"
            "Enjoy using DWN!", 0);
        demo_wait_for(DEMO_WAIT_TIME, demo_get_step_delay() + 2000);
        demo_next_step();
        break;
    case 1:
        notification_close(demo.current_notification);
        demo.current_notification = 0;
        demo.active = false;
        demo.phase = DEMO_IDLE;
        break;
    }
}

void demo_init(void)
{
    memset(&demo, 0, sizeof(demo));
    demo.phase = DEMO_IDLE;
}

void demo_cleanup(void)
{
    if (demo.current_notification > 0) {
        notification_close(demo.current_notification);
    }
    memset(&demo, 0, sizeof(demo));
}

void demo_start(void)
{
    if (demo.active) {
        demo_stop();
        return;
    }

    if (tutorial_is_active()) {
        demo_notify("Demo Unavailable",
            "Cannot start demo while tutorial is running.\n"
            "Please complete or stop the tutorial first.", 3000);
        return;
    }

    memset(&demo, 0, sizeof(demo));

    demo.active = true;
    demo.phase = DEMO_INTRO;
    demo.step = 0;
    demo.phase_start_time = get_time_ms();
    demo.step_start_time = demo.phase_start_time;
    demo.demo_workspace_start = dwn->current_workspace;
    demo.demo_window = None;

    Workspace *ws = workspace_get_current();
    if (ws != NULL) {
        demo.original_layout = ws->layout;
    }

    demo.wait_condition = DEMO_WAIT_NONE;
    demo.pending_ai_request = NULL;
    demo.pending_exa_request = NULL;
    demo.ai_demo_completed = false;
    demo.exa_demo_completed = false;
    demo.ai_response_buffer[0] = '\0';
    demo.exa_response_buffer[0] = '\0';
}

void demo_stop(void)
{
    if (!demo.active) {
        return;
    }

    if (demo.pending_ai_request != NULL) {
        ai_cancel_request(demo.pending_ai_request);
        demo.pending_ai_request = NULL;
    }

    demo.pending_exa_request = NULL;

    if (demo.current_notification > 0) {
        notification_close(demo.current_notification);
        demo.current_notification = 0;
    }

    Workspace *ws = workspace_get_current();
    if (ws != NULL && demo.original_layout != ws->layout) {
        ws->layout = demo.original_layout;
        workspace_arrange_current();
    }

    demo_notify("Demo Stopped", "Demo mode has been stopped.", 2000);

    demo.active = false;
    demo.phase = DEMO_IDLE;
    demo.step = 0;
    demo.wait_condition = DEMO_WAIT_NONE;
}

void demo_update(void)
{
    if (!demo.active) {
        return;
    }

    switch (demo.phase) {
    case DEMO_IDLE:
        break;
    case DEMO_INTRO:
        demo_phase_intro();
        break;
    case DEMO_WINDOW_MGMT:
        demo_phase_window_mgmt();
        break;
    case DEMO_WORKSPACES:
        demo_phase_workspaces();
        break;
    case DEMO_LAYOUTS:
        demo_phase_layouts();
        break;
    case DEMO_SNAPPING:
        demo_phase_snapping();
        break;
    case DEMO_PANELS:
        demo_phase_panels();
        break;
    case DEMO_AI:
        demo_phase_ai();
        break;
    case DEMO_NEWS:
        demo_phase_news();
        break;
    case DEMO_SHORTCUTS:
        demo_phase_shortcuts();
        break;
    case DEMO_COMPLETE:
        demo_phase_complete();
        break;
    }
}

bool demo_is_active(void)
{
    return demo.active;
}

DemoPhase demo_get_phase(void)
{
    return demo.phase;
}

int demo_get_step(void)
{
    return demo.step;
}

const char *demo_get_phase_name(DemoPhase phase)
{
    switch (phase) {
    case DEMO_IDLE: return "Idle";
    case DEMO_INTRO: return "Introduction";
    case DEMO_WINDOW_MGMT: return "Window Management";
    case DEMO_WORKSPACES: return "Workspaces";
    case DEMO_LAYOUTS: return "Layouts";
    case DEMO_SNAPPING: return "Snapping";
    case DEMO_PANELS: return "Panels";
    case DEMO_AI: return "AI Features";
    case DEMO_NEWS: return "News Ticker";
    case DEMO_SHORTCUTS: return "Shortcuts";
    case DEMO_COMPLETE: return "Complete";
    default: return "Unknown";
    }
}
