export type TaskStatus = 'not-started' | 'in-progress' | 'done' | 'blocked' | 'cancelled';

export type MissionStatus = 'active' | 'paused' | 'completed' | 'inactive';

export type MissionRuntime = 'claude' | 'codex' | 'unknown';

export interface MissionMilestone {
  id: string;
  name: string;
  status: 'pending' | 'in-progress' | 'completed' | 'blocked';
  branch?: string;
  issueRef?: string;
  startedAt?: string;
  completedAt?: string;
}

export interface MissionSession {
  sessionId: string;
  runtime: MissionRuntime;
  pid?: number;
  startedAt: string;
  endedAt?: string;
  endedReason?: 'completed' | 'paused' | 'crashed' | 'killed' | 'unknown';
  milestoneId?: string;
  lastTaskId?: string;
  durationSeconds?: number;
}

export interface Mission {
  schemaVersion: 1;
  id: string;
  name: string;
  description?: string;
  projectPath: string;
  createdAt: string;
  status: MissionStatus;
  tasksFile: string;
  manifestFile: string;
  scratchpadFile: string;
  orchestratorDir: string;
  taskPrefix?: string;
  qualityGates?: string;
  milestoneVersion?: string;
  milestones: MissionMilestone[];
  sessions: MissionSession[];
}

export interface MissionTask {
  id: string;
  title: string;
  status: TaskStatus;
  assignee?: string;
  dependencies: string[];
  milestone?: string;
  pr?: string;
  notes?: string;
  rawStatus?: string;
  line?: number;
}

export interface TaskRun {
  missionId: string;
  taskId: string;
  sessionId: string;
  runtime: 'claude' | 'codex';
  launchCommand: string[];
  startedAt: string;
  pid?: number;
  lockFile: string;
}

export interface MissionStatusSummary {
  mission: Pick<Mission, 'id' | 'name' | 'status' | 'projectPath'>;
  milestones: {
    total: number;
    completed: number;
    current?: MissionMilestone;
  };
  tasks: {
    total: number;
    done: number;
    inProgress: number;
    pending: number;
    blocked: number;
    cancelled: number;
  };
  nextTaskId?: string;
  activeSession?: MissionSession;
}

export interface TaskDetail {
  missionId: string;
  task: MissionTask;
  isNextTask: boolean;
  activeSession?: MissionSession;
}

export interface CreateMissionOptions {
  name: string;
  projectPath?: string;
  prefix?: string;
  milestones?: string[];
  qualityGates?: string;
  version?: string;
  description?: string;
  force?: boolean;
}

export interface RunTaskOptions {
  runtime?: 'claude' | 'codex';
  mode?: 'interactive' | 'print-only';
  milestoneId?: string;
  launchStrategy?: 'subprocess' | 'spawn-adapter';
  env?: Record<string, string>;
  command?: string[];
}

export interface NextTaskCapsule {
  generatedAt: string;
  runtime: 'claude' | 'codex';
  missionId: string;
  missionName: string;
  projectPath: string;
  qualityGates?: string;
  currentMilestone: {
    id?: string;
    name?: string;
  };
  nextTask: string;
  progress: {
    tasksDone: number;
    tasksTotal: number;
    pct: number;
  };
  currentBranch?: string;
}

const LEGACY_TASK_STATUS: Readonly<Record<string, TaskStatus>> = {
  'not-started': 'not-started',
  pending: 'not-started',
  todo: 'not-started',
  'in-progress': 'in-progress',
  in_progress: 'in-progress',
  done: 'done',
  completed: 'done',
  blocked: 'blocked',
  failed: 'blocked',
  cancelled: 'cancelled',
};

export function normalizeTaskStatus(input: string): {
  status: TaskStatus;
  rawStatus?: string;
} {
  const raw = input.trim().toLowerCase();
  if (raw.length === 0) {
    return { status: 'not-started' };
  }

  const normalized = LEGACY_TASK_STATUS[raw];
  if (normalized === undefined) {
    return { status: 'not-started', rawStatus: raw };
  }

  if (raw !== normalized) {
    return { status: normalized, rawStatus: raw };
  }

  return { status: normalized };
}

export function isMissionStatus(value: string): value is MissionStatus {
  return value === 'active' || value === 'paused' || value === 'completed' || value === 'inactive';
}

export function isTaskStatus(value: string): value is TaskStatus {
  return (
    value === 'not-started' ||
    value === 'in-progress' ||
    value === 'done' ||
    value === 'blocked' ||
    value === 'cancelled'
  );
}
