// Generated by bynkc — do not edit by hand.
// context demo.agt

import { Ok, Err, Some, None, type Result, type Option, type ValidationError, type DurableObjectState, type DurableObjectNamespace, StateRegistry, makeAgent, rehydrationViolation, type JsonValue, type BoundaryError } from "../runtime.js";

export type Id = number & { readonly __brand: "demo.agt.Id" };

export const Id = {
  of(value: number): Result<Id, ValidationError> {
    if (!Number.isInteger(value)) {
      return Err({ field: "Id", message: "must be an integer", value });
    }
    if (!(value >= 0)) {
      return Err({ field: "Id", message: "must be non-negative", value });
    }
    return Ok(value as Id);
  },
  unsafe(value: number): Id {
    return value as Id;
  },
};

export interface WalletState {
  readonly balance: number;
  readonly pending: number;
}

const __WalletRegistry = new StateRegistry();
function __zeroOfWalletState(): WalletState { return { balance: 0, pending: 0 }; }

function __rehydrateWalletState(s: WalletState): void {
  { const __r = ((__v) => typeof __v === "number" && Number.isInteger(__v) ? Ok(__v) : Err({ kind: "StructuralMismatch", path: "balance", expected: "number", actual: typeof __v } as BoundaryError))((s.balance as unknown as JsonValue)); if (__r.tag === "Err") throw rehydrationViolation("Wallet", __r.error); }
  { const __r = ((__v) => typeof __v === "number" && Number.isInteger(__v) ? Ok(__v) : Err({ kind: "StructuralMismatch", path: "pending", expected: "number", actual: typeof __v } as BoundaryError))((s.pending as unknown as JsonValue)); if (__r.tag === "Err") throw rehydrationViolation("Wallet", __r.error); }
}

export class Wallet {
  state: DurableObjectState;
  constructor(state: DurableObjectState) {
    this.state = state;
  }

  private async loadState(): Promise<WalletState> {
    const stored = await this.state.storage.get<WalletState>("state");
    if (stored === undefined) return __zeroOfWalletState();
    const __merged = { ...__zeroOfWalletState(), ...stored };
    __rehydrateWalletState(__merged);
    return __merged;
  }

  private async commitState(s: WalletState): Promise<void> {
    await this.state.storage.put("state", s);
  }

  async topup(amount: number, deps: {}): Promise<number> {
    const __state = { ...(await this.loadState()) };
    const __result = await (async () => {
      const cur = __state.balance;
      __state.balance = cur + amount;
      return cur + amount;
    })();
    await this.commitState(__state);
    return __result;
  }

}

export function __makeWallet(key: Id, env?: { WALLET?: DurableObjectNamespace }): Wallet {
  return makeAgent(__WalletRegistry, env?.WALLET, key, (state) => new Wallet(state));
}

export function __resetAgents(): void {
  __WalletRegistry.reset();
}

