import type { GateEntry, TaskResult } from '@mosaicstack/macp';

/** Stage dispatch mode. */
export type StageDispatch = 'exec' | 'yolo' | 'pi';

/** Stage type — determines agent selection and gate requirements. */
export type StageType = 'research' | 'review' | 'coding' | 'deploy';

/** Stage specification — defines a single pipeline stage. */
export interface StageSpec {
  number: string;
  title: string;
  dispatch: StageDispatch;
  type: StageType;
  gate: string;
  promptFile: string;
  qualityGates: (string | GateEntry)[];
}

/** Brief classification. */
export type BriefClass = 'strategic' | 'technical' | 'hotfix';

/** How the brief class was determined. */
export type ClassSource = 'cli' | 'frontmatter' | 'auto';

/** Per-stage status within a run manifest. */
export interface StageStatus {
  status: 'pending' | 'in_progress' | 'passed' | 'failed';
  startedAt?: string;
  completedAt?: string;
}

/** Run manifest — persisted to disk as manifest.json. */
export interface RunManifest {
  runId: string;
  brief: string;
  codebase: string;
  briefClass: BriefClass;
  classSource: ClassSource;
  forceBoard: boolean;
  createdAt: string;
  updatedAt: string;
  currentStage: string;
  status: 'in_progress' | 'completed' | 'failed' | 'interrupted' | 'rejected';
  stages: Record<string, StageStatus>;
}

/** Task status for the executor. */
export type ForgeTaskStatus =
  | 'pending'
  | 'running'
  | 'completed'
  | 'failed'
  | 'gated'
  | 'escalated';

/** Task submitted to a TaskExecutor. */
export interface ForgeTask {
  id: string;
  title: string;
  description: string;
  status: ForgeTaskStatus;
  type: StageType;
  dispatch: StageDispatch;
  briefPath: string;
  resultPath: string;
  timeoutSeconds: number;
  qualityGates: (string | GateEntry)[];
  worktree?: string;
  command?: string;
  dependsOn?: string[];
  dependsOnPolicy?: 'all' | 'any' | 'all_terminal';
  metadata: Record<string, unknown>;
}

/** Abstract task executor — decouples from packages/coord. */
export interface TaskExecutor {
  submitTask(task: ForgeTask): Promise<void>;
  waitForCompletion(taskId: string, timeoutMs: number): Promise<TaskResult>;
  getTaskStatus(taskId: string): Promise<ForgeTaskStatus>;
}

/** Board persona loaded from markdown. */
export interface BoardPersona {
  name: string;
  slug: string;
  description: string;
  path: string;
}

/** Board review result from a single persona. */
export interface PersonaReview {
  persona: string;
  verdict: 'approve' | 'reject' | 'conditional';
  confidence: number;
  concerns: string[];
  recommendations: string[];
  keyRisks: string[];
}

/** Board synthesis result merging all persona reviews. */
export interface BoardSynthesis extends PersonaReview {
  reviews: PersonaReview[];
}

/** Project-level Forge configuration (.forge/config.yaml). */
export interface ForgeConfig {
  board?: {
    additionalMembers?: string[];
    skipMembers?: string[];
  };
  specialists?: {
    alwaysInclude?: string[];
  };
}

/** Options for running a pipeline. */
export interface PipelineOptions {
  briefClass?: BriefClass;
  forceBoard?: boolean;
  codebase?: string;
  stages?: string[];
  skipTo?: string;
  dryRun?: boolean;
  executor: TaskExecutor;
}

/** Pipeline run result. */
export interface PipelineResult {
  runId: string;
  briefPath: string;
  projectRoot: string;
  runDir: string;
  taskIds: string[];
  stages: string[];
  manifest: RunManifest;
}
