/**
 * HTTP device gateway (ticket #77, lot F2) — the web sibling of
 * `TauriDeviceGateway`, behind the unchanged {@link DeviceGateway} port.
 *
 * Routes live outside the generic `/api/invoke` RPC, next to the pre-existing
 * `/api/pair` and `/api/logout`: the RPC endpoint is auth-gated, so the surface
 * that manages auth cannot ride on it (carnet #77).
 *
 * Paths are those B3 landed (`web-server/src/lib.rs`).
 */

import type { PairedDevice, PairingCode } from "@/domain";
import type { DeviceGateway } from "@/ports";
import type { HttpInvoker } from "./httpInvoker";

/** Backend shape of `GET /api/devices`: the list is wrapped, never bare. */
interface DeviceListResponse {
  devices: PairedDevice[];
}

export class HttpDeviceGateway implements DeviceGateway {
  constructor(private readonly http: HttpInvoker) {}

  async listDevices(): Promise<PairedDevice[]> {
    const body = await this.http.request<DeviceListResponse>("GET", "/api/devices");
    return body.devices;
  }

  createPairingCode(): Promise<PairingCode> {
    return this.http.request<PairingCode>("POST", "/api/pairing-code");
  }

  renameDevice(deviceId: string, name: string): Promise<void> {
    return this.http.request<void>(
      "POST",
      `/api/devices/${encodeURIComponent(deviceId)}/rename`,
      { name },
    );
  }

  revokeDevice(deviceId: string): Promise<void> {
    return this.http.request<void>(
      "POST",
      `/api/devices/${encodeURIComponent(deviceId)}/revoke`,
    );
  }

  revokeAllDevices(): Promise<void> {
    return this.http.request<void>("POST", "/api/devices/revoke-all");
  }
}
