// modules/core/frameloop.js
import {Logger} from "./logger";

/**
 * @typedef {Object} FrameTaskOptions
 * @property {boolean} [autoStart=false] - Automatically start the frame loop
 */

/** @type {Map<string, Function>} */
const tasks = new Map();
/** @type {boolean} */
let running = false;
/** @type {boolean} */
let showDebug = false;

let lastTime = performance.now();
let frameCount = 0;
let fps = 0;

// Create debug overlay
const debugOverlay = document.createElement('div');
debugOverlay.style.position = 'fixed';
debugOverlay.style.bottom = '0';
debugOverlay.style.left = '0';
debugOverlay.style.font = '12px monospace';
debugOverlay.style.color = '#0f0';
debugOverlay.style.background = 'rgba(0,0,0,0.75)';
debugOverlay.style.padding = '0.25rem 0.5rem';
debugOverlay.style.zIndex = '9999';
debugOverlay.style.pointerEvents = 'none';
debugOverlay.style.display = 'none';
const barWidth = Math.min(fps * 2, 100);
const bar = `<div style="width:${barWidth}%;height:4px;background:#0f0;margin-top:4px;"></div>`;
debugOverlay.innerHTML += bar;
debugOverlay.style.lineHeight = '1.4';
document.body.appendChild(debugOverlay);

import { PerformanceMonitor } from './PerformanceMonitor.js';
/** @type {PerformanceMonitor} */
export const monitor = new PerformanceMonitor();

// Debug toggle with § key
window.addEventListener('keydown', (e) => {
    if (e.key === '§') {
        showDebug = !showDebug;
        debugOverlay.style.display = showDebug ? 'block' : 'none';
    }
});

/**
 * Register a task to run on every frame
 * @param {string} id - Unique identifier for the task
 * @param {Function} callback - Function to execute each frame
 * @param {FrameTaskOptions} [options={}] - Task options
 */
export function registerFrameTask(id, callback, options = {}) {
    tasks.set(id, callback);
    if (options.autoStart && !running) startFrameLoop();
}

/**
 * Unregister a frame task
 * @param {string} id - Task identifier to remove
 */
export function unregisterFrameTask(id) {
    tasks.delete(id);
}

/**
 * Clear all registered frame tasks
 */
export function clearFrameTasks() {
    tasks.clear();
}

/**
 * Start the main frame loop
 */
export function startFrameLoop() {
    if (running) return;
    running = true;

    function loop() {
        for (const [id, task] of tasks) {
            try {
                if (showDebug) {
                    monitor.trackTask(id, task);
                } else {
                    task();
                }
            } catch (err) {
                Logger.warn(`[Frameloop] Fehler in Task:`, err);
            }
        }

        if (showDebug) {
            monitor.update(tasks);
        }

        requestAnimationFrame(loop);
    }

    requestAnimationFrame(loop);
}

/**
 * Stop the frame loop
 * Note: Loop continues until next frame, this just sets the flag
 */
export function stopFrameLoop() {
    running = false;
    // Achtung: Loop läuft weiter, solange nicht aktiv gestoppt
}
