import { SceneFeature } from './SceneFeature.js';
import sceneFeatureManager from './SceneFeatureManager.js';

export class FPSCounter extends SceneFeature {
    constructor() {
        super();
        this.frames = 0;
        this.timeAccumulator = 0;
        this.fpsElement = null;
        this.textElement = null;
        this.canvas = null;
        this.ctx = null;
        this.history = [];
        this.memTextElement = null;
        this.memCanvas = null;
        this.memCtx = null;
        this.memHistory = [];
        sceneFeatureManager.register(this);
    }

    init() {
        // Create the FPS display container
        this.fpsElement = document.createElement('div');
        Object.assign(this.fpsElement.style, {
            position: 'absolute',
            top: '0',
            right: '0',
            zIndex: '10000',
            padding: '5px',
            background: 'rgba(0, 0, 0, 0.5)',
            pointerEvents: 'none',
            userSelect: 'none',
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'flex-end'
        });

        // Text Display
        this.textElement = document.createElement('div');
        Object.assign(this.textElement.style, {
            color: '#00ff00',
            fontFamily: 'monospace',
            fontSize: '16px',
            fontWeight: 'bold',
            marginBottom: '2px'
        });
        this.textElement.innerText = 'FPS: --';
        this.fpsElement.appendChild(this.textElement);

        // Graph Canvas
        this.canvas = document.createElement('canvas');
        this.canvas.width = 100;
        this.canvas.height = 40;
        Object.assign(this.canvas.style, {
            width: '100px',
            height: '40px',
            background: '#222',
            border: '1px solid #444'
        });
        this.ctx = this.canvas.getContext('2d');
        this.fpsElement.appendChild(this.canvas);

        // Memory Text Display
        this.memTextElement = document.createElement('div');
        Object.assign(this.memTextElement.style, {
            color: '#00ffff',
            fontFamily: 'monospace',
            fontSize: '16px',
            fontWeight: 'bold',
            marginBottom: '2px',
            marginTop: '5px'
        });
        this.memTextElement.innerText = 'MEM: --';
        this.fpsElement.appendChild(this.memTextElement);

        // Memory Graph Canvas
        this.memCanvas = document.createElement('canvas');
        this.memCanvas.width = 100;
        this.memCanvas.height = 40;
        Object.assign(this.memCanvas.style, {
            width: '100px',
            height: '40px',
            background: '#222',
            border: '1px solid #444'
        });
        this.memCtx = this.memCanvas.getContext('2d');
        this.fpsElement.appendChild(this.memCanvas);

        document.body.appendChild(this.fpsElement);
        
        this.history = new Array(this.canvas.width).fill(0);
        this.memHistory = new Array(this.memCanvas.width).fill(0);
    }

    update(deltaTime) {
        this.frames++;
        this.timeAccumulator += deltaTime;

        const segment = 0.25;
        if (this.timeAccumulator >= segment) {
            const fps = Math.round(this.frames / this.timeAccumulator);
            if (this.textElement) {
                this.textElement.innerText = `FPS: ${fps}`;
                if (fps >= 58) {
                    this.textElement.style.color = '#00ff00';
                } else if (fps >= 55) {
                    this.textElement.style.color = '#ffff00';
                } else {
                    this.textElement.style.color = '#ff0000';
                }
            }
            
            // Update Graph
            this.history.push(fps);
            if (this.history.length > this.canvas.width) {
                this.history.shift();
            }
            this.drawGraph();

            // Update Memory
            if (performance && performance.memory) {
                const mem = performance.memory.usedJSHeapSize / 1048576; // MB
                if (this.memTextElement) this.memTextElement.innerText = `MEM: ${Math.round(mem)} MB`;
                
                this.memHistory.push(mem);
                if (this.memHistory.length > this.memCanvas.width) {
                    this.memHistory.shift();
                }
                this.drawMemGraph();
            } else {
                 if (this.memTextElement) this.memTextElement.style.display = 'none';
                 if (this.memCanvas) this.memCanvas.style.display = 'none';
            }

            this.frames = 0;
            this.timeAccumulator = 0;
        }
    }

    drawGraph() {
        if (!this.ctx) return;
        const ctx = this.ctx;
        const w = this.canvas.width;
        const h = this.canvas.height;
        const maxFps = 70; 

        ctx.clearRect(0, 0, w, h);

        // Draw 60 FPS reference line
        const y60 = h - (60 / maxFps) * h;
        ctx.beginPath();
        ctx.strokeStyle = '#555';
        ctx.moveTo(0, y60);
        ctx.lineTo(w, y60);
        ctx.stroke();

        // Draw Graph
        ctx.lineWidth = 1.5;
        
        for (let i = 0; i < this.history.length - 1; i++) {
            const val = this.history[i + 1];
            const x1 = i;
            const y1 = h - (this.history[i] / maxFps) * h;
            const x2 = i + 1;
            const y2 = h - (val / maxFps) * h;

            ctx.beginPath();
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);

            if (val >= 58) ctx.strokeStyle = '#00ff00';
            else if (val >= 55) ctx.strokeStyle = '#ffff00';
            else ctx.strokeStyle = '#ff0000';
            
            ctx.stroke();
        }
    }

    drawMemGraph() {
        if (!this.memCtx) return;
        const ctx = this.memCtx;
        const w = this.memCanvas.width;
        const h = this.memCanvas.height;
        // Auto-scale max memory
        const maxMem = Math.max(...this.memHistory, 100) * 1.1; 

        ctx.clearRect(0, 0, w, h);

        // Draw Graph
        ctx.beginPath();
        ctx.strokeStyle = '#00ffff';
        ctx.lineWidth = 1.5;
        
        for (let i = 0; i < this.memHistory.length; i++) {
            const val = this.memHistory[i];
            const x = i;
            const y = h - (val / maxMem) * h;
            if (i === 0) ctx.moveTo(x, y);
            else ctx.lineTo(x, y);
        }
        ctx.stroke();
    }
}

new FPSCounter();