/**
 * T2 — the frozen CLIENT-contract surface. Re-exports the `relay-contracts` §4.2/§4.3 shapes
 * VERBATIM (never redefines them) and adds ONLY response envelopes needed to parse HTTP JSON.
 *
 * INV3: there is NO `account_id`/`tenant_id` REQUEST field anywhere here — identity is always the
 * cookie/passkey session the browser already holds; the server derives the account.
 *
 * Wire note: over JSON, `HostRecord.agentPubkey` arrives base64url-encoded (a Uint8Array cannot
 * ride JSON). The wire schema decodes it back to `Uint8Array` so callers receive a genuine
 * `HostRecord` — validate-at-boundary (coding-style.md "Input Validation").
 */
import { z } from 'zod'
import {
  HostStatusSchema,
  decodeBase64UrlBytes,
  type HostRecord,
  type HostStatus,
  type CapabilityRight,
} from 'relay-contracts'

// Re-export the frozen types verbatim so P6 modules import them from one place (the src/types.ts
// discipline: a new shared field is changed in relay-contracts, never redeclared locally).
export type { HostRecord, HostStatus, CapabilityRight }
export { HostStatusSchema }

/** Wire form of a HostRecord: `agentPubkey` is base64url text, decoded to bytes on parse. */
export const HostRecordWireSchema = z
  .object({
    hostId: z.string().uuid(),
    accountId: z.string().uuid(),
    subdomain: z.string().min(1),
    agentPubkey: z.string().min(1),
    enrollFpr: z.string().min(1),
    status: HostStatusSchema,
    lastSeen: z.string().min(1),
    createdAt: z.string().min(1),
    revokedAt: z.string().min(1).nullable(),
  })
  .strict()
  .transform(
    (w): HostRecord => ({
      hostId: w.hostId,
      accountId: w.accountId,
      subdomain: w.subdomain,
      // Copy into a fresh ArrayBuffer-backed Uint8Array so the type matches HostRecord exactly.
      agentPubkey: new Uint8Array(decodeBase64UrlBytes(w.agentPubkey)),
      enrollFpr: w.enrollFpr,
      status: w.status,
      lastSeen: w.lastSeen,
      createdAt: w.createdAt,
      revokedAt: w.revokedAt,
    }),
  )

/** `GET /api/hosts` → array of HostRecord. */
export const HostListWireSchema = z.array(HostRecordWireSchema).readonly()

/** `GET /api/hosts/:id/status` → the host's current status. */
export const HostStatusResponseSchema = z.object({ status: HostStatusSchema }).strict()

/** `POST /api/pairing-codes` → single-use short-TTL code + its expiry (§4.5 ISSUE). */
export const PairingCodeResponseSchema = z
  .object({
    code: z.string().min(1),
    expiresAt: z.string().min(1),
  })
  .strict()
  .readonly()
export type PairingCodeResponse = z.infer<typeof PairingCodeResponseSchema>

/** `POST /api/hosts/:id/capability-token` → opaque raw §4.3 token (v0.9+; never decoded to trust). */
export const CapabilityTokenResponseSchema = z.object({ token: z.string().min(1) }).strict()
