#pragma once

#include "app_core/document_export.h"
#include "app_core/document_session.h"
#include "foundation/result.h"

#include <string_view>

namespace pp::app {

enum class FileMenuCommand {
    new_document,
    import_image,
    open_project,
    browse_cloud,
    save,
    save_as,
    save_version,
    export_jpeg,
    export_submenu,
    share,
    resize,
    cloud_upload,
    cloud_browse,
};

enum class FileMenuAction {
    show_new_document_dialog,
    pick_image_for_import,
    pick_project_file,
    show_cloud_browser_dialog,
    save_document,
    show_export_jpeg_dialog,
    show_export_submenu,
    share_document,
    show_resize_dialog,
    upload_to_cloud,
    browse_cloud_documents,
};

struct FileMenuPlan {
    FileMenuCommand command = FileMenuCommand::new_document;
    FileMenuAction action = FileMenuAction::show_new_document_dialog;
    DocumentSaveIntent save_intent = DocumentSaveIntent::save;
    DocumentExportMenuKind export_kind = DocumentExportMenuKind::jpeg;
};

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

    virtual void show_new_document_dialog() = 0;
    virtual void pick_image_for_import() = 0;
    virtual void pick_project_file() = 0;
    virtual void show_cloud_browser_dialog() = 0;
    virtual void save_document(DocumentSaveIntent intent) = 0;
    virtual void show_export_jpeg_dialog(DocumentExportMenuKind kind) = 0;
    virtual void show_export_submenu() = 0;
    virtual void share_document() = 0;
    virtual void show_resize_dialog() = 0;
    virtual void upload_to_cloud() = 0;
    virtual void browse_cloud_documents() = 0;
};

[[nodiscard]] constexpr FileMenuPlan plan_file_menu_command(FileMenuCommand command) noexcept
{
    FileMenuPlan plan;
    plan.command = command;

    switch (command) {
    case FileMenuCommand::new_document:
        plan.action = FileMenuAction::show_new_document_dialog;
        break;
    case FileMenuCommand::import_image:
        plan.action = FileMenuAction::pick_image_for_import;
        break;
    case FileMenuCommand::open_project:
        plan.action = FileMenuAction::pick_project_file;
        break;
    case FileMenuCommand::browse_cloud:
        plan.action = FileMenuAction::show_cloud_browser_dialog;
        break;
    case FileMenuCommand::save:
        plan.action = FileMenuAction::save_document;
        plan.save_intent = DocumentSaveIntent::save;
        break;
    case FileMenuCommand::save_as:
        plan.action = FileMenuAction::save_document;
        plan.save_intent = DocumentSaveIntent::save_as;
        break;
    case FileMenuCommand::save_version:
        plan.action = FileMenuAction::save_document;
        plan.save_intent = DocumentSaveIntent::save_version;
        break;
    case FileMenuCommand::export_jpeg:
        plan.action = FileMenuAction::show_export_jpeg_dialog;
        plan.export_kind = DocumentExportMenuKind::jpeg;
        break;
    case FileMenuCommand::export_submenu:
        plan.action = FileMenuAction::show_export_submenu;
        break;
    case FileMenuCommand::share:
        plan.action = FileMenuAction::share_document;
        break;
    case FileMenuCommand::resize:
        plan.action = FileMenuAction::show_resize_dialog;
        break;
    case FileMenuCommand::cloud_upload:
        plan.action = FileMenuAction::upload_to_cloud;
        break;
    case FileMenuCommand::cloud_browse:
        plan.action = FileMenuAction::browse_cloud_documents;
        break;
    }

    return plan;
}

[[nodiscard]] inline pp::foundation::Result<FileMenuCommand> parse_file_menu_command(
    std::string_view command) noexcept
{
    if (command == "new" || command == "new-document") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::new_document);
    }
    if (command == "import" || command == "import-image") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::import_image);
    }
    if (command == "open" || command == "open-project") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::open_project);
    }
    if (command == "browse") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::browse_cloud);
    }
    if (command == "save") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::save);
    }
    if (command == "save-as") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::save_as);
    }
    if (command == "save-version") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::save_version);
    }
    if (command == "export" || command == "export-jpeg") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::export_jpeg);
    }
    if (command == "export-submenu") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::export_submenu);
    }
    if (command == "share") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::share);
    }
    if (command == "resize") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::resize);
    }
    if (command == "cloud-upload") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::cloud_upload);
    }
    if (command == "cloud-browse") {
        return pp::foundation::Result<FileMenuCommand>::success(FileMenuCommand::cloud_browse);
    }

    return pp::foundation::Result<FileMenuCommand>::failure(
        pp::foundation::Status::invalid_argument("unknown file menu command"));
}

[[nodiscard]] inline pp::foundation::Status execute_file_menu_plan(
    const FileMenuPlan& plan,
    FileMenuServices& services)
{
    switch (plan.action) {
    case FileMenuAction::show_new_document_dialog:
        services.show_new_document_dialog();
        return pp::foundation::Status::success();
    case FileMenuAction::pick_image_for_import:
        services.pick_image_for_import();
        return pp::foundation::Status::success();
    case FileMenuAction::pick_project_file:
        services.pick_project_file();
        return pp::foundation::Status::success();
    case FileMenuAction::show_cloud_browser_dialog:
        services.show_cloud_browser_dialog();
        return pp::foundation::Status::success();
    case FileMenuAction::save_document:
        services.save_document(plan.save_intent);
        return pp::foundation::Status::success();
    case FileMenuAction::show_export_jpeg_dialog:
        services.show_export_jpeg_dialog(plan.export_kind);
        return pp::foundation::Status::success();
    case FileMenuAction::show_export_submenu:
        services.show_export_submenu();
        return pp::foundation::Status::success();
    case FileMenuAction::share_document:
        services.share_document();
        return pp::foundation::Status::success();
    case FileMenuAction::show_resize_dialog:
        services.show_resize_dialog();
        return pp::foundation::Status::success();
    case FileMenuAction::upload_to_cloud:
        services.upload_to_cloud();
        return pp::foundation::Status::success();
    case FileMenuAction::browse_cloud_documents:
        services.browse_cloud_documents();
        return pp::foundation::Status::success();
    }

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

} // namespace pp::app
