export interface TouchTargetAnalysis {
  totalInteractiveElements: number;
  tooSmallCount: number;
  tooCloseCount: number;
  passRate: number;
  issues: string[];
}

export function analyzeTouchTargets(domHtml: string): TouchTargetAnalysis {
  const anchorMatches = domHtml.match(/<a[\s>][^>]*>/gi) ?? [];
  const buttonMatches = domHtml.match(/<button[\s>][^>]*>/gi) ?? [];
  const inputMatches = domHtml.match(/<input[\s>][^>]*>/gi) ?? [];
  const selectMatches = domHtml.match(/<select[\s>][^>]*>/gi) ?? [];

  const totalInteractiveElements =
    anchorMatches.length + buttonMatches.length + inputMatches.length + selectMatches.length;

  // Detect explicitly small pixel dimensions in style attributes on interactive elements
  let tooSmallCount = 0;
  const interactiveHtml = [...anchorMatches, ...buttonMatches, ...inputMatches].join(" ");
  const smallDimensionPattern = /(?:width|height)\s*:\s*(\d+)px/gi;
  let m: RegExpExecArray | null;
  while ((m = smallDimensionPattern.exec(interactiveHtml)) !== null) {
    if (parseInt(m[1], 10) < 44) tooSmallCount++;
  }

  // Inline prose links are hard to tap on mobile
  const proseInlineLinks = (domHtml.match(/<p[^>]*>[\s\S]{0,300}<a[\s>]/gi) ?? []).length;
  tooSmallCount += Math.floor(proseInlineLinks * 0.3);

  // Dense list-link clusters likely have insufficient spacing
  const listLinkMatches = domHtml.match(/<li[^>]*>\s*<a[\s>]/gi) ?? [];
  const tooCloseCount =
    listLinkMatches.length > 10 ? Math.floor(listLinkMatches.length * 0.2) : 0;

  const issues: string[] = [];
  if (tooSmallCount > 0) {
    issues.push(
      `Estimated ${tooSmallCount} interactive element(s) may be below the 44px minimum touch target size`,
    );
  }
  if (tooCloseCount > 0) {
    issues.push(
      "Navigation or list links may be spaced too closely for reliable touch activation",
    );
  }

  const passRate =
    totalInteractiveElements > 0
      ? Math.max(
          0,
          Math.round(
            ((totalInteractiveElements - tooSmallCount) / totalInteractiveElements) * 100,
          ),
        )
      : 100;

  return { totalInteractiveElements, tooSmallCount, tooCloseCount, passRate, issues };
}
