/**
 * cli:scaffold-seed — types.ts
 * Source de vérité unique : IClientSeedDataProvider generation schemas.
 * IClientSeedDataProvider interface comes from SmartStack.Application NuGet package.
 */
import { z } from 'zod'

export const NavigationEntrySchema = z.object({
  level: z.enum(['application', 'module', 'section', 'resource']),
  code: z.string().min(1).regex(/^[a-z][a-z0-9-]*$/, 'code must be kebab-case and start with a letter'),
  label: z.string().min(1),
  parentCode: z.string().optional(),
  icon: z.string().default('Circle'),
  iconType: z.string().default('Lucide'),
  route: z.string().min(1),
  displayOrder: z.number().default(1),
  componentKey: z.string().optional(),
})

export const RoleEntrySchema = z.object({
  name: z.string().min(1),
  code: z.string().min(1),
  applicationCode: z.string().min(1),
  isDefault: z.boolean().default(false),
})

export const PermissionEntrySchema = z.object({
  path: z.string().regex(/^[\w]+\.[\w]+\.[\w]+\.[\w]+$/, 'Permission path must be {app}.{module}.{section}.{action}'),
  action: z.string().min(1),
  sectionCode: z.string().min(1),
})

export const RolePermissionSchema = z.object({
  roleCode: z.string().min(1),
  permissionPath: z.string().min(1),
})

/**
 * Test user — one per seeded role for Phase 5 UI tests. Gated by
 * IHostEnvironment.IsDevelopment() in the generated C# provider so
 * production deployments never seed these.
 */
export const TestUserEntrySchema = z.object({
  roleCode: z.string().min(1),
  /** Local part of the email (e.g. "admin" → admin.test@smartstack.local). Defaults to roleCode. */
  emailLocalPart: z.string().optional(),
})

export const ScaffoldSeedInputSchema = z.object({
  module: z.string().min(1),
  appCode: z.string().min(1).regex(
    /^[A-Za-z][A-Za-z0-9-]*$/,
    'appCode must start with a letter and contain only letters, digits and hyphens (PascalCase like "TestV2" or kebab like "test-v2")',
  ),
  /**
   * Per-application navigation code (kebab-case, e.g. "crm" or "budgeting").
   * Drives the per-app sub-folder under `Persistence/Seeding/Applications/{AppPascal}/Modules/{Module}/`.
   * Distinct from `appCode` (the .NET project namespace prefix).
   */
  applicationCode: z.string().min(1).regex(
    /^[a-z][a-z0-9-]*$/,
    'applicationCode must be kebab-case (lowercase) and start with a letter',
  ),
  namespace: z.string().optional(),
  // Navigation/roles/permissions are now generated by scaffold-core-seed (Phase 0)
  // for the whole app in one shot. scaffold-seed is for module-level seeds only —
  // typically reference data (lookup tables, enum codes) declared inline below
  // OR a per-module override registered separately when the Core seed needs
  // augmentation. All arrays default to empty so the CLI can produce a
  // ref-data-only provider that returns Task.CompletedTask for the navigation
  // phase.
  navigation: z.array(NavigationEntrySchema).default([]),
  roles: z.array(RoleEntrySchema).default([]),
  permissions: z.array(PermissionEntrySchema).default([]),
  rolePermissions: z.array(RolePermissionSchema).default([]),
  testUsers: z.array(TestUserEntrySchema).default([]),
  /** Shared dev password for all test users. Hardcoded in generated C# (dev-only). */
  testUserPassword: z.string().min(8).default('DevTest!2026Secure'),
  /** Domain part of test user emails. Default `smartstack.local` keeps them out of any real MX lookup. */
  testUserEmailDomain: z.string().default('smartstack.local'),
  /** When false, the manifest at tests/ui-test/test-users.json is NOT written. Default true. */
  emitDevCredentialsManifest: z.boolean().default(true),
  projectPath: z.string().min(1),
  order: z.number().default(100),
})

export type NavigationLevel = 'application' | 'module' | 'section' | 'resource'
export type NavigationEntry = z.infer<typeof NavigationEntrySchema>
export type RoleEntry = z.infer<typeof RoleEntrySchema>
export type PermissionEntry = z.infer<typeof PermissionEntrySchema>
export type RolePermission = z.infer<typeof RolePermissionSchema>
export type TestUserEntry = z.infer<typeof TestUserEntrySchema>
export type ScaffoldSeedInput = z.infer<typeof ScaffoldSeedInputSchema>

export interface GeneratedFile {
  path: string
  content: string
}

export interface ValidationResult {
  valid: boolean
  errors: string[]
  warnings: string[]
}
