/**
 * SDK glue. The {@link createShadeBridgeFromShade} helper turns any Shade-
 * shaped object into a {@link ShadeBridge} suitable for
 * `WebRtcSignalingChannel`. Kept in its own file so the package can be
 * consumed standalone (e.g. by tests with a memory bridge) without
 * pulling in the full SDK type tree.
 */

import type { ShadeBridge } from './signaling.js';

/**
 * Minimal shape of `Shade` we depend on. The real `@shade/sdk` `Shade`
 * class satisfies this structurally; declaring it locally avoids a
 * circular dependency on `@shade/sdk` in this package's `package.json`.
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface ShadeLike {
  readonly myAddress: string;
  // The real SDK returns a `ShadeEnvelope`; we accept anything because the
  // bridge just hands it back to `deliverControlEnvelope`.
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  send(address: string, plaintext: string): Promise<any>;
  onMessage(handler: (from: string, plaintext: string) => void | Promise<void>): () => void;
  /**
   * Optional. When present (the real SDK provides it), the bridge calls
   * `deliverControlEnvelope` after `send()` so the encrypted envelope
   * actually reaches the peer over HTTP. When absent (memory tests or
   * custom transports), `send()` alone is enough.
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  deliverControlEnvelope?: (peer: string, envelope: any) => Promise<void>;
}

/**
 * Adapt a `Shade`-shaped instance to the {@link ShadeBridge} interface used
 * by `WebRtcSignalingChannel`. Each `bridge.send` calls
 * `shade.send(plaintext)` to ratchet-encrypt the signaling JSON, then —
 * when available — `shade.deliverControlEnvelope(...)` to actually ship the
 * envelope to the peer.
 */
export function createShadeBridgeFromShade(shade: ShadeLike): ShadeBridge {
  return {
    myAddress: shade.myAddress,
    async send(peerAddress: string, plaintext: string): Promise<void> {
      const envelope = await shade.send(peerAddress, plaintext);
      if (shade.deliverControlEnvelope !== undefined) {
        await shade.deliverControlEnvelope(peerAddress, envelope);
      }
    },
    onMessage(handler) {
      return shade.onMessage(handler);
    },
  };
}
