#pragma once

#include "foundation/result.h"

#include <string_view>

namespace pp::app {

enum class ToolsMenuCommand {
    panels,
    options,
    clear_grids,
    reset_camera,
    shortcuts,
    sonarpen,
};

enum class ToolsMenuAction {
    show_panels_submenu,
    show_options_submenu,
    clear_grid_overlays,
    reset_camera,
    show_shortcuts_dialog,
    start_sonarpen,
    no_op_unavailable,
};

enum class ToolsPanel {
    presets,
    color,
    color_advanced,
    layers,
    brush,
    grids,
    animation,
};

enum class ToolsPanelAction {
    open_floating_panel,
    no_op_already_visible,
};

struct ToolsMenuPlan {
    ToolsMenuCommand command = ToolsMenuCommand::panels;
    ToolsMenuAction action = ToolsMenuAction::show_panels_submenu;
    std::string_view label;
    bool closes_root_popup = false;
};

struct ToolsPanelPlan {
    ToolsPanel panel = ToolsPanel::presets;
    ToolsPanelAction action = ToolsPanelAction::open_floating_panel;
    std::string_view title;
    int width = 0;
    int height = 0;
    int min_width = 0;
    int min_height = 0;
    bool droppable = true;
    bool hides_embedded_title = false;
};

class ToolsMenuServices {
public:
    virtual ~ToolsMenuServices() = default;

    virtual void show_panels_submenu() = 0;
    virtual void show_options_submenu() = 0;
    virtual void clear_grid_overlays() = 0;
    virtual void reset_camera() = 0;
    virtual void show_shortcuts_dialog() = 0;
    virtual void start_sonarpen() = 0;
};

[[nodiscard]] constexpr ToolsMenuPlan plan_tools_menu_command(
    ToolsMenuCommand command,
    bool sonarpen_available = false) noexcept
{
    switch (command) {
    case ToolsMenuCommand::panels:
        return { command, ToolsMenuAction::show_panels_submenu, "Panels", false };
    case ToolsMenuCommand::options:
        return { command, ToolsMenuAction::show_options_submenu, "Options", false };
    case ToolsMenuCommand::clear_grids:
        return { command, ToolsMenuAction::clear_grid_overlays, "Clear Grids", true };
    case ToolsMenuCommand::reset_camera:
        return { command, ToolsMenuAction::reset_camera, "Reset Camera", true };
    case ToolsMenuCommand::shortcuts:
        return { command, ToolsMenuAction::show_shortcuts_dialog, "Shortcuts", true };
    case ToolsMenuCommand::sonarpen:
        return {
            command,
            sonarpen_available ? ToolsMenuAction::start_sonarpen : ToolsMenuAction::no_op_unavailable,
            "SonarPen",
            sonarpen_available,
        };
    }

    return { command, ToolsMenuAction::no_op_unavailable, "", false };
}

[[nodiscard]] constexpr ToolsPanelPlan plan_tools_panel(
    ToolsPanel panel,
    bool already_visible) noexcept
{
    ToolsPanelPlan plan;
    plan.panel = panel;
    plan.action = already_visible
        ? ToolsPanelAction::no_op_already_visible
        : ToolsPanelAction::open_floating_panel;

    switch (panel) {
    case ToolsPanel::presets:
        plan.title = "Brushes";
        plan.height = 300;
        plan.min_height = 300;
        plan.min_width = 100;
        break;
    case ToolsPanel::color:
        plan.title = "Color Picker";
        plan.height = 300;
        plan.hides_embedded_title = true;
        break;
    case ToolsPanel::color_advanced:
        plan.title = "Color Picker";
        plan.width = 300;
        plan.height = 300;
        break;
    case ToolsPanel::layers:
        plan.title = "Layers";
        plan.height = 300;
        plan.min_height = 100;
        plan.hides_embedded_title = true;
        break;
    case ToolsPanel::brush:
        plan.title = "Brush Settings";
        plan.height = 300;
        plan.hides_embedded_title = true;
        break;
    case ToolsPanel::grids:
        plan.title = "Grid";
        plan.height = 300;
        plan.hides_embedded_title = true;
        break;
    case ToolsPanel::animation:
        plan.title = "Animation";
        plan.width = 500;
        plan.height = 300;
        plan.droppable = false;
        break;
    }

    return plan;
}

[[nodiscard]] inline pp::foundation::Status execute_tools_menu_plan(
    const ToolsMenuPlan& plan,
    ToolsMenuServices& services)
{
    switch (plan.action) {
    case ToolsMenuAction::show_panels_submenu:
        services.show_panels_submenu();
        return pp::foundation::Status::success();
    case ToolsMenuAction::show_options_submenu:
        services.show_options_submenu();
        return pp::foundation::Status::success();
    case ToolsMenuAction::clear_grid_overlays:
        services.clear_grid_overlays();
        return pp::foundation::Status::success();
    case ToolsMenuAction::reset_camera:
        services.reset_camera();
        return pp::foundation::Status::success();
    case ToolsMenuAction::show_shortcuts_dialog:
        services.show_shortcuts_dialog();
        return pp::foundation::Status::success();
    case ToolsMenuAction::start_sonarpen:
        services.start_sonarpen();
        return pp::foundation::Status::success();
    case ToolsMenuAction::no_op_unavailable:
        return pp::foundation::Status::success();
    }

    return pp::foundation::Status::invalid_argument("unknown tools menu action");
}

}
