/**
 * cli:scaffold-doc — types.ts
 *
 * The deterministic side of doc generation. It does the file operations that
 * are stable + error-prone for an LLM to do by hand:
 *   - write the 4 i18n locale JSON files at the canonical path + shape (FLAT),
 *   - idempotently upsert the `docs-manifest.json` entry (pure JSON),
 *   - compute a precise WIRING PLAN (file + anchor + snippet + idempotency
 *     marker) for the in-place TSX edits (i18n config.ts, DocRoutes.tsx,
 *     DocPanelContext.tsx, UserIndexPage.tsx).
 *
 * The TSX edits themselves are returned as instructions (not auto-applied):
 * those files vary across client projects, so Claude applies them with Edit,
 * adapting to the real file — robust where a hardcoded regex would corrupt code.
 * The doc page body + i18n CONTENT stay authored by Claude (templates.md).
 */
import { z } from 'zod'

export const LANGS = ['fr', 'en', 'de', 'it'] as const

export const ScaffoldDocInputSchema = z.object({
  type: z.enum(['user', 'developer', 'database', 'testing']),
  /** Module / tool / schema name, lowercase (e.g. "users"). */
  target: z.string().min(1),
  /** Parent application (e.g. "administration"). */
  application: z.string().min(1).optional(),
  /** i18n namespace, camelCase (e.g. "docsAdministrationUsers"). From extract-doc. */
  namespace: z.string().min(1),
  /** Route under /docs/business, no leading slash (e.g. "administration/users"). */
  routePath: z.string().min(1),
  /** Lazy component name for the route (e.g. "UsersDocPage"). */
  componentName: z.string().min(1),
  /** Page import specifier (e.g. "@/pages/docs/business/platform/administration/users"). */
  pageImportPath: z.string().min(1),
  /** Per-language i18n content (FLAT objects). FR is the source. Optional — Claude may write these itself. */
  i18n: z.record(z.enum(LANGS), z.record(z.string(), z.unknown())).optional(),
  manifest: z.object({
    id: z.string().min(1),
    name: z.string().min(1),
    description: z.string().default(''),
    version: z.string().default('1.0.0'),
    deferredLanguages: z.array(z.string()).default([]),
  }),
  /** Pathname keys for DocPanelContext docMapping (e.g. ["administration/users","administration/users/list"]). */
  docMappings: z.array(z.string()).default([]),
  /** When true, also set appDocMapping[application] to this doc (the app's default doc). */
  appDocDefault: z.boolean().default(false),
  projectPath: z.string().min(1),
  dryRun: z.boolean().default(false),
})

export type ScaffoldDocInput = z.infer<typeof ScaffoldDocInputSchema>

export interface WiringInstruction {
  /** Target file, relative to project root. Null if the file could not be located. */
  file: string | null
  /** Human description of the edit. */
  action: string
  /** A unique string already in the file, near where the insert goes. */
  anchor: string
  /** The text Claude should insert (usually right after the anchor / inside the anchored block). */
  insert: string
  /** If this string is already in the file, the wiring is done — skip (idempotency). */
  idempotencyMarker: string
}

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