/**
 * @file main.cpp
 * @brief Extra2D 图片显示示例
 *
 * 演示如何使用 RenderBackend 抽象接口加载和显示图片
 * 此示例不依赖任何特定渲染后端（如 OpenGL）
 */

#include <extra2d/extra2d.h>
#include <iostream>

using namespace extra2d;

class ImageDisplayScene : public Scene {
public:
  void onEnter() override {
    // 加载图片
    // 注意：请确保有图片文件在 assets/images/ 目录下
    try {
      texture_ = renderer_->loadTexture("assets/images/demo.jpg");
      std::cout << "Image loaded successfully!" << std::endl;
      std::cout << "  Size: " << texture_->getWidth() << "x"
                << texture_->getHeight() << std::endl;
    } catch (...) {
      std::cerr << "Failed to load image from assets/images/demo.jpg"
                << std::endl;
      // 尝试使用备用路径
      try {
        texture_ = renderer_->loadTexture(
            "examples/image_display/assets/images/demo.jpg");
        std::cout << "Image loaded from alternate path!" << std::endl;
      } catch (...) {
        std::cerr << "Failed to load image from alternate path!" << std::endl;
        texture_ = nullptr;
      }
    }
  }

  void onExit() override { texture_.reset(); }

  void onRender(RenderBackend &renderer) override {
    Scene::onRender(renderer);

    if (!texture_) {
      return;
    }

    // 使用 RenderBackend 的抽象接口绘制图片
    // 不依赖任何特定后端（如 OpenGL）
    // 自动批处理：无需手动调用 begin/endSpriteBatch

    // 计算图片显示位置（居中显示）
    float windowWidth = 1280.0f;
    float windowHeight = 720.0f;
    float imgWidth = static_cast<float>(texture_->getWidth());
    float imgHeight = static_cast<float>(texture_->getHeight());

    // 缩放图片以适应窗口（保持宽高比）
    float scale = 1.0f;
    if (imgWidth > windowWidth * 0.8f || imgHeight > windowHeight * 0.8f) {
      float scaleX = (windowWidth * 0.8f) / imgWidth;
      float scaleY = (windowHeight * 0.8f) / imgHeight;
      scale = std::min(scaleX, scaleY);
    }

    float displayWidth = imgWidth * scale;
    float displayHeight = imgHeight * scale;
    float x = (windowWidth - displayWidth) * 0.5f;
    float y = (windowHeight - displayHeight) * 0.5f;

    // 使用 RenderBackend 的 drawSprite 方法绘制图片
    // 参数：纹理、目标矩形、源矩形、颜色、旋转角度、锚点
    Rect destRect(x, y, displayWidth, displayHeight);
    Rect srcRect(0, 0, imgWidth, imgHeight);
    renderer.drawSprite(*texture_, destRect, srcRect, Colors::White, 0.0f,
                        Vec2(0, 0));

    // 注意：无需手动调用 renderer.endSpriteBatch()，帧结束时会自动刷新
  }

  void setRenderer(RenderBackend *renderer) { renderer_ = renderer; }

private:
  Ptr<Texture> texture_;
  RenderBackend *renderer_ = nullptr;
};

int main(int argc, char *argv[]) {
  (void)argc;
  (void)argv;

  std::cout << "Extra2D Image Display Demo - Starting..." << std::endl;

  Application &app = Application::get();

  // 注册模块
  app.use<WindowModule>([](auto &cfg) {
    cfg.w = 1280;
    cfg.h = 720;
    cfg.title = "Extra2D Image Display Demo";
    cfg.priority = 0;
    cfg.backend = "glfw";
  });

  app.use<RenderModule>([](auto &cfg) { cfg.priority = 10; });

  app.use<InputModule>([](auto &cfg) { cfg.priority = 20; });

  std::cout << "Initializing application..." << std::endl;
  if (!app.init()) {
    std::cerr << "Failed to initialize application!" << std::endl;
    return -1;
  }

  std::cout << "Application initialized successfully!" << std::endl;

  auto *win = app.window();
  if (win) {
    std::cout << "Window: " << win->width() << "x" << win->height()
              << std::endl;
  }

  // 设置事件监听
  auto eventService = ServiceLocator::instance().getService<IEventService>();
  if (eventService) {
    eventService->addListener(EventType::KeyPressed, [](Event &e) {
      auto &keyEvent = std::get<KeyEvent>(e.data);
      if (keyEvent.keyCode == static_cast<int>(Key::Escape)) {
        e.handled = true;
        Application::get().quit();
      }
    });
  }

  // 获取渲染器
  RenderBackend *renderer = app.renderer();

  // 创建并配置场景
  auto scene = makeShared<ImageDisplayScene>();
  scene->setRenderer(renderer);
  scene->setBackgroundColor(Color(0.1f, 0.1f, 0.15f, 1.0f));

  if (win) {
    scene->setViewportSize(static_cast<float>(win->width()),
                           static_cast<float>(win->height()));
  }

  // 配置相机
  auto cameraService = ServiceLocator::instance().getService<ICameraService>();
  if (cameraService && win) {
    ViewportConfig vpConfig;
    vpConfig.logicWidth = static_cast<float>(win->width());
    vpConfig.logicHeight = static_cast<float>(win->height());
    vpConfig.mode = ViewportMode::AspectRatio;
    cameraService->setViewportConfig(vpConfig);
    cameraService->updateViewport(win->width(), win->height());
    cameraService->applyViewportAdapter();
  }

  app.enterScene(scene);

  std::cout << "\nControls:" << std::endl;
  std::cout << "  ESC - Exit" << std::endl;
  std::cout << "\nRunning main loop...\n" << std::endl;

  app.run();

  std::cout << "Shutting down..." << std::endl;
  app.shutdown();

  std::cout << "Goodbye!" << std::endl;
  return 0;
}
