// Generated by bynkc — do not edit by hand.
// context shop.sales

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 interface Order {
  readonly id: string;
  readonly customer: string;
}

export const Order = {
};

export interface Line {
  readonly orderId: string;
  readonly qty: number;
}

export const Line = {
};

export interface Joined {
  readonly customer: string;
  readonly qty: number;
}

export const Joined = {
};

export interface Tot {
  readonly orderId: string;
  readonly total: number;
}

export const Tot = {
};

export interface SalesState {
  readonly orders: Record<string, Order>;
  readonly lines: Record<string, Line>;
}

const __SalesRegistry = new StateRegistry();
function __zeroOfSalesState(): SalesState { return { orders: {}, lines: {} }; }

function __rehydrateSalesState(s: SalesState): void {
  for (const __v of Object.values(s.orders)) { const __r = deserialise_Order((__v as unknown as JsonValue), "orders"); if (__r.tag === "Err") throw rehydrationViolation("Sales", __r.error); }
  for (const __k of Object.keys(s.orders)) { const __r = ((__v) => typeof __v === "string" ? Ok(__v) : Err({ kind: "StructuralMismatch", path: "orders", expected: "string", actual: typeof __v } as BoundaryError))((__k as unknown as JsonValue)); if (__r.tag === "Err") throw rehydrationViolation("Sales", __r.error); }
  for (const __v of Object.values(s.lines)) { const __r = deserialise_Line((__v as unknown as JsonValue), "lines"); if (__r.tag === "Err") throw rehydrationViolation("Sales", __r.error); }
  for (const __k of Object.keys(s.lines)) { const __r = ((__v) => typeof __v === "string" ? Ok(__v) : Err({ kind: "StructuralMismatch", path: "lines", expected: "string", actual: typeof __v } as BoundaryError))((__k as unknown as JsonValue)); if (__r.tag === "Err") throw rehydrationViolation("Sales", __r.error); }
}

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

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

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

  async report(deps: {}): Promise<readonly Joined[]> {
    const __state = await this.loadState();
    return ((() => { const __h: Record<string, any[]> = {}; for (const __u of ((() => Object.values(__state.orders)))()) { const __k = String(((o) => o.id)(__u)); (__h[__k] = __h[__k] ?? []).push(__u); } return Object.values(__state.lines).flatMap((__t) => { const __m = __h[String(((l) => l.orderId)(__t))] ?? []; return __m.map((__u) => ((l, o) => ({ customer: o.customer, qty: l.qty }))(__t, __u)); }); }))();
  }

  async withMissing(deps: {}): Promise<number> {
    const __state = await this.loadState();
    return ((() => { const __h: Record<string, any[]> = {}; for (const __u of ((() => Object.values(__state.orders)))()) { const __k = String(((o) => o.id)(__u)); (__h[__k] = __h[__k] ?? []).push(__u); } return Object.values(__state.lines).flatMap((__t) => { const __m = __h[String(((l) => l.orderId)(__t))] ?? []; return __m.length > 0 ? __m.map((__u) => ((l, mo) => l.qty)(__t, Some(__u))) : [((l, mo) => l.qty)(__t, None)]; }); }))().length;
  }

  async totals(deps: {}): Promise<readonly Tot[]> {
    const __state = await this.loadState();
    return ((() => { const __h: Record<string, any[]> = {}; const __order: string[] = []; for (const __t of Object.values(__state.lines)) { const __k = String(((l) => l.orderId)(__t)); if (!(__k in __h)) { __h[__k] = []; __order.push(__k); } __h[__k].push(__t); } return __order.map((__k) => { const __rows = __h[__k]; return ((oid, rows) => ({ orderId: oid, total: (rows).reduce((__s: number, __x: Line) => __s + ((r) => r.qty)(__x), 0) }))(((l) => l.orderId)(__rows[0]), __rows); }); }))();
  }

}

export function __makeSales(key: string, env?: { SALES?: DurableObjectNamespace }): Sales {
  return makeAgent(__SalesRegistry, env?.SALES, key, (state) => new Sales(state));
}

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

export function serialise_Line(value: Line): JsonValue {
  return {
    orderId: value.orderId as JsonValue,
    qty: value.qty as JsonValue,
  };
}

export function deserialise_Line(json: JsonValue, path: string = "$"): Result<Line, BoundaryError> {
  if (typeof json !== "object" || json === null || Array.isArray(json)) {
    return Err({ kind: "StructuralMismatch", path, expected: "object", actual: typeof json });
  }
  const obj = json as { [k: string]: JsonValue };
  if (typeof obj["orderId"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.orderId`, expected: "string", actual: typeof obj["orderId"] });
  }
  const __orderId = obj["orderId"];
  if (typeof obj["qty"] !== "number") {
    return Err({ kind: "StructuralMismatch", path: `${path}.qty`, expected: "number", actual: typeof obj["qty"] });
  }
  if (!Number.isInteger(obj["qty"])) {
    return Err({ kind: "StructuralMismatch", path: `${path}.qty`, expected: "integer", actual: String(obj["qty"]) });
  }
  const __qty = obj["qty"];
  return Ok({ orderId: __orderId, qty: __qty } as Line);
}

export function serialise_Order(value: Order): JsonValue {
  return {
    id: value.id as JsonValue,
    customer: value.customer as JsonValue,
  };
}

export function deserialise_Order(json: JsonValue, path: string = "$"): Result<Order, BoundaryError> {
  if (typeof json !== "object" || json === null || Array.isArray(json)) {
    return Err({ kind: "StructuralMismatch", path, expected: "object", actual: typeof json });
  }
  const obj = json as { [k: string]: JsonValue };
  if (typeof obj["id"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.id`, expected: "string", actual: typeof obj["id"] });
  }
  const __id = obj["id"];
  if (typeof obj["customer"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.customer`, expected: "string", actual: typeof obj["customer"] });
  }
  const __customer = obj["customer"];
  return Ok({ id: __id, customer: __customer } as Order);
}


