import {
  type ActivityActor,
  type ActivityCategory,
  type ActivityEvent,
  type ActivitySeverity,
  type ActivitySkippedEntry,
} from "@overdeck/activity-contract";

export {
  ACTIVITY_SEVERITY_ORDER,
  ALL_ACTIVITY_CATEGORIES,
  type ActivityActor,
  type ActivityCategory,
  type ActivityCorrelation,
  type ActivityEvent,
  type ActivityEvidence,
  type ActivityLifecycle,
  type ActivityReadResponse,
  type ActivityResult,
  type ActivitySeries,
  type ActivitySeverity,
  type ActivitySkippedEntry,
  type ActivitySkipReason,
  type ActivitySourceCoverage,
  type ActivitySourceEntriesResponse,
  type ActivitySourceStatus,
  type SuppressedNotificationRow,
  type SuppressedNotifications,
} from "@overdeck/activity-contract";

export type ActivitySourceAuthority = "authoritative" | "derived";

export interface RawActivitySourceCoverage {
  id: string;
  label: string;
  category: ActivityCategory;
  path: string;
  authority?: ActivitySourceAuthority;
  storage?: string;
  retention?: string;
  queryBounds?: string;
  coverageFrom?: string;
  status: "ok" | "absent" | "error";
  records: number;
  totalRecords: number;
  earliest?: string;
  latest?: string;
  skipped: number;
  error?: string;
}

export interface ActivitySourceOptions {
  fromMs?: number;
  toMs?: number;
  /** Off by default: the logs list polls every source and never renders skip records. */
  collectSkipped?: boolean;
}

export interface ControllerSourceOptions extends ActivitySourceOptions {
  path?: string;
  readFileImpl?: (path: string) => string;
  existsSyncImpl?: (path: string) => boolean;
}

export interface LandqSourceOptions extends ActivitySourceOptions {
  repoRoots?: string[];
  readFileImpl?: (path: string) => string;
  existsSyncImpl?: (path: string) => boolean;
}

export interface ActionsSourceOptions extends ActivitySourceOptions {
  path?: string;
  readFileImpl?: (path: string) => string;
  existsSyncImpl?: (path: string) => boolean;
}

export interface AgentSessionsSourceOptions extends ActivitySourceOptions {
  root?: string;
  readdirSyncImpl?: (path: string) => string[];
  existsSyncImpl?: (path: string) => boolean;
  readFileImpl?: (path: string) => string;
}

export interface FleetHardenSourceOptions extends ActivitySourceOptions {
  path?: string;
  readFileImpl?: (path: string) => string;
  existsSyncImpl?: (path: string) => boolean;
}

export interface NotificationsSourceOptions extends ActivitySourceOptions {
  path?: string;
  readFileImpl?: (path: string) => string;
  existsSyncImpl?: (path: string) => boolean;
}

export interface NotifGateSourceOptions extends ActivitySourceOptions {
  path?: string;
  readFileImpl?: (path: string) => string;
  existsSyncImpl?: (path: string) => boolean;
}

export interface SuppressedOptions {
  path?: string;
  readFileImpl?: (path: string) => string;
  existsSyncImpl?: (path: string) => boolean;
}

export interface ReaperSourceOptions extends ActivitySourceOptions {
  path?: string;
  readFileImpl?: (path: string) => string;
  existsSyncImpl?: (path: string) => boolean;
}

export interface KubernetesSourceOptions extends ActivitySourceOptions {
  path?: string;
  readFileImpl?: (path: string) => string;
  existsSyncImpl?: (path: string) => boolean;
}

export interface ActivityReadOptions {
  from?: string;
  to?: string;
  limit?: number;
  categories?: ActivityCategory[];
  projects?: string[];
  runtimes?: string[];
  hosts?: string[];
  actors?: ActivityActor[];
  severityFloor?: ActivitySeverity;
  q?: string;
  sources?: {
    controller?: ControllerSourceOptions;
    landq?: LandqSourceOptions;
    actions?: ActionsSourceOptions;
    agentSessions?: AgentSessionsSourceOptions;
    fleetHarden?: FleetHardenSourceOptions;
    notifications?: NotificationsSourceOptions;
    notifGate?: NotifGateSourceOptions;
    reaper?: ReaperSourceOptions;
    kubernetes?: KubernetesSourceOptions;
  };
  workloads?: string[];
  builds?: string[];
}

export interface ActivitySourceResult {
  coverage: RawActivitySourceCoverage;
  events: ActivityEvent[];
  /** Empty unless the caller asked for `collectSkipped`; `coverage.skipped` stays exact either way. */
  skippedEntries: ActivitySkippedEntry[];
  skippedTruncated: boolean;
}

export interface ActivitySourceEntriesOptions {
  sourceId: string;
  from?: string;
  to?: string;
  q?: string;
  recordId?: string;
  severityFloor?: ActivitySeverity;
  offset?: number;
  limit?: number;
  sources?: ActivityReadOptions["sources"];
}

export type ActivitySeriesId = "activeAgents" | "logVolume" | "commits" | "bots" | "builds" | "incidents";
