// Generated by smithplates HTTP codegen. Do not edit.

import { dumpApiModel } from "generated/example/warehouseApi/modelValidation";
import { parseClientResponse } from "generated/example/warehouseApi/client/clientResponse";
import { OPERATION_HTTP_BINDINGS } from "generated/example/warehouseApi/client/operationBindings";
import type { Conflict } from "generated/example/conflict";
import type { ItemDetails } from "generated/example/itemDetails";
import type { ServiceUnavailable } from "generated/example/serviceUnavailable";
import type { ShelfItemOutput } from "generated/example/shelfItemOutput";
import type { ShelfSkuOutput } from "generated/example/shelfSkuOutput";

function encodeRfc3986(value: string): string {
  return encodeURIComponent(value).replace(
    /[!'()*]/g,
    (character) => "%" + character.charCodeAt(0).toString(16).toUpperCase(),
  );
}

export class WarehouseApiClient {
  private readonly baseUrl: string;
  private readonly fetchFn: typeof fetch;

  constructor(baseUrl: string, fetchFn: typeof fetch = fetch) {
    this.baseUrl = baseUrl.replace(/\/+$/, "");
    this.fetchFn = fetchFn;
  }

  async assignShelfSku(
    requestId: string | null,
    shelfId: string,
    tenant: string,
    preview: boolean | null,
    tags: string[] | null,
    sku: string,
  ): Promise<ShelfSkuOutput | ServiceUnavailable> {
    const headers: Record<string, string> = {};
    headers["Content-Type"] = "application/json";
    if (requestId !== null && requestId !== undefined) {
      headers["X-Request-Id"] = String(requestId);
    }
    const queryParts: string[] = [];
    queryParts.push(encodeRfc3986("tenant") + "=" + encodeRfc3986(String(tenant)));
    if (preview !== null && preview !== undefined) {
      queryParts.push(encodeRfc3986("preview") + "=" + encodeRfc3986(String(preview)));
    }
    if (tags !== null && tags !== undefined) {
      for (const value of tags) {
        queryParts.push(encodeRfc3986("tag") + "=" + encodeRfc3986(String(value)));
      }
    }
    const queryString = queryParts.join("&");
    const requestUrl = `${this.baseUrl}/shelves/${encodeRfc3986(String(shelfId))}/skus` + (queryString ? "?" + queryString : "");
    const requestBody = JSON.stringify(sku);
    const response = await this.fetchFn(
      requestUrl,
      {
        method: "POST",
        headers,
        body: requestBody,
      },
    );
    const normalized = {
      status: response.status,
      headers: Object.fromEntries(response.headers.entries()),
      text: () => response.text(),
      json: async () => await response.json(),
    };
    const parsed = await parseClientResponse(normalized, OPERATION_HTTP_BINDINGS["assignShelfSku"]);
    return parsed as ShelfSkuOutput | ServiceUnavailable;
  }

  async createShelfItem(
    contentType: string | null,
    idempotencyKey: string | null,
    warehouseId: string,
    shelfId: string,
    details: ItemDetails,
  ): Promise<ShelfItemOutput | Conflict | ServiceUnavailable> {
    const headers: Record<string, string> = {};
    if (contentType !== null && contentType !== undefined) {
      headers["content-type"] = String(contentType);
    }
    if (idempotencyKey !== null && idempotencyKey !== undefined) {
      headers["X-Idempotency-Key"] = String(idempotencyKey);
    }
    const queryParts: string[] = [];
    const queryString = queryParts.join("&");
    const requestUrl = `${this.baseUrl}/warehouses/${encodeRfc3986(String(warehouseId))}/shelves/${encodeRfc3986(String(shelfId))}/items` + (queryString ? "?" + queryString : "");
    const requestBody = JSON.stringify(dumpApiModel(details));
    const response = await this.fetchFn(
      requestUrl,
      {
        method: "POST",
        headers,
        body: requestBody,
      },
    );
    const normalized = {
      status: response.status,
      headers: Object.fromEntries(response.headers.entries()),
      text: () => response.text(),
      json: async () => await response.json(),
    };
    const parsed = await parseClientResponse(normalized, OPERATION_HTTP_BINDINGS["createShelfItem"]);
    return parsed as ShelfItemOutput | Conflict | ServiceUnavailable;
  }
}
