// core.cm - Minimal entry point for prosperon rendering
//
// Usage:
//   var core = use('prosperon/core')
//   core.start({
//     width: 1280,
//     height: 720,
//     title: "My Game",
//     update: function(dt) { ... },
//     render: function() { return graph }
//   })

var video = use('sdl3/video')
var events = use('sdl3/input')
var time_mod = use('time')
var debug_imgui = use('debug_imgui')

var core = {}

// Private state
var _running = false
var _config = null
var _backend = null
var _window = null
var _last_time = 0
var _framerate = 60

var imgui = use('imgui')

// Start the application
core.start = function(config) {
  _config = config
  _framerate = config.framerate || 60
  
  // Initialize SDL GPU backend
  var sdl_gpu = use('sdl_gpu')
  _backend = sdl_gpu
  
  var init_result = _backend.init({
    width: config.width || 1280,
    height: config.height || 720,
    title: config.title || "Prosperon"
  })
  
  if (!init_result) {
    log.console("core: Failed to initialize backend")
    return false
  }
  
  _window = _backend.get_window()
  
  if ((config.imgui || config.editor) && imgui.init) {
    imgui.init(_window, _backend.get_device())
  }
  
  _running = true
  _last_time = time_mod.number()
  
  // Start main loop
  _main_loop()
  
  return true
}

// Stop the application
core.stop = function() {
  _running = false
}

// Get window size
core.window_size = function() {
  return _backend.get_window_size()
}

// Get backend for direct access
core.backend = function() {
  return _backend
}
// FPS tracking
var _fps_samples = []
var _fps_sample_count = 120
var _fps_sample_sum = 0
var _fps_sample_pos = 0

function fps_add_sample(sample) {
  var n = length(_fps_samples)
  var old = null
  if (n < _fps_sample_count) {
    push(_fps_samples, sample)
    _fps_sample_sum += sample
  } else {
    old = _fps_samples[_fps_sample_pos]
    _fps_samples[_fps_sample_pos] = sample
    _fps_sample_sum += sample - old
    _fps_sample_pos++
    if (_fps_sample_pos >= _fps_sample_count) _fps_sample_pos = 0
  }
}

function fps_get_avg() {
  var n = length(_fps_samples)
  return n ? _fps_sample_sum / n : 0
}

var _current_fps = 0
var _frame_time_ms = 0

// Main loop
function _main_loop() {
  var frame_start = time_mod.number()
  
  if (!_running) return
  
  var now = frame_start
  var dt = now - _last_time
  _last_time = now
  
  // Process events
  var evts = events.get_events()

  var win_size = _backend.get_window_size()
  
  // Get input module for auto-ingestion
  var input_mod = use('input')
  
  arrfor(evts, function(ev) {
    if (_config.imgui || _config.editor) {
      imgui.process_event(ev)
    }

    var ev_obj = events.objectify(ev)
    if (ev_obj.type == 'quit') {
      _running = false
      $stop()
      return
    }

    if (ev_obj.type == 'window_pixel_size_changed') {
      win_size.width = ev_obj.width
      win_size.height = ev_obj.height
      if (_backend.set_window_size) {
        _backend.set_window_size(ev_obj.width, ev_obj.height)
      }
    }
    
    // Auto-ingest through input system
    input_mod.ingest(ev_obj)
    
    // Optional raw hook for debugging
    if (_config.input) {
      _config.input(ev_obj)
    }
  })
  
  // Update
  if (_config.update) {
    _config.update(dt)
  }

  var imgui_mod = use('imgui')
  var debug_imgui = use('debug_imgui')
  
  // ImGui Frame
  if (_config.imgui || _config.editor) {
    imgui_mod.newframe()
  }

  // Render
  var render_result = null
  var dbg = false
  var stats = null
  if (_config.render) {
    render_result = _config.render()
    if (render_result) {
      if (_config.debug == 'graph') {
        log.console(render_result)
        $stop()
        return
      }
      dbg = _config.debug == 'cmd'

      // Build stats for debug_imgui
      stats = {
        fps: _current_fps,
        frame_time_ms: _frame_time_ms
      }

      // Handle both compositor result ({commands: [...]}) and fx_graph (graph object)
      if (render_result.commands) {
        if (_config.imgui || _config.editor) {
          push(render_result.commands, {
            cmd: 'imgui',
            draw: function(ui) {
              if (_config.imgui) _config.imgui(ui)
              if (is_function(_config.editor)) {
                debug_imgui.render(ui, null, render_result.plan, stats)
                _config.editor(ui)
              }
            },
            target: 'screen'
          })
        }
        // Compositor result - execute commands directly
        _backend.execute_commands(render_result.commands, win_size, dbg)
      } else {
        // fx_graph result - execute graph
        _backend.execute_graph(render_result, win_size, dbg)
      }
      
      if (dbg) {
        $stop()
        return
      }
    }
  }
  
  var frame_end = time_mod.number()
  var actual_frame_time = frame_end - frame_start

  _frame_time_ms = actual_frame_time * 1000
  fps_add_sample(actual_frame_time)

  var avg_frame_time = fps_get_avg()
  _current_fps = avg_frame_time > 0 ? 1 / avg_frame_time : 0

  // Schedule next frame
  var frame_time = 1 / _framerate
  var elapsed = frame_end - frame_start
  var delay = frame_time - elapsed
  if (delay < 0) delay = 0
  
  $delay(_main_loop, delay)
}

return core
