#!/usr/bin/env node

import { readdirSync, readFileSync, statSync } from 'node:fs'
import { join, relative } from 'node:path'

const appRoot = join(process.cwd(), 'src', 'app')

const textLikePatterns = [
  /<p\b/g,
  /<span\b/g,
  /<li\b/g,
  /<h[1-6]\b/g,
  /<ReactMarkdown\b/g,
  /prose\b/g,
  /leading-\d/g,
]

const controlPatterns = [
  /<button\b/g,
  /<select\b/g,
  /<input\b/g,
  /<Link\b/g,
  /role=["']tab/g,
  /type=["']checkbox/g,
]

const layoutPatterns = [
  /grid-cols-/g,
  /flex\b/g,
  /overflow-y-auto/g,
  /sticky\b/g,
]

const textWallPatterns = [
  /max-w-(?:2xl|3xl|4xl|5xl|6xl|7xl)/g,
  /line-clamp-[4-9]/g,
  /prose\b/g,
  /<ReactMarkdown\b/g,
]

const manualTerms = [
  /\u4eba\u5de5/g,
  /\u624b\u52d5/g,
  /manual/gi,
  /needs_human/gi,
  /human_/gi,
]

const fixedTaxonomyPatterns = [
  /const\s+CATEGORIES\s*=/g,
]

function collectPages(dir, acc = []) {
  for (const name of readdirSync(dir)) {
    const fullPath = join(dir, name)
    const stats = statSync(fullPath)
    if (stats.isDirectory()) {
      collectPages(fullPath, acc)
    } else if (name === 'page.tsx') {
      acc.push(fullPath)
    }
  }
  return acc
}

function countMatches(source, patterns) {
  return patterns.reduce((sum, pattern) => sum + (source.match(pattern) ?? []).length, 0)
}

function routeFromPage(filePath) {
  return relative(appRoot, filePath)
    .replace(/\/page\.tsx$/, '')
    .replace(/\[locale\]/, ':locale')
}

const pages = collectPages(appRoot)
  .map(filePath => {
    const source = readFileSync(filePath, 'utf8')
    const lineCount = source.split('\n').length
    const textSignals = countMatches(source, textLikePatterns)
    const controls = countMatches(source, controlPatterns)
    const layoutSignals = countMatches(source, layoutPatterns)
    const textWallSignals = countMatches(source, textWallPatterns)
    const manualSignals = countMatches(source, manualTerms)
    const fixedTaxonomySignals = countMatches(source, fixedTaxonomyPatterns)
    const nestedCardSignals = (source.match(/rounded-(?:md|lg|xl)[^`'"]*border/g) ?? []).length
    const score =
      Math.round(
        (textSignals * 1.2)
        + (textWallSignals * 8)
        + (manualSignals * 4)
        + (fixedTaxonomySignals * 10)
        + (nestedCardSignals * 0.7)
        - (controls * 1.5)
        - (layoutSignals * 0.4),
      )

    return {
      route: routeFromPage(filePath),
      file: relative(process.cwd(), filePath),
      lines: lineCount,
      score,
      textSignals,
      controls,
      layoutSignals,
      textWallSignals,
      manualSignals,
      fixedTaxonomySignals,
      nestedCardSignals,
    }
  })
  .sort((a, b) => b.score - a.score)

console.log('AWOOOI_UI_DENSITY_AUDIT')
console.table(
  pages.slice(0, 20).map(page => ({
    route: page.route,
    score: page.score,
    lines: page.lines,
    text: page.textSignals,
    controls: page.controls,
    manual: page.manualSignals,
    fixedTaxonomy: page.fixedTaxonomySignals,
  })),
)

console.log(JSON.stringify({
  page_count: pages.length,
  top_routes: pages.slice(0, 20),
}, null, 2))
