/**
 * types.ts — Zod input schema + internal interfaces for create-plan-development CLI.
 *
 * Parses cross-module FK dependencies from entité.md files and builds a
 * phased development plan via topological sort.
 */
import { z } from 'zod';

// ---------------------------------------------------------------------------
// Input schema (Zod)
// ---------------------------------------------------------------------------

export const PlanDevelopmentInputSchema = z.object({
  /** Absolute path to the .smartstack/ba/ directory. */
  baRoot: z.string().min(1),

  /** Application codes to include (UPPERCASE, e.g. ["CRM", "BILLING"]). */
  apps: z
    .array(z.string().min(1).regex(/^[A-Z][A-Z0-9_-]*$/, 'Must be UPPERCASE app code'))
    .min(1),

  /** Whether to read _audit/prd.md verdicts for readiness status. */
  includeReadiness: z.boolean().default(true),
});

export type PlanDevelopmentInput = z.infer<typeof PlanDevelopmentInputSchema>;

// ---------------------------------------------------------------------------
// Module key — canonical format matching entité.md FK descriptions
// ---------------------------------------------------------------------------

/** e.g. "CRM/CONTACTS" — matches `FK cross-module vers CRM/CONTACTS.Contact` */
export type ModuleKey = `${string}/${string}`;

export function moduleKey(appCode: string, moduleCode: string): ModuleKey {
  return `${appCode}/${moduleCode}` as ModuleKey;
}

export function parseModuleKey(key: ModuleKey): { appCode: string; moduleCode: string } {
  const [appCode, moduleCode] = key.split('/');
  return { appCode, moduleCode };
}

// ---------------------------------------------------------------------------
// Parsed data structures
// ---------------------------------------------------------------------------

export interface EntityRef {
  /** e.g. "ENT-001" */
  code: string;
  /** e.g. "Opportunity" */
  name: string;
  /** e.g. "agrégat racine", "lookup", "composant", "technical" */
  classification?: string;
}

export interface CrossModuleDep {
  /** Entity in the current module that holds the FK. */
  sourceEntity: string;
  /** Attribute name (e.g. "ContactId"). */
  sourceAttribute: string;
  /** Target application code. */
  targetApp: string;
  /** Target module code. */
  targetModule: string;
  /** Target entity name (e.g. "Contact"). */
  targetEntity: string;
}

export interface CoreRef {
  /** Entity in the current module that holds the FK. */
  sourceEntity: string;
  /** Attribute name (e.g. "UserId"). */
  sourceAttribute: string;
  /** Core target (e.g. "auth_Users", "nav_Applications"). */
  coreTarget: string;
}

export interface ReadinessInfo {
  verdict: 'GO' | 'NO-GO' | 'UNKNOWN';
  score?: number;
  errCount?: number;
  warnCount?: number;
}

export interface ModuleInfo {
  appCode: string;
  moduleCode: string;
  key: ModuleKey;
  entities: EntityRef[];
  crossModuleDeps: CrossModuleDep[];
  coreRefs: CoreRef[];
  hasEntiteMd: boolean;
  readiness?: ReadinessInfo;
}

// ---------------------------------------------------------------------------
// Graph structures
// ---------------------------------------------------------------------------

export interface DependencyEdge {
  from: ModuleKey;
  to: ModuleKey;
  fks: CrossModuleDep[];
}

// ---------------------------------------------------------------------------
// Plan output
// ---------------------------------------------------------------------------

export interface WaveModule {
  appCode: string;
  moduleCode: string;
  key: ModuleKey;
  entityCount: number;
  dependsOn: ModuleKey[];
  readiness?: ReadinessInfo;
  isExternal: boolean;
  /** Which modules reference this external as a dependency. */
  referencedBy?: ModuleKey[];
  warnings: string[];
}

export interface Wave {
  /** 0 = external prerequisites, 1+ = development waves. */
  level: number;
  modules: WaveModule[];
}

export interface DevelopmentPlan {
  generatedAt: string;
  apps: string[];
  totalModules: number;
  totalCrossModuleDeps: number;
  waves: Wave[];
  cycles: ModuleKey[][];
  warnings: string[];
}

// ---------------------------------------------------------------------------
// Validation
// ---------------------------------------------------------------------------

export interface ValidationResult {
  valid: boolean;
  spec?: PlanDevelopmentInput;
  errors: string[];
  warnings: string[];
  /** Discovered modules per app (used by parse step). */
  discoveredModules?: Map<string, string[]>;
}

// ---------------------------------------------------------------------------
// File generation
// ---------------------------------------------------------------------------

export interface GeneratedFile {
  path: string;
  content: string;
}
