// Filename: web/static/js/status-grid.js (V6.0 - 健壮初始化最终版)
// export default function initializeStatusGrid() {
class StatusGrid {
    constructor(canvasId) {
        this.canvas = document.getElementById(canvasId);
        if (!this.canvas) { return; }
        this.ctx = this.canvas.getContext('2d');
        
        this.config = {
            cols: 100, rows: 4, gap: 2, cornerRadius: 2,
            colors: {
                'ACTIVE': '#22C55E', 'ACTIVE_BLINK': '#A7F3D0',
                'PENDING': '#9CA3AF', 'COOLDOWN': '#EAB308', 
                'DISABLED': '#F97316', 'BANNED': '#EF4444',
                'EMPTY': '#F3F4F6',
            },
            blinkInterval: 100, blinksPerInterval: 2, blinkDuration: 200,
            statusOrder: ['ACTIVE', 'COOLDOWN', 'DISABLED', 'BANNED', 'PENDING']
        };
        this.state = {
            squares: [], squareSize: 0,
            devicePixelRatio: window.devicePixelRatio || 1,
            animationFrameId: null, blinkIntervalId: null,
            blinkingSquares: new Set()
        };
        
        this.debouncedResize = this.debounce(this.resize.bind(this), 250);
    }
    init() {
        this.setupCanvas();
        // 初始化时，绘制一个完全为空的网格
        this.state.squares = Array(this.config.rows * this.config.cols).fill({ status: 'EMPTY' });
        this.drawFullGrid();
        window.addEventListener('resize', this.debouncedResize);
    }
    
    /**
     * [灵魂重塑] 这是被彻底重写的核心函数
     * @param {object} keyStatusCounts - 例如 { "BANNED": 1, "DISABLED": 4, ... }
     */
    updateData(keyStatusCounts) {
        if (!keyStatusCounts) return;
        
        this.destroyAnimation();
        this.state.squares = [];
        this._activeIndices = null;
        this.state.blinkingSquares.clear();
        const totalKeys = Object.values(keyStatusCounts).reduce((s, c) => s + c, 0);
        const totalSquares = this.config.rows * this.config.cols;
        // 如果没有密钥，则显示为空白的网格
        if (totalKeys === 0) {
            this.init();
            return;
        }
        let statusMap = [];
        let calculatedSquares = 0;
        // 1. 严格按照比例，计算每个状态应该占据多少个“像素”
        for (const status of this.config.statusOrder) {
            const count = keyStatusCounts[status] || 0;
            if (count > 0) {
                const proportion = count / totalKeys;
                const squaresForStatus = Math.floor(proportion * totalSquares);
                for (let i = 0; i < squaresForStatus; i++) {
                    statusMap.push(status);
                }
                calculatedSquares += squaresForStatus;
            }
        }
        
        // 2. [关键] 修正四舍五入的误差，将剩余的方块填满
        const remainingSquares = totalSquares - calculatedSquares;
        if (remainingSquares > 0) {
            // 将剩余方块，全部分配给数量最多的那个状态，以使其最不失真
            let largestStatus = this.config.statusOrder[0]; // 默认给第一个
            let maxCount = -1;
            for (const status in keyStatusCounts) {
                if (keyStatusCounts[status] > maxCount) {
                    maxCount = keyStatusCounts[status];
                    largestStatus = status;
                }
            }
            for (let i = 0; i < remainingSquares; i++) {
                statusMap.push(largestStatus);
            }
        }
        
        // 3. 将最终的、按比例填充的地图，转化为内部的 square 对象
        this.state.squares = statusMap.map(status => ({
            status: status,
            isBlinking: false,
            blinkUntil: 0
        }));
        
        // 4. [渲染修正] 直接、完整地重绘整个网格，然后启动动画
        this.drawFullGrid();
        this.startAnimationSystem();
    }
    // [渲染修正] 一个简单、直接、一次性绘制所有方块的函数
    drawFullGrid() {
        const rect = this.canvas.getBoundingClientRect();
        this.ctx.clearRect(0, 0, rect.width, rect.height);
        
        // offsetX 和 offsetY 是在 setupCanvas 中计算的
        const offsetX = this.state.offsetX;
        const offsetY = this.state.offsetY;
        this.state.squares.forEach((square, i) => {
            const c = i % this.config.cols;
            const r = Math.floor(i / this.config.cols);
            
            const x = offsetX + c * (this.state.squareSize + this.config.gap);
            const y = offsetY + r * (this.state.squareSize + this.config.gap);
            const color = this.config.colors[square.status];
            this.drawRoundedRect(x, y, this.state.squareSize, this.config.cornerRadius, color);
        });
    }

    startAnimationSystem() {
        if(this.state.blinkIntervalId) clearInterval(this.state.blinkIntervalId);
        if(this.state.animationFrameId) cancelAnimationFrame(this.state.animationFrameId);

        this.state.blinkIntervalId = setInterval(() => {
            const activeSquareIndices = this.getActiveSquareIndices();
            if (activeSquareIndices.length === 0) return;

            for(let i = 0; i < this.config.blinksPerInterval; i++) {
                const randomIndex = activeSquareIndices[Math.floor(Math.random() * activeSquareIndices.length)];
                const square = this.state.squares[randomIndex];
                
                if (square && !square.isBlinking) {
                    square.isBlinking = true;
                    square.blinkUntil = performance.now() + this.config.blinkDuration;
                    this.state.blinkingSquares.add(randomIndex);
                }
            }
        }, this.config.blinkInterval);

        const animationLoop = (timestamp) => {
            if (this.state.blinkingSquares.size > 0) {
                this.state.blinkingSquares.forEach(index => {
                    const square = this.state.squares[index];
                    if(!square) { // 防御性检查
                        this.state.blinkingSquares.delete(index);
                        return;
                    }
                    const c = index % this.config.cols;
                    const r = Math.floor(index / this.config.cols);

                    this.drawSquare(square, c, r);

                    if (timestamp > square.blinkUntil) {
                        square.isBlinking = false;
                        this.state.blinkingSquares.delete(index);
                        this.drawSquare(square, c, r); 
                    }
                });
            }
            this.state.animationFrameId = requestAnimationFrame(animationLoop);
        };
        animationLoop();
    }
    
    setupCanvas() {
        const rect = this.canvas.getBoundingClientRect();
        this.canvas.width = rect.width * this.state.devicePixelRatio;
        this.canvas.height = rect.height * this.state.devicePixelRatio;
        this.ctx.scale(this.state.devicePixelRatio, this.state.devicePixelRatio);
        const calculatedWidth = (rect.width - (this.config.cols - 1) * this.config.gap) / this.config.cols;
        const calculatedHeight = (rect.height - (this.config.rows - 1) * this.config.gap) / this.config.rows;
        this.state.squareSize = Math.max(1, Math.floor(Math.min(calculatedWidth, calculatedHeight)));
        const totalGridWidth = this.config.cols * this.state.squareSize + (this.config.cols - 1) * this.config.gap;
        const totalGridHeight = this.config.rows * this.state.squareSize + (this.config.rows - 1) * this.config.gap;
        this.state.offsetX = Math.floor((rect.width - totalGridWidth) / 2);
        this.state.offsetY = Math.floor((rect.height - totalGridHeight) / 2);
    }
    
    getActiveSquareIndices() {
        if (!this._activeIndices) {
            this._activeIndices = [];
            this.state.squares.forEach((s, i) => {
                if (s.status === 'ACTIVE') this._activeIndices.push(i);
            });
        }
        return this._activeIndices;
    }

    drawRoundedRect(x, y, size, radius, color) {
        this.ctx.fillStyle = color;
        this.ctx.beginPath();
        this.ctx.moveTo(x + radius, y);
        this.ctx.arcTo(x + size, y, x + size, y + size, radius);
        this.ctx.arcTo(x + size, y + size, x, y + size, radius);
        this.ctx.arcTo(x, y + size, x, y, radius);
        this.ctx.arcTo(x, y, x + size, y, radius);
        this.ctx.closePath();
        this.ctx.fill();
    }

    drawSquare(square, c, r) {
        const x = this.state.offsetX + c * (this.state.squareSize + this.config.gap);
        const y = this.state.offsetY + r * (this.state.squareSize + this.config.gap);
        const color = square.isBlinking ? this.config.colors.ACTIVE_BLINK : this.config.colors[square.status];
        this.drawRoundedRect(x, y, this.state.squareSize, this.config.cornerRadius, color);
    }

    destroyAnimation() {
      if(this.state.animationFrameId) cancelAnimationFrame(this.state.animationFrameId);
      if(this.state.blinkIntervalId) clearInterval(this.state.blinkIntervalId);
      this.state.animationFrameId = null;
      this.state.blinkIntervalId = null;
    }
    
    resize() {
        this.destroyAnimation();
        this.init(); // 重新绘制空网格
        // 这里依赖dashboard.js在resize后重新获取并传入数据
    }

    debounce(func, delay) {
        let timeout;
        return (...args) => {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), delay);
        };
    }
}
