import type { DevToolbarRule } from "./types.ts";
import { contrastRatio, createIssue, effectiveBackground, isVisible, parseRgb } from "./helpers.ts";

export const colorRules: DevToolbarRule[] = [
  {
    id: "color/contrast",
    category: "color",
    defaultSeverity: "warning",
    description: "Checks basic text contrast against computed solid backgrounds.",
    run: ({ root }) => {
      const issues = [];
      const candidates = root.querySelectorAll(
        "p,span,a,button,label,input,textarea,select,h1,h2,h3,h4,h5,h6,li,td,th",
      );
      for (const element of candidates) {
        if (
          !isVisible(element) ||
          !(element.textContent?.trim() || element instanceof HTMLInputElement)
        )
          continue;
        const style = getComputedStyle(element);
        const foreground = parseRgb(style.color);
        const background = effectiveBackground(element);
        if (!foreground || !background || foreground[3] < 0.95) continue;
        const ratio = contrastRatio(foreground, background);
        const fontSize = Number.parseFloat(style.fontSize);
        const fontWeight = Number.parseInt(style.fontWeight, 10) || 400;
        const large = fontSize >= 24 || (fontSize >= 18.66 && fontWeight >= 700);
        const required = large ? 3 : 4.5;
        if (ratio < required)
          issues.push(
            createIssue({
              ruleId: "color/contrast",
              category: "color",
              severity: ratio < 2 ? "error" : "warning",
              title: "Text contrast is too low",
              message: `Computed contrast is ${ratio.toFixed(2)}:1; this text generally needs at least ${required}:1.`,
              element,
              recommendation: "Increase the difference between text and background colors.",
              confidence: "medium",
              metadata: { ratio, required },
            }),
          );
      }
      return issues;
    },
  },
];
