import type { DevToolbarRule } from "./types.ts";
import { createIssue } from "./helpers.ts";

export const seoRules: DevToolbarRule[] = [
  {
    id: "seo/document",
    category: "seo",
    defaultSeverity: "warning",
    description: "Validates core document metadata.",
    run: ({ document }) => {
      const issues = [];
      const title = document.title.trim();
      if (!title)
        issues.push(
          createIssue({
            ruleId: "seo/title-missing",
            category: "seo",
            severity: "error",
            title: "Page title is missing",
            message: "The document does not have a useful title.",
            recommendation: "Add a unique title describing this page.",
          }),
        );
      else if (title.length < 20 || title.length > 65)
        issues.push(
          createIssue({
            ruleId: "seo/title-length",
            category: "seo",
            severity: "warning",
            title: "Page title length may be suboptimal",
            message: `The title contains ${title.length} characters.`,
            recommendation: "Keep most titles between about 20 and 65 characters.",
            confidence: "medium",
          }),
        );
      const description = document
        .querySelector<HTMLMetaElement>('meta[name="description"]')
        ?.content.trim();
      if (!description)
        issues.push(
          createIssue({
            ruleId: "seo/description-missing",
            category: "seo",
            severity: "warning",
            title: "Meta description is missing",
            message: "Search and social previews may not have a useful description.",
            recommendation: "Add a unique meta description for the page.",
          }),
        );
      else if (description.length < 70 || description.length > 170)
        issues.push(
          createIssue({
            ruleId: "seo/description-length",
            category: "seo",
            severity: "suggestion",
            title: "Meta description length may be suboptimal",
            message: `The description contains ${description.length} characters.`,
            recommendation: "Aim for a concise description of roughly 70–170 characters.",
            confidence: "medium",
          }),
        );
      if (!document.querySelector('meta[name="viewport"]'))
        issues.push(
          createIssue({
            ruleId: "seo/viewport-missing",
            category: "seo",
            severity: "error",
            title: "Viewport meta tag is missing",
            message: "The page may render incorrectly on mobile devices.",
            recommendation: "Add width=device-width, initial-scale=1.",
          }),
        );
      if (!document.querySelector('link[rel="canonical"]'))
        issues.push(
          createIssue({
            ruleId: "seo/canonical-missing",
            category: "seo",
            severity: "suggestion",
            title: "Canonical URL is missing",
            message: "Search engines have no explicit preferred URL for this page.",
            recommendation: "Add a canonical link for public indexable pages.",
            confidence: "medium",
          }),
        );
      const h1s = document.querySelectorAll("h1");
      if (h1s.length === 0)
        issues.push(
          createIssue({
            ruleId: "seo/h1-missing",
            category: "seo",
            severity: "warning",
            title: "Page has no h1 heading",
            message: "The page lacks a clear primary heading.",
            recommendation: "Add one descriptive h1.",
          }),
        );
      if (h1s.length > 1)
        issues.push(
          createIssue({
            ruleId: "seo/multiple-h1",
            category: "seo",
            severity: "suggestion",
            title: "Page has multiple h1 headings",
            message: `Found ${h1s.length} h1 elements.`,
            recommendation:
              "Use one clear primary page heading unless multiple h1 elements are intentional.",
            confidence: "medium",
          }),
        );
      return issues;
    },
  },
];
