/**
 * cli:scaffold-routes — validate.ts
 *
 * Structural Zod validation + non-blocking filesystem cross-check: every
 * entity × view combination is expected to have a matching `.tsx` page under
 * `{projectPath}/src/pages/{module}/{section}/`. Missing pages are
 * reported as warnings so the caller (Frontend subagent) knows which pages to
 * scaffold BEFORE writing the aggregated registry. Never blocks — the CLI may
 * legitimately run before scaffold-component in some flows.
 */
import fs from 'node:fs'
import path from 'node:path'
import {
  ScaffoldRoutesInputSchema,
  type ScaffoldRoutesInput,
  type ValidationResult,
} from './types.js'

function pageNameFor(entity: string, view: string): string {
  // List uses plural (BudgetsListPage); detail/form stay singular. Aligns
  // with scaffold-component's emitted file names and the actual SmartStack
  // project layout.
  if (view === 'list') return `${entity}sListPage`
  if (view === 'detail') return `${entity}DetailPage`
  if (view === 'create' || view === 'edit') return `${entity}FormPage`
  return `${entity}${view.charAt(0).toUpperCase() + view.slice(1)}Page`
}

function checkPagesExist(spec: ScaffoldRoutesInput): string[] {
  const warnings: string[] = []
  // Pages live at src/pages/{module}/{section}/ — no appLower prefix.
  // This matches scaffold-component's emit path exactly, so the registry
  // imports point at real files instead of phantom paths.
  const pagesBase = path.join(spec.projectPath, 'src', 'pages', spec.module)
  for (const entity of spec.entities) {
    const sectionDir = path.join(pagesBase, entity.section)
    for (const view of entity.views) {
      const pageName = pageNameFor(entity.name, view)
      const candidates = [
        path.join(sectionDir, `${pageName}.tsx`),
        path.join(sectionDir, `${pageName}.ts`),
        path.join(sectionDir, pageName, 'index.tsx'),
        path.join(sectionDir, pageName, 'index.ts'),
      ]
      if (!candidates.some((c) => fs.existsSync(c))) {
        warnings.push(
          `Page missing for ${entity.name}.${view}: expected at ${path.relative(
            spec.projectPath,
            candidates[0],
          )} — run scaffold-component first, otherwise the registry will reference a phantom import (Vite fails at launch on those).`,
        )
      }
    }
  }
  return warnings
}

export function validate(raw: unknown): ValidationResult {
  const result = ScaffoldRoutesInputSchema.safeParse(raw)
  if (!result.success) {
    return {
      valid: false,
      errors: result.error.issues.map((i) => `[${i.path.join('.')}] ${i.message}`),
      warnings: [],
    }
  }
  return { valid: true, errors: [], warnings: checkPagesExist(result.data) }
}
