/**
 * This is a custom formatter for eslint, to print the output grouped by rules.
 * It is also possible, to filter by a specific rule.
 * Run this command via `RULE=no-prototype-builtins yarn lint:grouped`
 * (no-prototype-builtins is the rule you want to filter for)
 * or without a specific rule via `yarn lint:grouped`.
 *
 * { This code was proudly generated by chatGPT }
 *
 * #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### #### ####
 *
 * TLDR:
 * usage:             `yarn lint:grouped`
 * usage (with rule): `RULE=no-prototype-builtins yarn lint:grouped`
 */
module.exports = (results) => {
  const filterRule = process.env.FILTER_RULE
  const grouped = {}
  const ruleCount = {}

  results.forEach((result) =>
    result.messages.forEach((message) => {
      const ruleId = message.ruleId || "unknown"

      if (filterRule && ruleId !== filterRule) {
        return
      }

      if (!grouped[ruleId]) {
        grouped[ruleId] = []
      }

      const shortenedPath = result.filePath.replace(
        /^.*\/frontend\//,
        "client/",
      )

      grouped[ruleId].push({
        filePath: shortenedPath,
        line: message.line,
        column: message.column,
        message: message.message,
        severity: message.severity === 2 ? "error" : "warning",
      })

      // Zähle Vorkommnisse pro Regel
      if (!ruleCount[ruleId]) {
        ruleCount[ruleId] = 0
      }
      ruleCount[ruleId]++
    }),
  )

  let output = ""

  Object.entries(grouped).forEach(([ruleId, messages]) => {
    // Nehme den ersten Fehler und setze ihn hinter dem Rule-Namen
    const firstMessage = messages[0]
    const ruleMessage = firstMessage.message // Fehlernachricht aus der ersten Nachricht
    const severity = firstMessage.severity === "error" ? "\x1b[31m" : "\x1b[33m"

    // Rule in Lila (Magenta) und Fehlernachricht in Klammern
    output += `\n\x1b[35m${ruleId} (${severity}${ruleMessage}\x1b[0m)\n`

    // Durchlaufe alle Nachrichten und zeige nur den Pfad mit Zeile und Spalte
    messages.forEach((msg) => {
      const location = `\x1b[34m${msg.filePath}\x1b[0m:${msg.line}:${msg.column}`

      output += `  ${location}  \x1b[90m${msg.message}\n`
    })
  })

  const totalErrors = results.reduce(
    (sum, file) =>
      sum +
      file.messages.filter(
        (msg) =>
          msg.severity === 2 && (!filterRule || msg.ruleId === filterRule),
      ).length,
    0,
  )
  const totalWarnings = results.reduce(
    (sum, file) =>
      sum +
      file.messages.filter(
        (msg) =>
          msg.severity === 1 && (!filterRule || msg.ruleId === filterRule),
      ).length,
    0,
  )

  output += `\n\x1b[37m${totalErrors} error${totalErrors !== 1 ? "s" : ""}, ${totalWarnings} warning${totalWarnings !== 1 ? "s" : ""} found.\x1b[0m\n`

  // Sortiere die Regeln nach Vorkommnissen (absteigend)
  const sortedRuleCount = Object.entries(ruleCount).sort((a, b) => b[1] - a[1])

  if (!filterRule) {
    // Ausgabe der Regeln nach Häufigkeit sortiert
    output += `\n\x1b[37mRules with occurrences (sorted by count):\x1b[0m\n`
    sortedRuleCount.forEach(([ruleId, count]) => {
      output += `  \x1b[35m${ruleId}\x1b[0m  \x1b[37m${count} occurrence${count !== 1 ? "s" : ""}\x1b[0m\n`
    })

    output +=
      "use RULE=no-prototype-builtins yarn lint:grouped to filter for rules now"
  }

  return output.trim()
}
