/**
 * cli:extract-doc — types.ts
 *
 * Read-only extraction for the /documentation skill. Produces a JSON report
 * (NO file writes) that Claude consumes to author a faithful doc page:
 *   - the real page TSX path (so Claude can read & reproduce it),
 *   - chart type per imported chart (recharts → Mock UI pattern),
 *   - API endpoints, business rules, entity properties,
 *   - a suggested i18n namespace + base routes for the wiring step.
 *
 * Extraction is richest for `user` (reads page + controller + entity + tests).
 * For developer/testing the report is intentionally thin — those docs are
 * authored from external/tool knowledge, not from project code.
 */
import { z } from 'zod'

export const ExtractDocInputSchema = z.object({
  type: z.enum(['user', 'developer', 'database', 'testing']),
  /** Module / tool / schema name, lowercase (e.g. "users", "sla", "support"). */
  target: z.string().min(1),
  /** Parent application for `user` docs (e.g. "administration"). */
  application: z.string().min(1).optional(),
  /** Explicit page TSX (relative to projectPath) to document — overrides auto-detection. */
  pagePath: z.string().min(1).optional(),
  /** Absolute path to the SmartStack project root being documented. */
  projectPath: z.string().min(1),
})

export type ExtractDocInput = z.infer<typeof ExtractDocInputSchema>

export interface ChartInfo {
  /** Imported chart component name (e.g. "WeeklyUsageChart"). */
  component: string
  /** Raw import specifier (e.g. "@/components/dashboard/WeeklyUsageChart"). */
  importPath: string
  /** Resolved source file (relative to project root) or null if unresolved. */
  sourceFile: string | null
  /** Detected recharts primitive (BarChart | PieChart | LineChart | …). */
  rechartsType: string | null
  /** `layout=` prop value when present (drives vertical vs horizontal bars). */
  layout: string | null
  /** Human guidance for the faithful Mock UI pattern to generate. */
  mockUiPattern: string
}

export interface ApiEndpoint {
  method: string
  path: string
  handler: string
  permission: string
}

export interface BusinessRule {
  id: string
  name: string
  category: string
  statement: string
}

export interface EntityProperty {
  name: string
  type: string
  nullable: boolean
}

/**
 * A forbidden "sales" framing detected in an EXISTING doc artifact
 * (problème/solution, Bénéfices, Avant/Après). Documentation leads with a
 * factual `objective` — never a value-proposition pitch (SKILL.md rule #12).
 */
export interface ForbiddenSection {
  /** File the token was found in (relative to project root). */
  file: string
  /** 1-based line number. */
  line: number
  /** The offending token (problem | solution | benefits | beforeAfter | a literal section title). */
  token: string
  /** Trimmed source line (truncated) for the report. */
  snippet: string
}

/** Scan of the EXISTING doc page / doc-data / i18n for structural compliance. */
export interface ExistingDocReport {
  /** Whether any existing doc artifact was located for this module. */
  found: boolean
  /** Located artifacts (index.tsx / doc-data.ts / docs-<kebab>.json), relative to project root. */
  files: string[]
  /** Forbidden sections still present — non-empty means the doc must be corrected. */
  forbiddenSections: ForbiddenSection[]
  /**
   * Mandatory elements ABSENT from an existing doc (the mirror of
   * `forbiddenSections`). May contain:
   *   - `'objective'` — the factual Section 1 that replaced problème/solution
   *     (all doc types; SKILL.md rule #12).
   *   - `'summary'` — the header accent tagline (`user` type only; the one-line
   *     accent summary between title and subtitle).
   * Empty when the doc is compliant, or when none was found yet (nothing to
   * require before the doc is authored).
   */
  missingRequired: string[]
}

export interface ExtractReport {
  type: string
  target: string
  application: string | null
  /** Suggested i18n namespace, e.g. "docsAdministrationUsers". */
  namespace: string
  resolved: {
    projectRoot: string
    webRoot: string | null
    apiDir: string | null
    domainDir: string | null
    /** Real page TSX (relative to project root) Claude must read & reproduce. */
    pageTsxPath: string | null
    pageCandidatesTried: string[]
  }
  navRoute: string | null
  /** Best-effort frontend routes for wiring (DocPanelContext keys / manifest). */
  suggestedRoutes: string[]
  charts: ChartInfo[]
  apiEndpoints: ApiEndpoint[]
  businessRules: BusinessRule[]
  entity: { name: string; file: string | null; properties: EntityProperty[] } | null
  /** Forbidden-section scan of the EXISTING doc (drives the step-03 corrective gate). */
  existingDoc: ExistingDocReport
}

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