import { GeneratedJsWithTypes, header } from "./common.js";

const serverDTS = `
  ${header(
    "Generated utilities for implementing server-side Convex query and mutation functions."
  )}
  import {
    MutationBuilderForDataModel,
    QueryBuilderForDataModel,
    QueryCtx as GenericQueryCtx,
    MutationCtx as GenericMutationCtx,
    DatabaseReader as GenericDatabaseReader,
    DatabaseWriter as GenericDatabaseWriter,
  } from "convex/server";
  import { DataModel } from "./dataModel.js";

  /**
   * Define a query in this Convex app's public API.
   *
   * This function will be allowed to read your Convex database and will be accessible from the client.
   *
   * @param func - The query function. It receives a {@link QueryCtx} as its first argument.
   * @returns The wrapped query. Include this as an \`export\` to name it and make it accessible.
   */
  export declare const query: QueryBuilderForDataModel<DataModel>;

  /**
   * Define a mutation in this Convex app's public API.
   *
   * This function will be allowed to modify your Convex database and will be accessible from the client.
   *
   * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
   * @returns The wrapped mutation. Include this as an \`export\` to name it and make it accessible.
   */
  export declare const mutation: MutationBuilderForDataModel<DataModel>;

  /**
   * A set of services for use within Convex query functions.
   *
   * The query context is passed as the first argument to any Convex query
   * function run on the server.
   *
   * This differs from the {@link MutationCtx} because all of the services are
   * read-only.
   */
  export type QueryCtx = GenericQueryCtx<DataModel>;

  /**
   * A set of services for use within Convex mutation functions.
   *
   * The mutation context is passed as the first argument to any Convex mutation
   * function run on the server.
   */
  export type MutationCtx = GenericMutationCtx<DataModel>;

  /**
   * An interface to read from the database within Convex query functions.
   *
   * The two entry points are {@link DatabaseReader.get}, which fetches a single
   * document by its {@link Id}, or {@link DatabaseReader.query}, which starts
   * building a query.
   */
  export type DatabaseReader = GenericDatabaseReader<DataModel>;

  /**
   * An interface to read from and write to the database within Convex mutation
   * functions.
   *
   * Convex guarantees that all writes within a single mutation are
   * executed atomically, so you never have to worry about partial writes leaving
   * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)
   * for the guarantees Convex provides your functions.
   */
  export type DatabaseWriter = GenericDatabaseWriter<DataModel>;`;

const serverJS = `
  ${header(
    "Generated utilities for implementing server-side Convex query and mutation functions."
  )}
  import {
    queryGeneric,
    mutationGeneric,
  } from "convex/server";

  /**
   * Define a query in this Convex app's public API.
   *
   * This function will be allowed to read your Convex database and will be accessible from the client.
   *
   * @param func - The query function. It receives a {@link QueryCtx} as its first argument.
   * @returns The wrapped query. Include this as an \`export\` to name it and make it accessible.
   */
  export const query = queryGeneric;

  /**
   * Define a mutation in this Convex app's public API.
   *
   * This function will be allowed to modify your Convex database and will be accessible from the client.
   *
   * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
   * @returns The wrapped mutation. Include this as an \`export\` to name it and make it accessible.
   */
  export const mutation = mutationGeneric;
  `;

export const server: GeneratedJsWithTypes = {
  DTS: serverDTS,
  JS: serverJS,
};
