/**
 * types.ts — Zod input schema + internal interfaces for create-ba-order CLI.
 *
 * Receives the user-validated module dependency graph (inferred conversationally
 * by the SKILL.md) and produces a topologically sorted BA creation order.
 */
import { z } from 'zod';

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

const ModuleDepSchema = z.object({
  /** UPPERCASE application code. */
  appCode: z.string().min(1).regex(/^[A-Z][A-Z0-9_-]*$/),
  /** UPPERCASE module code. */
  moduleCode: z.string().min(1).regex(/^[A-Z][A-Z0-9_-]*$/),
  /** Modules this one depends on (ModuleKey format: "APP/MODULE"). */
  dependsOn: z.array(z.string().regex(/^[A-Z][A-Z0-9_-]*\/[A-Z][A-Z0-9_-]*$/)),
});

export const BaOrderInputSchema = z.object({
  /** Absolute path to the .smartstack/ba/ directory. */
  baRoot: z.string().min(1),
  /** Application codes in scope (UPPERCASE). */
  apps: z.array(z.string().min(1).regex(/^[A-Z][A-Z0-9_-]*$/)).min(1),
  /** Module dependency declarations, validated by the user. */
  modules: z.array(ModuleDepSchema).min(1),
});

export type BaOrderInput = z.infer<typeof BaOrderInputSchema>;

// ---------------------------------------------------------------------------
// Module key — canonical format: "APP/MODULE"
// ---------------------------------------------------------------------------

export type ModuleKey = `${string}/${string}`;

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

// ---------------------------------------------------------------------------
// Internal structures
// ---------------------------------------------------------------------------

export interface ModuleDep {
  appCode: string;
  moduleCode: string;
  key: ModuleKey;
  dependsOn: ModuleKey[];
  context?: string;
}

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

export interface BaWaveModule {
  appCode: string;
  moduleCode: string;
  key: ModuleKey;
  dependsOn: ModuleKey[];
  isExternal: boolean;
  /** Which modules reference this external as a dependency (Wave 0 only). */
  referencedBy?: ModuleKey[];
  warnings: string[];
}

export interface BaWave {
  /** 0 = external prerequisites, 1+ = BA waves. */
  level: number;
  modules: BaWaveModule[];
}

export interface BaOrderPlan {
  generatedAt: string;
  apps: string[];
  totalModules: number;
  totalDeps: number;
  waves: BaWave[];
  cycles: ModuleKey[][];
  warnings: string[];
  /** Distinguishes from the FK-based dev-plan ('entite'). */
  source: 'context';
}

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

export interface ValidationResult {
  valid: boolean;
  spec?: BaOrderInput;
  errors: string[];
  warnings: string[];
}

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

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