#pragma once

#include "foundation/result.h"

#include <string_view>

namespace pp::app {

enum class DocumentImageImportAction {
    import_equirectangular,
    place_transform,
};

struct DocumentImageImportPlan {
    int width = 0;
    int height = 0;
    DocumentImageImportAction action = DocumentImageImportAction::place_transform;
    bool imports_equirectangular = false;
    bool enters_transform_mode = false;
};

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

    virtual void import_equirectangular(std::string_view path) = 0;
    virtual void enter_transform_import(std::string_view path) = 0;
};

[[nodiscard]] inline pp::foundation::Status validate_document_image_import_dimensions(
    int width,
    int height) noexcept
{
    if (width <= 0 || height <= 0) {
        return pp::foundation::Status::invalid_argument("image dimensions must be positive");
    }
    return pp::foundation::Status::success();
}

[[nodiscard]] inline pp::foundation::Result<DocumentImageImportPlan> plan_document_image_import(
    int width,
    int height) noexcept
{
    const auto dimensions = validate_document_image_import_dimensions(width, height);
    if (!dimensions.ok()) {
        return pp::foundation::Result<DocumentImageImportPlan>::failure(dimensions);
    }

    const auto wide_equirect = static_cast<long long>(width) == static_cast<long long>(height) * 2LL;
    const auto vertical_cube_strip = width == height / 6;

    DocumentImageImportPlan plan;
    plan.width = width;
    plan.height = height;
    plan.imports_equirectangular = wide_equirect || vertical_cube_strip;
    plan.enters_transform_mode = !plan.imports_equirectangular;
    plan.action = plan.imports_equirectangular
        ? DocumentImageImportAction::import_equirectangular
        : DocumentImageImportAction::place_transform;
    return pp::foundation::Result<DocumentImageImportPlan>::success(plan);
}

[[nodiscard]] inline pp::foundation::Status execute_document_image_import_plan(
    const DocumentImageImportPlan& plan,
    std::string_view path,
    DocumentImageImportServices& services)
{
    const auto dimensions = validate_document_image_import_dimensions(plan.width, plan.height);
    if (!dimensions.ok()) {
        return dimensions;
    }
    if (path.empty()) {
        return pp::foundation::Status::invalid_argument("image import path must not be empty");
    }

    switch (plan.action) {
    case DocumentImageImportAction::import_equirectangular:
        services.import_equirectangular(path);
        return pp::foundation::Status::success();
    case DocumentImageImportAction::place_transform:
        services.enter_transform_import(path);
        return pp::foundation::Status::success();
    }

    return pp::foundation::Status::invalid_argument("unknown image import action");
}

} // namespace pp::app
