function toPascal(name: string): string {
  return name.charAt(0).toUpperCase() + name.slice(1);
}

export function renderCommandStub(name: string): string {
  const inputType = `${toPascal(name)}Input`;
  return `import type { Transaction } from "../generated/kysely-tailordb";
import { ok, type CommandContext } from "@tailor-platform/erp-kit/core";

export interface ${inputType} {
  // TODO: define input fields
}

export async function run(db: Transaction, input: ${inputType}, ctx: CommandContext) {
  // TODO: implement
  return ok({});
}
`;
}

export function renderCommandTestStub(name: string): string {
  const pascal = toPascal(name);
  return `import { createKyselyMock } from "@tailor-platform/sdk/vitest";
import { describe, expect, it } from "vitest";
import type { Namespace } from "../generated/kysely-tailordb";
import { run, ${pascal}Input } from "./${name}";
import type { CommandContext } from "@tailor-platform/erp-kit/core";

describe("${name} - test scenario", () => {
  const ctx: CommandContext = {
    actorId: "test-actor",
    permissions: ["TODO:${name}"],
  };

  it("should be implemented", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    const result = await mock.withTx((trx) => run(trx, {} as ${pascal}Input, ctx));
    expect(result.ok).toBe(true);
  });
});
`;
}

export function renderQueryStub(name: string): string {
  const inputType = `${toPascal(name)}Input`;
  return `import type { DB } from "../generated/kysely-tailordb";
import type { ReadonlyDB } from "@tailor-platform/erp-kit/core";

export interface ${inputType} {
  // TODO: define input fields
}

export async function run(db: ReadonlyDB<DB>, input: ${inputType}) {
  // TODO: implement
  return {};
}
`;
}

export function renderQueryTestStub(name: string): string {
  const pascal = toPascal(name);
  const inputType = `${pascal}Input`;
  return `import { createKyselyMock } from "@tailor-platform/sdk/vitest";
import { describe, expect, it } from "vitest";
import type { Namespace } from "../generated/kysely-tailordb";
import { run, type ${inputType} } from "./${name}";

describe("${name}", () => {
  it("should be implemented", async () => {
    const mock = createKyselyMock<Namespace[keyof Namespace]>();
    const result = await run(mock.db, {} as ${inputType});
    expect(result).toBeDefined();
  });
});
`;
}

export function renderDbStub(name: string): string {
  const pascal = toPascal(name);
  return `import {
  type CommonReservedFields,
  type NoReservedFields,
  defaultGqlPermission,
  defaultPermission,
} from "@tailor-platform/erp-kit/core";
import { db, type TailorAnyDBField } from "@tailor-platform/sdk";

const builtins = {
  // TODO: define fields
};

type ReservedFields = keyof typeof builtins | CommonReservedFields;

export interface Create${pascal}TypeParams<F extends Record<string, TailorAnyDBField>> {
  fields?: NoReservedFields<F, ReservedFields>;
}

export function create${pascal}Type<const F extends Record<string, TailorAnyDBField>>(
  params: Create${pascal}TypeParams<F>,
) {
  return db
    .type("${pascal}", {
      ...builtins,
      ...((params.fields ?? {}) as F),
      ...db.fields.timestamps(),
    })
    .permission(defaultPermission)
    .gqlPermission(defaultGqlPermission);
}

export const ${name} = create${pascal}Type({});
`;
}
