/**
 * audit-dev-wire / types.ts — CLI args + finding + report shapes.
 *
 * Mirrors `audit-dev-api/types.ts` so the orchestrator UI renders both audits
 * with one component. Single-rule MVP (DEV-WIRE-001 frontend-orphan); the
 * other 2 rule slots (DEV-WIRE-002/003) are reserved in the schema for
 * forward compatibility with the auto-healing failure kinds.
 */
import { z } from 'zod'
import type { Stratum } from '../../../../lib/url-conventions.js'

export const AuditDevWireModeSchema = z.enum(['audit', 'apply'])
export type AuditDevWireMode = z.infer<typeof AuditDevWireModeSchema>

export const AuditDevWireArgsSchema = z.object({
  /** Absolute path to the .NET backend root (holds src/<Ns>.Api/Controllers/**). */
  backendPath: z.string().min(1),
  /** Absolute path to the web project root (holds src/features/**). */
  webPath: z.string().min(1),
  /** `audit` = report only ; `apply` is a stub (no-op in MVP). */
  mode: AuditDevWireModeSchema.default('audit'),
  /** Active module code (PRD scope) — embedded in the markdown report. */
  moduleCode: z.string().min(1),
  /** Active application code (PRD scope) — embedded in the markdown report. */
  appCode: z.string().min(1),
  /** Subset of rule codes to run. Empty = all implemented rules. */
  rules: z.array(z.string()).default([]),
})

export type AuditDevWireArgs = z.infer<typeof AuditDevWireArgsSchema>

export type Severity = 'err' | 'warn' | 'ok'

export interface Finding {
  dimension: 'devWire'
  code: string
  severity: Severity
  label: string
  params: Record<string, unknown>
  solution: string
  fixSkill?: string
  fixPhaseKey?: string
  file?: string
}

// ─── Internal call/route shapes ──────────────────────────────────────────

/** One URL call extracted from a frontend service or hook. */
export interface FrontendCall {
  /** Lowercase verb: 'get' / 'post' / 'put' / 'patch' / 'delete'. */
  verb: string
  /** Full URL path with `{id}` placeholders normalised. */
  urlPath: string
  /** Source file relative to webPath. */
  file: string
  /** Source line for navigation. */
  line: number
}

/** One backend controller route. Mirrors audit-dev-api's ControllerEndpointEntry. */
export interface BackendRoute {
  verb: string
  /** Full URL path (class route + method suffix), with `{id:guid}` → `{id}`. */
  urlPath: string
  /** Source file relative to backendPath. */
  file: string
  /** Stratum as classified by lib/url-conventions' canonicaliseRoute. */
  stratum: Stratum
}

// ─── Report ──────────────────────────────────────────────────────────────

export interface AuditReport {
  scope: 'devWire'
  applicationCode: string
  moduleCode: string
  backendPath: string
  webPath: string
  filesInspected: number
  findings: Finding[]
  counts: { errors: number; warnings: number; oks: number }
  byRule: Record<string, number>
  markdown: string
}

export interface AuditDevWireOutput {
  success: boolean
  command: 'audit-dev-wire'
  data: {
    mode: AuditDevWireMode
    rulesRun: string[]
    valid: boolean
  }
  report: AuditReport | null
  auditReport: {
    scope: 'devWire'
    applicationCode: string
    moduleCode: string
    findings: Array<Pick<Finding, 'dimension' | 'code' | 'severity' | 'label' | 'params' | 'solution' | 'fixSkill' | 'fixPhaseKey'>>
  } | null
  filesModified: string[]
  errors: string[]
  warnings: string[]
  nextSteps: string[]
}

export interface ArgsValidationResult {
  valid: boolean
  args: AuditDevWireArgs | null
  errors: string[]
}
