/**
 * cli:scaffold-seed — validate.ts
 */
import { ScaffoldSeedInputSchema, type ScaffoldSeedInput, type ValidationResult } from './types.js'

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

export function validateBusinessRules(spec: ScaffoldSeedInput): ValidationResult {
  const errors: string[] = []
  const warnings: string[] = []

  // Application-level entries are now seeded by scaffold-core-seed (Phase 0).
  // If a caller still passes one here, warn — they likely meant to call
  // scaffold-core-seed instead. Empty navigation is the new normal for
  // ref-data-only providers.
  const apps = spec.navigation.filter(n => n.level === 'application')
  if (apps.length > 0) {
    warnings.push(
      `scaffold-seed received ${apps.length} application-level navigation entry/entries — these belong to scaffold-core-seed (Phase 0). Module-level scaffold-seed should only carry section/resource overrides or reference data.`,
    )
  }

  // Permissions should reference existing sections
  const sectionCodes = new Set(spec.navigation.filter(n => n.level === 'section').map(n => n.code))
  for (const perm of spec.permissions) {
    if (!sectionCodes.has(perm.sectionCode)) {
      warnings.push(`Permission ${perm.path} references unknown section: ${perm.sectionCode}`)
    }
  }

  // Role permissions should reference existing roles and permissions
  const roleCodes = new Set(spec.roles.map(r => r.code))
  const permPaths = new Set(spec.permissions.map(p => p.path))
  for (const rp of spec.rolePermissions) {
    if (!roleCodes.has(rp.roleCode)) {
      warnings.push(`Role-permission references unknown role: ${rp.roleCode}`)
    }
    if (!permPaths.has(rp.permissionPath)) {
      warnings.push(`Role-permission references unknown permission: ${rp.permissionPath}`)
    }
  }

  // Test users must reference existing roles. Hard error since Phase 5 needs
  // these to log in by role — a silent warning would manifest as 401s in tests.
  for (const tu of spec.testUsers) {
    if (!roleCodes.has(tu.roleCode)) {
      errors.push(`Test user references unknown role: ${tu.roleCode}. Add the role to spec.roles or fix the typo.`)
    }
  }

  return { valid: errors.length === 0, errors, warnings }
}

export function validate(raw: unknown): ValidationResult {
  const structural = validateStructure(raw)
  if (!structural.valid) return structural
  return validateBusinessRules(raw as ScaffoldSeedInput)
}
