import { InferInsertModel, SQL, Table } from "drizzle-orm";
import { Querier, Transaction, TransactionalDatabase } from "@platform-modules/db";
//#region src/index.d.ts
type TenantStatus = 'active' | 'suspended' | 'pending';
type MembershipStatus = 'active' | 'frozen' | 'pending_approval';
type Tenant = {
  id: string;
  slug: string;
  name: string;
  status: TenantStatus;
  ownerId: string;
  createdAt: Date;
};
type Membership = {
  tenantId: string;
  userId: string;
  roleKey: string;
  status: MembershipStatus;
};
type CreateTenantInput = {
  slug: string;
  name: string;
  ownerId: string;
  status?: TenantStatus;
};
type TenancyStore = {
  createTenant(input: CreateTenantInput): Promise<Tenant>;
  getTenant(tenantId: string): Promise<Tenant | null>;
  getTenantBySlug(slug: string): Promise<Tenant | null>;
  suspendTenant(tenantId: string): Promise<Tenant>;
  addMember(membership: Membership): Promise<Membership>;
  removeMember(tenantId: string, userId: string): Promise<void>;
  setMemberRole(tenantId: string, userId: string, roleKey: string): Promise<Membership>;
  freezeMember(tenantId: string, userId: string): Promise<Membership>;
  listMembers(tenantId: string): Promise<Membership[]>;
  getMembership(tenantId: string, userId: string): Promise<Membership | null>;
};
type RunInTenantFn<S extends Record<string, unknown> = Record<string, never>> = <T>(db: TransactionalDatabase<S>, tenantId: string, fn: (scoped: Transaction<S>) => Promise<T>, opts?: {
  gucName?: string;
  role?: string;
}) => Promise<T>;
type ScopedSelectBuilder = {
  from(table: Table, ...rest: unknown[]): unknown;
};
type SnakeToCamel<S extends string> = S extends `${infer Head}_${infer Tail}` ? `${Head}${Capitalize<SnakeToCamel<Tail>>}` : S;
type ScopedTenantOmitKeys<T extends Table, C extends string> = Extract<keyof InferInsertModel<T>, C | SnakeToCamel<C>>;
type ScopedInsertValues<T extends Table, C extends string> = Omit<InferInsertModel<T>, ScopedTenantOmitKeys<T, C>>;
type ScopedInsertBuilder<TTable extends Table = Table, C extends string = never> = {
  values(values: ScopedInsertValues<TTable, C> | ScopedInsertValues<TTable, C>[]): unknown;
};
type ScopedUpdateBuilder<TTable extends Table = Table, C extends string = never> = {
  set(patch: Partial<ScopedInsertValues<TTable, C>>): unknown;
};
type ScopedQuerier<S extends Record<string, unknown> = Record<string, never>, C extends string = never> = {
  select: (...args: unknown[]) => ScopedSelectBuilder;
  selectDistinct: (...args: unknown[]) => ScopedSelectBuilder;
  selectDistinctOn: (...args: unknown[]) => ScopedSelectBuilder;
  insert: <TTable extends Table>(table: TTable) => ScopedInsertBuilder<TTable, C>;
  update: <TTable extends Table>(table: TTable) => ScopedUpdateBuilder<TTable, C>;
  delete: <TTable extends Table>(table: TTable) => {
    where: (condition?: SQL) => unknown;
  };
};
type IsolationAdapter<S extends Record<string, unknown> = Record<string, never>, C extends string = never> = {
  scopeQuerier(q: Querier<S>, tenantId: string): ScopedQuerier<S, C>;
};
type RbacResolveInput = {
  userId: string;
  tenantId: string;
  roleKey: string;
};
type RbacAdapter = {
  resolveCapabilities(input: RbacResolveInput): Promise<string[]>;
};
declare class TenancyError extends Error {}
declare class TenantNotFoundError extends TenancyError {
  readonly tenantId: string;
  readonly name = "TenantNotFoundError";
  constructor(message: string, tenantId: string);
}
declare class NotAMemberError extends TenancyError {
  readonly tenantId: string;
  readonly userId: string;
  readonly name = "NotAMemberError";
  constructor(message: string, tenantId: string, userId: string);
}
declare class MembershipFrozenError extends TenancyError {
  readonly tenantId: string;
  readonly userId: string;
  readonly name = "MembershipFrozenError";
  constructor(message: string, tenantId: string, userId: string);
}
declare class ScopeViolationError extends TenancyError {
  readonly tenantId: string;
  readonly name = "ScopeViolationError";
  constructor(message: string, tenantId: string);
}
type TenancyDeps<S extends Record<string, unknown> = Record<string, never>> = {
  store: TenancyStore;
  rbac: RbacAdapter;
  isolation?: IsolationAdapter<S>;
};
type Tenancy<S extends Record<string, unknown> = Record<string, never>> = {
  scopeQuerier?(q: Querier<S>, tenantId: string): ScopedQuerier<S>;
  resolveCapabilities(userId: string, tenantId: string): Promise<string[]>;
  createTenant(input: CreateTenantInput): Promise<Tenant>;
  getTenant(tenantId: string): Promise<Tenant | null>;
  suspendTenant(tenantId: string): Promise<Tenant>;
  addMember(membership: Membership): Promise<Membership>;
  removeMember(tenantId: string, userId: string): Promise<void>;
  setMemberRole(tenantId: string, userId: string, roleKey: string): Promise<Membership>;
  freezeMember(tenantId: string, userId: string): Promise<Membership>;
  listMembers(tenantId: string): Promise<Membership[]>;
};
declare function createMemoryTenancyStore(): TenancyStore;
declare function createTenancy<S extends Record<string, unknown> = Record<string, never>>(deps: TenancyDeps<S>): Tenancy<S>;
//#endregion
export { CreateTenantInput, IsolationAdapter, Membership, MembershipFrozenError, MembershipStatus, NotAMemberError, RbacAdapter, RbacResolveInput, RunInTenantFn, ScopeViolationError, ScopedInsertBuilder, ScopedInsertValues, ScopedQuerier, ScopedSelectBuilder, ScopedTenantOmitKeys, ScopedUpdateBuilder, Tenancy, TenancyDeps, TenancyError, TenancyStore, Tenant, TenantNotFoundError, TenantStatus, createMemoryTenancyStore, createTenancy };