/** JSON-only contracts for office screen surfaces. No browser or renderer types. */

export type MediaAudience = "public" | "authenticated" | "office-members" | "allowlist";
export type MediaSourcePrivacy = "public" | "private";
export type MediaSourceKind = "live-stream" | "recording";
export type MediaSurfaceStatus = "idle" | "presenting" | "reconnecting" | "stopped" | "revoked";

export interface MediaSurfaceAcl {
  audience: MediaAudience;
  viewerIds: string[];
  presenterIds: string[];
  moderatorIds: string[];
}

export interface MediaSurfaceSource {
  kind: MediaSourceKind;
  /** Opaque server-issued locator. Never expose it before authorization and opt-in. */
  locator: string;
  privacy: MediaSourcePrivacy;
  hasAudio: boolean;
  /** Deliberately literal invariants: a surface never asks a browser to autoplay. */
  autoplay: false;
  muted: true;
}

export interface MediaSurfaceState {
  status: MediaSurfaceStatus;
  presenterId: string | null;
  revision: number;
}

export interface MediaSurface {
  screenId: string;
  officeId: string;
  levelId: string;
  roomId: string | null;
  acl: MediaSurfaceAcl;
  source: MediaSurfaceSource | null;
  state: MediaSurfaceState;
}

export interface MediaViewerContext {
  /** Trusted server identity. `null` is the anonymous public viewer. */
  viewerId: string | null;
  /** Trusted memberships, not values supplied by the browser. */
  officeIds: string[];
  /** Viewing never starts merely because authorization succeeded. */
  optedIn: boolean;
}

export type MediaAuthorizationReason =
  | "ready"
  | "not_presenting"
  | "authentication_required"
  | "office_membership_required"
  | "not_allowlisted"
  | "opt_in_required";

/** Safe response shape. `source` is null unless both policy and opt-in passed. */
export interface MediaSurfaceView {
  screenId: string;
  officeId: string;
  levelId: string;
  roomId: string | null;
  status: MediaSurfaceStatus;
  source: MediaSurfaceSource | null;
  playback: { autoplay: false; muted: true };
}

export interface MediaAuthorizationDecision {
  authorized: boolean;
  optedIn: boolean;
  canView: boolean;
  reason: MediaAuthorizationReason;
  surface: MediaSurfaceView;
}

export type MediaSurfaceEvent =
  | { type: "present"; presenterId: string; source: MediaSurfaceSource }
  | { type: "stop"; presenterId: string }
  | { type: "revoke"; actorId: string }
  | { type: "disconnect"; presenterId: string }
  | { type: "reconnect"; presenterId: string; source?: MediaSurfaceSource };

