/**
 * Generates src/lib/viewRouteMeta.generated.ts from discovered PHP view files.
 * Run: node scripts/gen-view-route-meta.mjs
 */
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const projectRoot = path.resolve(__dirname, '..')
const parentRoot = path.resolve(projectRoot, '..')
const outFile = path.resolve(projectRoot, 'src/lib/viewRouteMeta.generated.ts')

const SKIP_DIRS = new Set([
  'layout',
  'partials',
  'errors',
  'pagination',
  'docs',
])

function humanize(slug) {
  const normalized = slug.replace(/(\.blade)?\.php$/i, '').replace(/_/g, ' ')
  return normalized.replace(/\b\w/g, (char) => char.toUpperCase())
}

function walk(dir, baseRel) {
  const out = []
  let entries = []

  try {
    entries = fs.readdirSync(dir, { withFileTypes: true })
  } catch {
    return out
  }

  for (const entry of entries) {
    const rel = path.join(baseRel, entry.name)
    const full = path.join(dir, entry.name)

    if (entry.isDirectory()) {
      if (SKIP_DIRS.has(entry.name)) continue
      out.push(...walk(full, rel))
      continue
    }

    if (entry.isFile() && /\.php$/i.test(entry.name)) {
      out.push(rel.replace(/\\/g, '/'))
    }
  }

  return out
}

function discoverViewRoots() {
  const roots = []
  const fromEnv = process.env.VIEW_SOURCE_ROOT?.trim()

  if (fromEnv) {
    roots.push(path.resolve(projectRoot, fromEnv))
  }

  let siblings = []
  try {
    siblings = fs.readdirSync(parentRoot, { withFileTypes: true })
      .filter((entry) => entry.isDirectory())
      .map((entry) => path.join(parentRoot, entry.name))
  } catch {
    siblings = []
  }

  for (const sibling of siblings) {
    roots.push(path.join(sibling, 'app', 'Views'))
    roots.push(path.join(sibling, 'resources', 'views'))
  }

  return [...new Set(roots)].filter((root) => fs.existsSync(root))
}

function resolveViewsRoot() {
  let best = null
  let bestCount = -1

  for (const candidate of discoverViewRoots()) {
    const count = walk(candidate, '').length
    if (count > bestCount) {
      best = candidate
      bestCount = count
    }
  }

  return best
}

function main() {
  const viewsRoot = resolveViewsRoot()
  if (!viewsRoot) {
    console.error('Missing PHP view source folder. Set VIEW_SOURCE_ROOT to override discovery.')
    process.exit(1)
  }

  const files = walk(viewsRoot, '')
    .filter((file) => !file.includes('/layout/'))
    .sort()

  const entries = []
  for (const file of files) {
    const parts = file.split('/')
    const base = parts.pop().replace(/(\.blade)?\.php$/i, '')
    const routeKey = [...parts, base].filter(Boolean).join('/')
    const sourceViewPath = file
    const title = humanize(base)
    entries.push({ routeKey, title, sourceViewPath })
  }

  const lines = []
  lines.push('/** Auto-generated by scripts/gen-view-route-meta.mjs — do not edit by hand. */')
  lines.push('')
  lines.push('export type ViewRouteMetaEntry = {')
  lines.push('  title: string')
  lines.push('  sourceViewPath: string')
  lines.push('}')
  lines.push('')
  lines.push('export const viewRouteMeta: Record<string, ViewRouteMetaEntry> = {')

  for (const { routeKey, title, sourceViewPath } of entries) {
    const safeTitle = title.replace(/\\/g, '\\\\').replace(/'/g, "\\'")
    const safeView = sourceViewPath.replace(/\\/g, '/')
    lines.push(`  '${routeKey}': { title: '${safeTitle}', sourceViewPath: '${safeView}' },`)
  }

  lines.push('}')
  lines.push('')

  fs.mkdirSync(path.dirname(outFile), { recursive: true })
  fs.writeFileSync(outFile, lines.join('\n'), 'utf8')
  console.log(`Wrote ${entries.length} entries → ${path.relative(process.cwd(), outFile)}`)
}

main()
