#include "lumacs/mode_activator.hpp"
#include "lumacs/editor_core.hpp"
#include "lumacs/minibuffer_manager.hpp"
#include "lumacs/lua_api.hpp"
#include <algorithm>

namespace lumacs {

ModeActivator::ModeActivator(EditorCore& core)
    : core_(core) {}

bool ModeActivator::handle_mode_event(EditorEvent event, QuitCallback quit_callback) {
    switch (event) {
        case EditorEvent::CommandMode:
            activate_command_mode(quit_callback);
            return true;

        case EditorEvent::BufferSwitchMode:
            activate_buffer_switch_mode();
            return true;

        case EditorEvent::KillBufferMode:
            activate_kill_buffer_mode();
            return true;

        case EditorEvent::FindFileMode:
            activate_find_file_mode();
            return true;

        case EditorEvent::ThemeSelectionMode:
            activate_theme_selection_mode();
            return true;

        case EditorEvent::ISearchMode:
            activate_isearch_mode(true);
            return true;

        case EditorEvent::ISearchBackwardMode:
            activate_isearch_mode(false);
            return true;

        default:
            return false;
    }
}

void ModeActivator::activate_command_mode(QuitCallback quit_callback) {
    core_.minibuffer_manager().activate_minibuffer(
        MinibufferMode::Command, "M-x ",
        [this, quit_callback](const std::string& input) {
            if (input == "q" || input == "quit") {
                if (quit_callback) {
                    quit_callback();
                }
            } else {
                auto result = core_.minibuffer_manager().parse_and_execute_command_string(input);
                core_.set_message(result.message);
            }
        },
        [this]() { core_.set_message("Cancelled"); }
    );
}

void ModeActivator::activate_buffer_switch_mode() {
    core_.minibuffer_manager().activate_minibuffer(
        MinibufferMode::BufferName, "Switch to buffer: ",
        [this](const std::string& input) {
            if (core_.switch_buffer_in_window(input)) {
                core_.set_message("Switched to: " + input);
                // Trigger major mode auto-activation
                if (core_.lua_api()) {
                    core_.lua_api()->execute("auto_activate_major_mode()");
                }
            } else {
                core_.set_message("Buffer not found: " + input);
            }
        },
        [this]() { core_.set_message("Cancelled"); }
    );
}

void ModeActivator::activate_kill_buffer_mode() {
    core_.minibuffer_manager().activate_minibuffer(
        MinibufferMode::BufferName, "Kill buffer: ",
        [this](const std::string& input) {
            if (core_.close_buffer(input)) {
                core_.set_message("Killed buffer: " + input);
            } else {
                core_.set_message("Failed to kill buffer: " + input);
            }
        },
        [this]() { core_.set_message("Cancelled"); }
    );
}

void ModeActivator::activate_find_file_mode() {
    core_.minibuffer_manager().activate_minibuffer(
        MinibufferMode::FilePath, "Find file: ",
        [this](const std::string& input) {
            if (core_.load_file(input)) {
                core_.set_message("Loaded: " + input);
                // Trigger major mode auto-activation and recentf tracking
                if (core_.lua_api()) {
                    core_.lua_api()->execute("auto_activate_major_mode()");
                    // Track in recent files if recentf is loaded
                    core_.lua_api()->execute(
                        "if lumacs.recentf_track then lumacs.recentf_track('" + input + "') end");
                }
            } else {
                core_.set_message("Failed to load: " + input);
            }
        },
        [this]() { core_.set_message("Cancelled"); }
    );
}

void ModeActivator::activate_theme_selection_mode() {
    core_.minibuffer_manager().activate_minibuffer(
        MinibufferMode::ThemeName, "Set theme: ",
        [this](const std::string& input) {
            auto theme_names = core_.theme_manager().theme_names();
            auto it = std::find(theme_names.begin(), theme_names.end(), input);
            if (it != theme_names.end()) {
                core_.theme_manager().set_active_theme(input);
                core_.set_message("Switched to theme: " + input);
            } else {
                core_.set_message("Theme not found: " + input);
            }
        },
        [this]() { core_.set_message("Cancelled"); }
    );
}

void ModeActivator::activate_isearch_mode(bool forward) {
    std::string prompt = forward ? "I-search: " : "I-search backward: ";
    std::string cancel_msg = forward ? "Cancelled I-search" : "Cancelled I-search backward";

    core_.minibuffer_manager().activate_minibuffer(
        MinibufferMode::ISearch, prompt,
        [](const std::string&) { /* Submit handled by return key in isearch */ },
        [this, cancel_msg]() { core_.set_message(cancel_msg); }
    );
    core_.minibuffer_manager().start_isearch(forward);
}

} // namespace lumacs
