import {
  COUNTER_TARGET,
  isAdminRoleAssignment
} from "./chunk-RQKJNMX5.mjs";
import {
  countMembershipsByUserOperation,
  listTenantsOperation,
  listWorkspacesOperation,
  membershipListByWorkspaceOperation,
  roleAssignmentListByWorkspaceOperation
} from "./chunk-AYHBFK3Y.mjs";
import {
  listMembershipsOperation
} from "./chunk-RGE4WDND.mjs";
import {
  extractRoleLevel
} from "./chunk-BUAYVN3C.mjs";
import {
  extractReferenceSlug
} from "./chunk-I6LUPJUY.mjs";
import {
  listUsersOperation
} from "./chunk-V6AO5T57.mjs";
import {
  getDynamoControlService
} from "./chunk-EUIP2U5F.mjs";

// src/data/operations/control/counters/counter-reconcile-operation.ts
function counterValue(value) {
  return typeof value === "number" && Number.isFinite(value) ? value : 0;
}
function reconcileContext(tenantId) {
  return {
    tenantId,
    workspaceId: "",
    date: (/* @__PURE__ */ new Date()).toISOString(),
    actorId: "counter-reconciliation",
    actorName: "Counter Reconciliation Job",
    actorType: "internal-system",
    source: "step-function"
  };
}
async function reconcileTenantCountersOperation(params) {
  const { tenantId, tableName } = params;
  const service = getDynamoControlService(tableName);
  const context = reconcileContext(tenantId);
  const workspacesResult = await listWorkspacesOperation({
    context,
    tableName,
    mode: "count"
  });
  const workspacesInTenant = workspacesResult.total;
  const memberships = await listMembershipsOperation({
    context,
    tableName,
    mode: "full"
  });
  let usersInTenant = 0;
  for (const entry of memberships.entries) {
    const workspaceSlug = extractReferenceSlug(entry.resource, "workspace");
    if (workspaceSlug === void 0) {
      usersInTenant += 1;
    }
  }
  const current = await service.entities.tenant.get({ tenantId, sk: "CURRENT" }).go();
  const drift = [];
  const recomputed = {
    usersInTenant,
    workspacesInTenant
  };
  for (const counter of Object.keys(recomputed)) {
    const oldValue = counterValue(current.data?.[counter]);
    const newValue = recomputed[counter];
    if (oldValue !== newValue) {
      drift.push({
        target: COUNTER_TARGET.Tenant,
        id: tenantId,
        counter,
        old: oldValue,
        new: newValue
      });
    }
  }
  if (drift.length > 0) {
    await service.entities.tenant.patch({ tenantId, sk: "CURRENT" }).set(recomputed).go();
  }
  return { drift };
}
async function reconcileWorkspaceCountersOperation(params) {
  const { tenantId, workspaceId, tableName } = params;
  const service = getDynamoControlService(tableName);
  let usersInWorkspace = 0;
  let membershipCursor = null;
  do {
    const page = await membershipListByWorkspaceOperation({
      tenantId,
      workspaceId,
      cursor: membershipCursor,
      tableName
    });
    usersInWorkspace += page.items.length;
    membershipCursor = page.cursor;
  } while (membershipCursor !== null);
  let adminUsersInWorkspace = 0;
  let normalUsersInWorkspace = 0;
  let roleAssignmentCursor = null;
  do {
    const page = await roleAssignmentListByWorkspaceOperation({
      tenantId,
      workspaceId,
      cursor: roleAssignmentCursor,
      tableName
    });
    for (const item of page.items) {
      const roleLevel = await readRoleLevel(
        service,
        tenantId,
        item.roleAssignmentId
      );
      if (isAdminRoleAssignment({ roleLevel, roleId: item.roleId })) {
        adminUsersInWorkspace += 1;
      } else {
        normalUsersInWorkspace += 1;
      }
    }
    roleAssignmentCursor = page.cursor;
  } while (roleAssignmentCursor !== null);
  const current = await service.entities.workspace.get({ tenantId, id: workspaceId, sk: "CURRENT" }).go();
  const drift = [];
  const recomputed = {
    usersInWorkspace,
    adminUsersInWorkspace,
    normalUsersInWorkspace
  };
  for (const counter of Object.keys(recomputed)) {
    const oldValue = counterValue(current.data?.[counter]);
    const newValue = recomputed[counter];
    if (oldValue !== newValue) {
      drift.push({
        target: COUNTER_TARGET.Workspace,
        id: workspaceId,
        tenantId,
        counter,
        old: oldValue,
        new: newValue
      });
    }
  }
  if (drift.length > 0) {
    await service.entities.workspace.patch({ tenantId, id: workspaceId, sk: "CURRENT" }).set(recomputed).go();
  }
  return { drift };
}
async function reconcileUserCountersOperation(params) {
  const { userId, tableName } = params;
  const service = getDynamoControlService(tableName);
  const tenantsForUser = await countMembershipsByUserOperation({
    userId,
    mode: "tenant",
    tableName
  });
  const workspacesForUser = await countMembershipsByUserOperation({
    userId,
    mode: "workspace",
    tableName
  });
  const current = await service.entities.user.get({ id: userId, sk: "CURRENT" }).go();
  const drift = [];
  const recomputed = {
    tenantsForUser,
    workspacesForUser
  };
  for (const counter of Object.keys(recomputed)) {
    const oldValue = counterValue(current.data?.[counter]);
    const newValue = recomputed[counter];
    if (oldValue !== newValue) {
      drift.push({
        target: COUNTER_TARGET.User,
        id: userId,
        counter,
        old: oldValue,
        new: newValue
      });
    }
  }
  if (drift.length > 0) {
    await service.entities.user.patch({ id: userId, sk: "CURRENT" }).set(recomputed).go();
  }
  return { drift };
}
async function readRoleLevel(service, tenantId, roleAssignmentId) {
  const response = await service.entities.roleAssignment.get({ tenantId, id: roleAssignmentId, sk: "CURRENT" }).go();
  if (!response.data) {
    return void 0;
  }
  const resource = JSON.parse(response.data.resource);
  return extractRoleLevel(resource);
}

// src/data/operations/control/counters/counter-reconcile-driver.ts
function driverContext(tenantId) {
  return {
    tenantId,
    workspaceId: "",
    date: (/* @__PURE__ */ new Date()).toISOString(),
    actorId: "counter-reconciliation",
    actorName: "Counter Reconciliation Job",
    actorType: "internal-system",
    source: "step-function"
  };
}
async function reconcileAllCountersOperation(params = {}) {
  const { tableName } = params;
  const drift = [];
  let tenantsScanned = 0;
  let workspacesScanned = 0;
  let usersScanned = 0;
  const tenants = await listTenantsOperation({
    context: driverContext(""),
    tableName,
    mode: "summary"
  });
  for (const tenant of tenants.entries) {
    tenantsScanned += 1;
    const tenantResult = await reconcileTenantCountersOperation({
      tenantId: tenant.id,
      tableName
    });
    drift.push(...tenantResult.drift);
    const workspaces = await listWorkspacesOperation({
      context: driverContext(tenant.id),
      tableName,
      mode: "summary"
    });
    for (const workspace of workspaces.entries) {
      workspacesScanned += 1;
      const workspaceResult = await reconcileWorkspaceCountersOperation({
        tenantId: tenant.id,
        workspaceId: workspace.id,
        tableName
      });
      drift.push(...workspaceResult.drift);
    }
  }
  const users = await listUsersOperation({
    context: driverContext(""),
    tableName,
    mode: "summary"
  });
  for (const user of users.entries) {
    usersScanned += 1;
    const userResult = await reconcileUserCountersOperation({
      userId: user.id,
      tableName
    });
    drift.push(...userResult.drift);
  }
  return {
    drift,
    scanned: {
      tenants: tenantsScanned,
      workspaces: workspacesScanned,
      users: usersScanned
    },
    countersCorrected: drift.length
  };
}

export {
  reconcileAllCountersOperation
};
//# sourceMappingURL=chunk-7WBLBIQJ.mjs.map