import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState, } from "react";
import chromajs from "chroma-js";
import Styles from "./PixelatedScan.module.scss";
const AnimDuration = Number(Styles.animationDuration);
/**
 * This effect scans up and down on the div with a following pixelated trail
 **/
/**
 * A visual animation component that creates a pixelated scanning effect.
 * It generates a grid of colored squares that animate in waves to create
 * a dynamic, pixel-art style visual pattern.
 */
export default function PixelatedScan({ squaresByLine, color, className = "", }) {
    const iteration = useRef(0);
    const tableRef = useRef(null);
    const [config, setConfig] = useState();
    useEffect(() => {
        const squareSize = tableRef.current.clientWidth / squaresByLine;
        const howMuchLines = tableRef.current.clientHeight / squareSize;
        setConfig({
            squareSize,
            howMuchLines,
        });
    }, []);
    const rowsDef = useMemo(() => {
        return new Array(Math.ceil(config?.howMuchLines || 0)).fill(undefined);
    }, [config]);
    const lineDef = useMemo(() => {
        return new Array(squaresByLine).fill(undefined);
    }, [config]);
    return (_jsx(_Fragment, { children: _jsxs("div", { className: `${Styles.grid} ${Styles.iterate} ${className}`, ref: tableRef, children: [rowsDef.map((_, iRow, _rows) => (_jsx(GridRow, { squares: lineDef, size: config.squareSize, baseColor: color, lineCount: config.howMuchLines, lineIndex: iRow, onFinish: iRow === _rows.length - 6
                        ? () => {
                            tableRef.current.classList.remove(Styles.iterate);
                            iteration.current += 1;
                            if (iteration.current % 2 === 1)
                                tableRef.current.classList.add(Styles.inverse);
                            else
                                tableRef.current.classList.remove(Styles.inverse);
                            setTimeout(() => {
                                tableRef.current.classList.add(Styles.iterate);
                            }, 100);
                        }
                        : undefined }, `${iRow}`))), _jsx("div", { className: Styles.guide })] }) }));
}
function GridRow({ onFinish, squares, size, baseColor, lineCount, lineIndex, }) {
    const ref = useRef(null);
    const gridItemsRefs = useRef([]);
    useEffect(() => {
        function updateColor() {
            gridItemsRefs.current.forEach((i) => i?.updateColor());
        }
        ref.current?.addEventListener("animationend", updateColor);
        return () => {
            ref.current?.removeEventListener("animationend", updateColor);
        };
    }, []);
    return (_jsx("div", { className: Styles.gridAnimate, onAnimationEnd: onFinish, style: {
            animationDelay: `${(AnimDuration / lineCount) * (lineIndex - 1)}ms`,
        }, children: squares.map((_, i) => (_jsx(GridItem, { ref: (refNode) => {
                gridItemsRefs.current[i] = refNode;
            }, size: size, baseColor: baseColor }, i))) }));
}
function _GridItem({ size, baseColor = "#ff0", }, externalRef) {
    const ref = useRef(null);
    function calculateNewRandomColorStrength() {
        const color = chromajs.hex(baseColor).alpha(1 - Math.random() * 0.3);
        return color;
    }
    const [randomColorStrength, setRandomColorStrength] = useState(calculateNewRandomColorStrength);
    useImperativeHandle(externalRef, () => ({
        updateColor: () => {
            setRandomColorStrength(calculateNewRandomColorStrength());
        },
    }), []);
    return (_jsx("div", { ref: ref, className: Styles.gridItem, style: {
            width: size,
            height: size,
            ...{ "--pixel-color": randomColorStrength.hex() },
        } }));
}
const GridItem = forwardRef(_GridItem);
//# sourceMappingURL=PixelatedScan.js.map