// Generated by bynkc — do not edit by hand.
// context orders

import { Ok, Err, Some, None, type Result, type Option, type ValidationError, HttpResult, type JsonValue, type BoundaryError, type ServiceBinding, callService, boundaryError } from "../../runtime.js";

export type OrderError =
    { readonly tag: "EmptyCart" }
  | { readonly tag: "OutOfStock" }
  | { readonly tag: "PaymentDeclined" };

export const OrderError = {
  EmptyCart: { tag: "EmptyCart" } as OrderError,
  OutOfStock: { tag: "OutOfStock" } as OrderError,
  PaymentDeclined: { tag: "PaymentDeclined" } as OrderError,
};

export interface CreateOrder {
  readonly itemCount: number;
}

export const CreateOrder = {
};

export interface OrderView {
  readonly id: string;
  readonly status: string;
}

export const OrderView = {
};

export function placeOrder(req: CreateOrder): Result<OrderView, OrderError> {
  return (req.itemCount === 0 ? Err(OrderError.EmptyCart) : Ok({ id: "id-1", status: "placed" }));
}

export const api = {
  async http_POST_orders(body: CreateOrder, deps: {}): Promise<HttpResult<OrderView>> {
    const result = placeOrder(body);
    switch (result.tag) {
      case "Ok": {
        const o = result.value;
        return HttpResult.Created(o);
      }
      case "Err": {
        const error = result.error;
        return ((__d) => {
    switch (__d.tag) {
      case "EmptyCart": {
        return HttpResult.BadRequest("cart is empty");
      }
      case "OutOfStock": {
        return HttpResult.Conflict("item out of stock");
      }
      case "PaymentDeclined": {
        return HttpResult.UnprocessableEntity("payment declined");
      }
    }
    throw new Error("non-exhaustive match");
  })(error);
      }
    }
    throw new Error("non-exhaustive match");
  },
};

export function serialise_CreateOrder(value: CreateOrder): JsonValue {
  return {
    itemCount: value.itemCount as JsonValue,
  };
}

export function deserialise_CreateOrder(json: JsonValue, path: string = "$"): Result<CreateOrder, 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["itemCount"] !== "number") {
    return Err({ kind: "StructuralMismatch", path: `${path}.itemCount`, expected: "number", actual: typeof obj["itemCount"] });
  }
  if (!Number.isInteger(obj["itemCount"])) {
    return Err({ kind: "StructuralMismatch", path: `${path}.itemCount`, expected: "integer", actual: String(obj["itemCount"]) });
  }
  const __itemCount = obj["itemCount"];
  return Ok({ itemCount: __itemCount } as CreateOrder);
}

export function serialise_OrderView(value: OrderView): JsonValue {
  return {
    id: value.id as JsonValue,
    status: value.status as JsonValue,
  };
}

export function deserialise_OrderView(json: JsonValue, path: string = "$"): Result<OrderView, 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["status"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.status`, expected: "string", actual: typeof obj["status"] });
  }
  const __status = obj["status"];
  return Ok({ id: __id, status: __status } as OrderView);
}


