import {
  type CommonReservedFields,
  type NoReservedFields,
  defaultGqlPermission,
  defaultPermission,
} from "@tailor-platform/erp-kit/core";
import { db, type TailorAnyDBField } from "@tailor-platform/sdk";
import { slackWorkspaceIntegrationLifecycle } from "./slackWorkspaceIntegration.lifecycle.generated";

/** Connection states of a SlackWorkspaceIntegration (e.g. PENDING, ACTIVE, REVOKED). */
export const SLACK_WORKSPACE_INTEGRATION_STATUSES = slackWorkspaceIntegrationLifecycle.states;

const builtins = {
  teamId: db
    .string()
    .unique()
    .description(
      "Slack team id; unique across the module so the tenant holds at most one connection",
    ),
  teamName: db.string({ optional: true }).description("Slack workspace display name"),
  botUserId: db.string({ optional: true }).description("Slack bot user id"),
  status: db
    .enum(SLACK_WORKSPACE_INTEGRATION_STATUSES)
    .description("Workspace connection lifecycle status (ACTIVE, REVOKED)"),
  installedAt: db.datetime().description("First successful install timestamp"),
  lastValidatedAt: db
    .datetime({ optional: true })
    .description("Last successful (re-)install / validation timestamp"),
  revokedAt: db
    .datetime({ optional: true })
    .description("Revocation timestamp set when app_uninstalled is handled"),
};

type ReservedFields = keyof typeof builtins | CommonReservedFields;

export interface CreateSlackWorkspaceIntegrationTypeParams<
  F extends Record<string, TailorAnyDBField>,
> {
  fields?: NoReservedFields<F, ReservedFields>;
}

export function createSlackWorkspaceIntegrationType<
  const F extends Record<string, TailorAnyDBField> = Record<string, never>,
>(params: CreateSlackWorkspaceIntegrationTypeParams<F> = {}) {
  return db
    .type("SlackWorkspaceIntegration", {
      ...builtins,
      ...params.fields,
      ...db.fields.timestamps(),
    })
    .features({
      // Close the GraphQL gateway's auto-CRUD entirely (mirrors
      // DestinationDeliveryLog): this row carries only workspace metadata (the
      // bot token lives in the host secret manager, not here), and the only
      // read surface is the redacted getSlackWorkspaceIntegration query; all
      // writes go through the install / uninstall commands' in-transaction db
      // handle.
      gqlOperations: { create: false, read: false, update: false, delete: false },
    })
    .permission(defaultPermission)
    .gqlPermission(defaultGqlPermission);
}

export const slackWorkspaceIntegration = createSlackWorkspaceIntegrationType();
