import type { HarnessError } from './errors.js';
import type { HarnessSelection, HarnessSessionState } from './contracts.js';

export const HARNESS_CAPABILITIES = [
  'modelSelection',
  'thinkingLevels',
  'images',
  'toolEvents',
  'extensionUi',
  'steering',
  'followUp',
  'compaction',
  'persistentResume',
] as const satisfies readonly string[];

export type HarnessCapability = (typeof HARNESS_CAPABILITIES)[number];

/** Durable lifecycle states; later persistence enforces one terminal response per request. */
export type HarnessInteractionState = 'pending' | 'responded' | 'cancelled' | 'expired';
export type HarnessInteractionType = 'confirm' | 'select' | 'input' | 'editor';

export interface HarnessUsage {
  readonly inputTokens: number;
  readonly outputTokens: number;
  readonly totalTokens: number;
}

export type HarnessTurnOutcome =
  | 'settled'
  | 'failed'
  | 'aborted'
  | 'interrupted'
  | 'outcome_unknown';

export interface HarnessSessionStartedEvent {
  readonly type: 'session.started';
  readonly state: HarnessSessionState;
}

export interface HarnessSessionStateEvent {
  readonly type: 'session.state';
  readonly state: HarnessSessionState;
}

export interface HarnessSessionIdentityChangedEvent {
  readonly type: 'session.identity_changed';
  readonly identityGeneration: number;
  readonly label: string;
}

export interface HarnessTurnStartedEvent {
  readonly type: 'turn.started';
}

export interface HarnessTextDeltaEvent {
  readonly type: 'text.delta';
  readonly text: string;
}

export interface HarnessThinkingDeltaEvent {
  readonly type: 'thinking.delta';
  readonly text: string;
}

export interface HarnessToolStartedEvent {
  readonly type: 'tool.started';
  readonly toolCallId: string;
  readonly toolName: string;
}

export interface HarnessToolUpdatedEvent {
  readonly type: 'tool.updated';
  readonly toolCallId: string;
  readonly toolName: string;
  readonly message: string;
}

export interface HarnessToolFinishedEvent {
  readonly type: 'tool.finished';
  readonly toolCallId: string;
  readonly toolName: string;
  readonly isError: boolean;
}

export interface HarnessInteractionRequiredEvent {
  readonly type: 'interaction.required';
  readonly requestId: string;
  readonly interactionType: HarnessInteractionType;
  readonly state: HarnessInteractionState;
  readonly prompt: string;
  readonly options?: readonly string[];
}

export interface HarnessUsageUpdatedEvent {
  readonly type: 'usage.updated';
  readonly usage: HarnessUsage;
}

export interface HarnessTurnCompletedEvent {
  readonly type: 'turn.completed';
  readonly outcome: HarnessTurnOutcome;
}

export interface HarnessErrorEvent {
  readonly type: 'error';
  readonly error: HarnessError;
}

export type HarnessEvent =
  | HarnessSessionStartedEvent
  | HarnessSessionStateEvent
  | HarnessSessionIdentityChangedEvent
  | HarnessTurnStartedEvent
  | HarnessTextDeltaEvent
  | HarnessThinkingDeltaEvent
  | HarnessToolStartedEvent
  | HarnessToolUpdatedEvent
  | HarnessToolFinishedEvent
  | HarnessInteractionRequiredEvent
  | HarnessUsageUpdatedEvent
  | HarnessTurnCompletedEvent
  | HarnessErrorEvent;

/** Persisted normalized event plus Gateway-owned ordering and native reconciliation metadata. */
export interface HarnessEventEnvelope {
  readonly conversationId: string;
  readonly nativeSessionId: string;
  readonly turnId?: string;
  readonly correlationId: string;
  /** Monotonic Gateway journal sequence within the conversation. */
  readonly sequence: number;
  /** Native session-entry cursor when the harness provides one. */
  readonly nativeEntryCursor?: string;
  readonly occurredAt: string;
  readonly harnessId: string;
  /** Exact effective selected provider/model tuple; no alternate success selection is exposed. */
  readonly selection: HarnessSelection;
  readonly event: HarnessEvent;
}
