export type HistoryRepairPolicy =
  | 'StartRecent'
  | 'Bridge'
  | { BridgeShortGaps: { threshold_ms: number } };

export interface HistoryRepairBudget {
  max_pages: number;
  max_events: number;
  max_duration_ms: number;
}

export interface HistoryRepairFailure {
  kind: string;
  message: string;
  server?: { status: number; errcode: string; message: string } | null;
  [key: string]: unknown;
}

export interface HistoryRepairReport {
  room_id: string;
  requested_policy: HistoryRepairPolicy;
  strategy: 'Recent' | 'Overlap' | 'Bridge';
  coverage_duration_ms: number | null;
  threshold_evaluated: boolean;
  pages: number;
  events: number;
  phase: 'FetchingRecent' | 'Bridging' | 'Ready' | 'Paused';
  continuity: 'Unresolved' | 'Verified' | 'AccessibleStart';
  recent_available: boolean;
  stop: 'Cancelled' | 'Budget' | 'HistoryUnavailable' | 'NoAnchor' | 'CursorStalled' | null;
  failure: HistoryRepairFailure | null;
}

export const DEFAULT_HISTORY_REPAIR_BUDGET: HistoryRepairBudget = {
  max_pages: 10,
  max_events: 1000,
  max_duration_ms: 15000
};

function record(value: unknown): Record<string, unknown> | null {
  return typeof value === 'object' && value !== null && !Array.isArray(value)
    ? (value as Record<string, unknown>)
    : null;
}

function safeNonnegativeInteger(value: unknown): value is number {
  return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
}

export function parseHistoryRepairPolicy(value: unknown): HistoryRepairPolicy | null {
  if (value === 'StartRecent' || value === 'Bridge') return value;
  const outer = record(value);
  const details = outer && record(outer['BridgeShortGaps']);
  if (!outer || Object.keys(outer).length !== 1 || !details || Object.keys(details).length !== 1 || !safeNonnegativeInteger(details['threshold_ms'])) return null;
  return { BridgeShortGaps: { threshold_ms: details['threshold_ms'] } };
}

function isOneOf<T extends string>(value: unknown, values: readonly T[]): value is T {
  return typeof value === 'string' && (values as readonly string[]).includes(value);
}

export function parseHistoryRepairReport(value: unknown): HistoryRepairReport | null {
  const data = record(value);
  if (!data) return null;
  const policy = parseHistoryRepairPolicy(data['requested_policy']);
  const failure = data['failure'];
  const failureData = failure === null ? null : record(failure);
  if (
    typeof data['room_id'] !== 'string' || !policy ||
    !isOneOf(data['strategy'], ['Recent', 'Overlap', 'Bridge']) ||
    !(data['coverage_duration_ms'] === null || safeNonnegativeInteger(data['coverage_duration_ms'])) ||
    typeof data['threshold_evaluated'] !== 'boolean' ||
    !safeNonnegativeInteger(data['pages']) || !safeNonnegativeInteger(data['events']) ||
    !isOneOf(data['phase'], ['FetchingRecent', 'Bridging', 'Ready', 'Paused']) ||
    !isOneOf(data['continuity'], ['Unresolved', 'Verified', 'AccessibleStart']) ||
    typeof data['recent_available'] !== 'boolean' ||
    !(data['stop'] === null || isOneOf(data['stop'], ['Cancelled', 'Budget', 'HistoryUnavailable', 'NoAnchor', 'CursorStalled'])) ||
    !(failure === null || (failureData && typeof failureData['kind'] === 'string' && typeof failureData['message'] === 'string'))
  ) return null;
  return {
    room_id: data['room_id'],
    requested_policy: policy,
    strategy: data['strategy'],
    coverage_duration_ms: data['coverage_duration_ms'],
    threshold_evaluated: data['threshold_evaluated'],
    pages: data['pages'],
    events: data['events'],
    phase: data['phase'],
    continuity: data['continuity'],
    recent_available: data['recent_available'],
    stop: data['stop'],
    failure: failureData as HistoryRepairFailure | null
  };
}
