#include "SDL_log.h"
#include "frostbite2D/types/type_math.h"
#include <SDL2/SDL.h>
#include <frostbite2D/core/application.h>
#include <frostbite2D/core/window.h>
#include <frostbite2D/event/event.h>
#include <frostbite2D/graphics/renderer.h>
#include <frostbite2D/graphics/texture.h>
#include <glad/glad.h>


#include <frostbite2D/2d/sprite.h>
#include <frostbite2D/scene/scene.h>
#include <frostbite2D/scene/scene_manager.h>
#include <frostbite2D/resource/binary_reader.h>
#include <frostbite2D/resource/pvf_archive.h>
#include <frostbite2D/resource/script_parser.h>

#include <frostbite2D/audio/audio_system.h>
#include <frostbite2D/audio/music.h>
#include <frostbite2D/audio/sound.h>
#include <frostbite2D/resource/npk_archive.h>

#include <frostbite2D/resource/audio_database.h>
#include <frostbite2D/resource/sound_pack_archive.h>

#include <frostbite2D/animation/animation.h>

using namespace frostbite2D;

int main(int argc, char **argv) {
  AppConfig config = AppConfig::createDefault();
  config.appName = "Frostbite2D Test App";
  config.appVersion = "1.0.0";
  config.windowConfig.width = 1920;
  config.windowConfig.height = 1080;
  config.windowConfig.title = "Frostbite2D - Renderer Test";

  Application& app = Application::get();

  if (!app.init(config)) {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize application!");
    return -1;
  }
  
  // SDL_Log("Starting main loop...");

  auto &pvf = PvfArchive::get();
  if (pvf.open("assets/Script.pvf")) {
    pvf.init();
    SDL_Log("PVF initialized successfully");
  }

  NpkArchive &npk = NpkArchive::get();
  npk.setImagePackDirectory("assets/ImagePacks2");
  npk.setDefaultImg("sprite/interface/base.img", 0);
  npk.init();

  auto menuScene = MakePtr<Scene>();
  SceneManager::get().PushScene(menuScene);

  auto ani = MakePtr<Animation>(
      "monster/event/bluemarble/goblin/animation_goblin2/move.ani");

  if (ani) {
    SDL_Log("Animation created successfully");
    ani->SetAnchor(Vec2(0.5f, 0.5f));
    ani->SetPosition(640, 360);
    menuScene->AddChild(ani);
  }

  auto TestActor = MakePtr<Actor>();

  menuScene->AddChild(TestActor);

  TestActor->EnableEventReceive();

  // 监听手柄按键按下
  TestActor->AddEventListener(
      EventType::JoystickButtonDown, [](const Event &event) {
        const auto &ke = static_cast<const JoystickButtonEvent &>(event);
        SDL_Log("Joystick Button Down: device=%d, button=%d", ke.getDeviceId(),
                ke.getButton());

        if(ke.getButton() == 6) {
          Application::get().quit();
        }
        return true;
      });

  // 监听手柄按键抬起
  TestActor->AddEventListener(
      EventType::JoystickButtonUp, [](const Event &event) {
        const auto &ke = static_cast<const JoystickButtonEvent &>(event);
        SDL_Log("Joystick Button Up: device=%d, button=%d", ke.getDeviceId(),
                ke.getButton());

        return true;
      });

  // 监听手柄轴
  TestActor->AddEventListener(EventType::JoystickAxis, [](const Event &event) {
    const auto &ae = static_cast<const JoystickAxisEvent &>(event);
    if (std::abs(ae.getNormalizedValue()) > 0.1f) {
      SDL_Log("Joystick Axis: device=%d, axis=%d, value=%.2f", ae.getDeviceId(),
              ae.getAxis(), ae.getNormalizedValue());
    }
    return true;
  });

  auto sprite1 = Sprite::createFromNpk("sprite/newtitle/nangua.img", 0);
  if (sprite1) {
    sprite1->SetPosition(220, 10);
    // sprite1->SetScale(2.0f);
    menuScene->AddChild(sprite1);
  } else {
    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create sprite from NPK!");
  }
  
  // // auto &archive = PvfArchive::get();
  // // if (archive.open("assets/Script.pvf")) {
  // //   archive.init();
  // //   // 文件内容读取
  // //   if (auto rawData = archive.getFileRawData("region/balmayer_north.rgn")) {
  // //     ScriptParser parser(*rawData, "script/example.bin");
  // //     // // 方式1：迭代解析
  // //     // while (!parser.isEnd()) {
  // //     //   if (auto value = parser.next()) {
  // //     //     switch (value->type) {
  // //     //     case ScriptValueType::Integer:
  // //     //       SDL_Log("Integer: %d", value->intValue);
  // //     //       break;
  // //     //     case ScriptValueType::Float:
  // //     //       SDL_Log("Float: %f", value->floatValue);
  // //     //       break;
  // //     //     case ScriptValueType::String:
  // //     //       SDL_Log("String: %s", value->stringValue.c_str());
  // //     //       break;
  // //     //     default:
  // //     //       break;
  // //     //     }
  // //     //   }
  // //     // }

  // //     // // 方式2：批量解析
  // //     // parser.reset();
  // //     auto allValues = parser.parseAll();
  // //     for (const auto &value : allValues) {
  // //       // 处理 value
  // //       switch (value.type) {
  // //       case ScriptValueType::Integer:
  // //         SDL_Log("Integer: %d", value.intValue);
  // //         break;
  // //       case ScriptValueType::Float:
  // //         SDL_Log("Float: %f", value.floatValue);
  // //         break;
  // //       case ScriptValueType::String:
  // //         SDL_Log("String: %s", value.stringValue.c_str());
  // //         break;
  // //       default:
  // //         break;
  // //       }
  // //     }
  // //   }
  // // }

  // AudioSystem::get().init();
  // AudioSystem::get().setMasterVolume(1.0f);
  // AudioSystem::get().setSoundVolume(0.8f);
  // AudioSystem::get().setMusicVolume(0.6f);

  // auto bgMusic = Music::loadFromFile("assets/BackgroundMusic.mp3");
  // if (bgMusic) {
  //   bgMusic->play();
  // } else {
  //   SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load background music!");
  // }



  // SoundPackArchive &archive = SoundPackArchive::get();
  // archive.setSoundPackDirectory("assets/SoundPacks");
  // archive.init();

  // // auto sound = Sound::loadFromNpk("sounds/ui/adventurer_maker_name.ogg");
  // // if (sound) {
  // //   sound->play();
  // // } else {
  // //   SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to load sound!");
  // // }

  // auto &audioDB = AudioDatabase::get();
  // audioDB.loadFromFile("assets/audio.xml");

  // // ========== 方式 1: 最简单的 API（推荐） ==========
  // std::string path = audioDB.filePath("P_ICECANNON_SHOT");
  // if (!path.empty()) {
  //   SDL_Log("=== 方式 1: 直接获取文件路径 ===");
  //   SDL_Log("File: %s", path.c_str());
  // }

  app.run();

  SDL_Log("Application exited normally");
  app.shutdown();

  return 0;
}
