#include "SDL_log.h"
#include <SDL2/SDL.h>
#include <frostbite2D/core/window.h>
#include <frostbite2D/resource/asset.h>
#include <glad/glad.h>


namespace frostbite2D {

bool Window::create(const WindowConfig &cfg) {

  Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
  
#ifndef __SWITCH__
  if (cfg.fullscreen) {
    flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
  } else if (cfg.borderless) {
    flags |= SDL_WINDOW_BORDERLESS;
  }
  if (cfg.resizable) {
    flags |= SDL_WINDOW_RESIZABLE;
  }
  if (!cfg.decorated) {
    flags |= SDL_WINDOW_BORDERLESS;
  }
#endif

  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
  SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

  if (cfg.multisamples > 0) {
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, cfg.multisamples);
  }

  int x = SDL_WINDOWPOS_CENTERED;
  int y = SDL_WINDOWPOS_CENTERED;
  if (!cfg.centered) {
    x = SDL_WINDOWPOS_UNDEFINED;
    y = SDL_WINDOWPOS_UNDEFINED;
  }

  // 创建窗口
  sdlWindow_ =
      SDL_CreateWindow(cfg.title.c_str(), x, y, cfg.width, cfg.height, flags);

  if (!sdlWindow_) {
    SDL_Log("Failed to create window: %s", SDL_GetError());
    return false;
  }

  glContext_ = SDL_GL_CreateContext(sdlWindow_);
  if (!glContext_) {
    SDL_Log("Failed to create OpenGL context: %s", SDL_GetError());
    SDL_DestroyWindow(sdlWindow_);
    sdlWindow_ = nullptr;
    return false;
  }

  if (!gladLoadGLES2Loader((GLADloadproc)SDL_GL_GetProcAddress)) {
    SDL_Log("Failed to initialize GLAD GLES2");
    SDL_GL_DeleteContext(glContext_);
    glContext_ = nullptr;
    SDL_DestroyWindow(sdlWindow_);
    sdlWindow_ = nullptr;
    return false;
  }

  SDL_GL_SetSwapInterval(cfg.vsync ? 1 : 0);

  // 获取实际的可绘制大小（考虑高 DPI 和 Switch 等平台）
  int drawableWidth, drawableHeight;
  SDL_GL_GetDrawableSize(sdlWindow_, &drawableWidth, &drawableHeight);
  width_ = drawableWidth;
  height_ = drawableHeight;
  
  // 计算缩放比例
  int windowWidth, windowHeight;
  SDL_GetWindowSize(sdlWindow_, &windowWidth, &windowHeight);
  if (windowWidth > 0 && windowHeight > 0) {
    scaleX_ = static_cast<float>(drawableWidth) / static_cast<float>(windowWidth);
    scaleY_ = static_cast<float>(drawableHeight) / static_cast<float>(windowHeight);
  }
  
  fullscreen_ = (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0;
  vsync_ = cfg.vsync;

#ifndef __SWITCH__
  if (!cfg.icon.file_path.empty()) {
    Asset& asset = Asset::get();
    std::string resolvedPath = asset.resolveAssetPath(cfg.icon.file_path);
    SDL_Surface* icon = SDL_LoadBMP(resolvedPath.c_str());
    if (icon) {
      SDL_SetWindowIcon(sdlWindow_, icon);
      SDL_FreeSurface(icon);
    } else {
      SDL_Log("Failed to load window icon: %s", resolvedPath.c_str());
    }
  }
#if defined(_WIN32)
  if (cfg.icon.resource_id != 0) {
    SDL_Log("Loading icon from resource ID: %u", cfg.icon.resource_id);
  }
#endif
#endif

  return true;
}

void Window::destroy() {
  if (sdlWindow_) {
    SDL_GL_DeleteContext(glContext_);
    glContext_ = nullptr;
    SDL_DestroyWindow(sdlWindow_);
    sdlWindow_ = nullptr;
  }
}

void Window::poll() {}

void Window::swap() {
  if (sdlWindow_ && glContext_) {
    SDL_GL_SwapWindow(sdlWindow_);
  }
}

void Window::close() { shouldClose_ = true; }

void Window::setTitle(const std::string &title) {}

void Window::setSize(int w, int h) {
  if (sdlWindow_) {
    SDL_SetWindowSize(sdlWindow_, w, h);
  }
  width_ = w;
  height_ = h;
  if (resizeCb_) {
    resizeCb_(w, h);
  }
}

void Window::setPos(int x, int y) {
  if (sdlWindow_) {
    SDL_SetWindowPosition(sdlWindow_, x, y);
  }
}

void Window::setFullscreen(bool fs) { fullscreen_ = fs; }

void Window::setVSync(bool vsync) { vsync_ = vsync; }

void Window::setVisible(bool visible) {}

int Window::width() const { return width_; }

int Window::height() const { return height_; }

Size Window::size() const {
  return Size{static_cast<float>(width_), static_cast<float>(height_)};
}

Vec2 Window::pos() const {
  if (sdlWindow_) {
    int x, y;
    SDL_GetWindowPosition(sdlWindow_, &x, &y);
    return Vec2{static_cast<float>(x), static_cast<float>(y)};
  }
  return Vec2{0.0f, 0.0f};
}

bool Window::fullscreen() const { return fullscreen_; }

bool Window::vsync() const { return vsync_; }

bool Window::focused() const { return focused_; }

bool Window::minimized() const { return minimized_; }

float Window::scaleX() const { return scaleX_; }

float Window::scaleY() const { return scaleY_; }

void Window::setCursor(CursorType cursor) {}

void Window::showCursor(bool show) { cursorVisible_ = show; }

void Window::lockCursor(bool lock) { cursorLocked_ = lock; }

void Window::onResize(ResizeCb cb) { resizeCb_ = cb; }

void Window::onClose(CloseCb cb) { closeCb_ = cb; }

void Window::onFocus(FocusCb cb) { focusCb_ = cb; }

void *Window::native() const { return nullptr; }

} // namespace frostbite2D
