import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core";
import type { Transaction } from "../generated/kysely-tailordb";
import {
  InvalidStateError,
  OauthExchangeFailedError,
  TeamAlreadyConnectedError,
} from "../lib/errors.generated";
import { exchangeOauthCode, type SlackOauthAccessResult } from "../lib/slackClient";
import { parseStateToken } from "../lib/slackState";

export interface CompleteSlackWorkspaceInstallDeps {
  exchangeOauthCode?: (
    code: string,
    redirectUri: string,
    clientId: string,
    clientSecret: string,
  ) => Promise<SlackOauthAccessResult>;
}

export interface CompleteSlackWorkspaceInstallInput {
  state: string;
  code: string;
  redirectUri: string;
  clientId: string;
  clientSecret: string;
  /** Shared secret used to verify the state token's HMAC signature; must equal the value beginSlackWorkspaceInstall signed with. */
  signingSecret: string;
}

export async function run(
  db: Transaction,
  input: CompleteSlackWorkspaceInstallInput,
  ctx: CommandContext,
  deps: CompleteSlackWorkspaceInstallDeps = {},
) {
  const state = await parseStateToken(input.state, input.signingSecret);
  if (!state) {
    return err(new InvalidStateError(input.state));
  }
  if (!state.userId || state.userId !== ctx.actorId) {
    return err(new InvalidStateError("actor-mismatch"));
  }
  if (state.redirectUri !== undefined && state.redirectUri !== input.redirectUri) {
    return err(new InvalidStateError("redirect-uri-mismatch"));
  }
  if (!input.code) {
    return err(new OauthExchangeFailedError("slack-workspace-install"));
  }

  const exchange = deps.exchangeOauthCode ?? exchangeOauthCode;
  let oauth: SlackOauthAccessResult;
  try {
    oauth = await exchange(input.code, input.redirectUri, input.clientId, input.clientSecret);
  } catch {
    return err(new OauthExchangeFailedError("slack-workspace-install"));
  }
  if (!oauth.ok || !oauth.access_token || !oauth.team?.id) {
    return err(new OauthExchangeFailedError("slack-workspace-install"));
  }

  const teamId = oauth.team.id;

  // Singleton connection: the tenant holds at most one SlackWorkspaceIntegration row.
  // An ACTIVE row bound to a different workspace must be uninstalled first.
  // `orderBy("createdAt")` makes the picked row deterministic (oldest wins)
  // if multiple rows ever exist. Residual race: two concurrent installs
  // against an EMPTY table both see no row and both insert — TailorDB cannot
  // express a constant-field unique index, so that window is not closed at
  // the schema level (the `teamId` unique constraint still dedupes same-team
  // double installs).
  const existing = await db
    .selectFrom("SlackWorkspaceIntegration")
    .selectAll()
    .orderBy("createdAt")
    .limit(1)
    .forUpdate()
    .executeTakeFirst();
  if (existing && existing.status === "ACTIVE" && existing.teamId !== teamId) {
    return err(new TeamAlreadyConnectedError(teamId));
  }

  const now = new Date();
  const slackWorkspaceIntegration = existing
    ? await db
        .updateTable("SlackWorkspaceIntegration")
        .set({
          teamId,
          teamName: oauth.team.name ?? existing.teamName,
          botUserId: oauth.bot_user_id ?? existing.botUserId,
          status: "ACTIVE",
          lastValidatedAt: now,
          revokedAt: null,
          updatedAt: now,
        })
        .where("id", "=", existing.id)
        .returningAll()
        .executeTakeFirst()
    : await db
        .insertInto("SlackWorkspaceIntegration")
        .values({
          teamId,
          teamName: oauth.team.name ?? null,
          botUserId: oauth.bot_user_id ?? null,
          status: "ACTIVE",
          installedAt: now,
          lastValidatedAt: now,
          revokedAt: null,
          createdAt: now,
          updatedAt: now,
        })
        .returningAll()
        .executeTakeFirst();

  if (!slackWorkspaceIntegration) {
    return err(new InvalidStateError("failed-to-persist-workspace-connection"));
  }

  return ok({ slackWorkspaceIntegration, botToken: oauth.access_token });
}
