import { calculateScore } from "./calculateScore.js";
import { matchingSelector } from "./matchingSelector.js";

const DEFAULT_SCORE_POOL_MAIN_THREAD_YIELD = 15;

type ScorePool = {
    /**
     * The time in milliseconds the calculation took place.
     * This allows to avoid long-running-tasks in huge DOM sized pages.
     */
    calculationTime: number;
    items: {
        selector: CSSStyleRule["selectorText"];
        specificity: number;
        style: string | number;
    }[];
};

async function iterateRules(
    rules: CSSRuleList,
    element: HTMLElement,
    scoresPool: ScorePool,
    property: keyof CSSStyleDeclaration,
) {
    for (const ruleIdx in rules) {
        const rule = rules[ruleIdx];
        if (!(rule instanceof CSSStyleRule)) {
            continue;
        }

        const now = performance.now();

        if (scoresPool.calculationTime >= DEFAULT_SCORE_POOL_MAIN_THREAD_YIELD) {
            await new Promise((r) => setTimeout(r, 0));
            scoresPool.calculationTime = 0;
        }

        try {
            if (matchingSelector(element, rule.selectorText)) {
                const style = rule.style[property] as string | number;
                if (style !== undefined && style !== "") {
                    const { items } = scoresPool;
                    items.push({
                        ...calculateScore(rule, items.length, property),
                        style,
                    });
                }
            }
        } catch (e) {
            // Silence is golden.
        }

        scoresPool.calculationTime += performance.now() - now;
    }
}

export { iterateRules, type ScorePool };
