type PresentationPhase =
  | "inline"
  | "opening"
  | "viewer"
  | "closing";

type PresentationOwner = "feed" | "transport" | "viewer";

type PresentationState = {
  phase: PresentationPhase;
  owner: PresentationOwner;
  liveFrame: boolean;
  destinationValid: boolean;
};

type PresentationEvent =
  | { type: "OPEN"; sourceRect: DOMRect }
  | { type: "VIEWER_FRAME_PRESENTED" }
  | { type: "CLOSE"; destinationRect: DOMRect }
  | { type: "RETURN_TARGET_INVALIDATED" }
  | { type: "RETURN_SETTLED" };

export function transition(
  state: PresentationState,
  event: PresentationEvent,
): PresentationState {
  if (state.phase === "inline" && event.type === "OPEN") {
    return { ...state, phase: "opening", owner: "transport" };
  }

  if (
    state.phase === "opening" &&
    event.type === "VIEWER_FRAME_PRESENTED"
  ) {
    return {
      phase: "viewer",
      owner: "viewer",
      liveFrame: true,
      destinationValid: true,
    };
  }

  if (state.phase === "viewer" && event.type === "CLOSE") {
    return {
      ...state,
      phase: "closing",
      owner: "transport",
      destinationValid: true,
    };
  }

  if (
    state.phase === "closing" &&
    event.type === "RETURN_TARGET_INVALIDATED"
  ) {
    return { ...state, destinationValid: false };
  }

  if (
    state.phase === "closing" &&
    state.destinationValid &&
    event.type === "RETURN_SETTLED"
  ) {
    return {
      phase: "inline",
      owner: "feed",
      liveFrame: false,
      destinationValid: true,
    };
  }

  return state;
}
