import { z } from 'zod';
import type { PolicyVerdict, DbTarget } from '../lib/migration-policy.js';

export const ApplySpecSchema = z.object({
  cwd: z.string().min(1),
  /** Limit to one context; default = every detected context. */
  contextName: z.string().optional(),
  /** Down-migration: roll back to this migration ("0" = revert all). Omit = apply to latest. */
  targetMigration: z.string().optional(),
  /** Confirmation token required to proceed on a 🟡 (yellow) verdict. */
  confirm: z.boolean().optional().default(false),
  /** Explicit connection string — overrides reading appsettings (testing / non-standard layout). */
  connectionString: z.string().optional(),
  /** Override the startup project used by `dotnet ef`. */
  startupProject: z.string().optional(),
  /** Dry-run: classify + count pending, do NOT spawn `database update`. */
  dryRun: z.boolean().optional().default(false),
});
export type ApplySpec = z.infer<typeof ApplySpecSchema>;

export interface ApplyContextResult {
  contextName: string;
  assemblyName: string;
  pending: number;
  /** True when `database update` actually ran for this context. */
  applied: boolean;
  appliedMigrations: string[];
  output: string;
  success: boolean;
  error?: string;
}

export interface ApplyResult {
  success: boolean;
  cwd: string;
  branch: string;
  op: 'apply' | 'revert';
  dbTarget: DbTarget;
  dbHost: string | null;
  policy: PolicyVerdict;
  /** Set on a 🔴 verdict — autonomous refusal; a human decides. */
  blocked?: boolean;
  /** Set on a 🟡 verdict reached without `confirm:true`. */
  needsConfirmation?: boolean;
  contexts: ApplyContextResult[];
  warnings: string[];
  error?: string;
}
