import { applyResponseEnrichers } from "@open-mercato/shared/lib/crud/enricher-runner";
import { loadCustomFieldValues } from "@open-mercato/shared/lib/crud/custom-fields";
import { normalizeCustomFieldResponse } from "@open-mercato/shared/lib/custom-fields/normalize";
import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { CustomerDeal, CustomerEntity } from "../data/entities.js";
import { User } from "@open-mercato/core/modules/auth/data/entities";
import {
  CUSTOMER_INTERACTION_ENTITY_ID
} from "./interactionCompatibility.js";
function resolveActorId(auth) {
  if (typeof auth.sub === "string" && auth.sub.trim().length > 0) return auth.sub;
  if (typeof auth.userId === "string" && auth.userId.trim().length > 0) return auth.userId;
  if (typeof auth.keyId === "string" && auth.keyId.trim().length > 0) return auth.keyId;
  return "system";
}
function mergeAdditiveRecord(base, candidate) {
  if (!candidate) return base;
  const additions = Object.fromEntries(
    Object.entries(candidate).filter(([key]) => !(key in base))
  );
  return {
    ...base,
    ...additions
  };
}
function normalizeInteractionCustomValues(values) {
  return normalizeCustomFieldResponse(values) ?? null;
}
async function resolveUserFeatures(container, userId, tenantId, organizationId) {
  try {
    const rbac = container.resolve("rbacService");
    if (!rbac?.getGrantedFeatures) return void 0;
    return await rbac.getGrantedFeatures(userId, { tenantId, organizationId });
  } catch {
    return void 0;
  }
}
async function buildCustomersInteractionEnricherContext(container, auth, organizationId) {
  const userId = resolveActorId(auth);
  return {
    organizationId: organizationId ?? "",
    tenantId: auth.tenantId ?? "",
    userId,
    em: container.resolve("em"),
    container,
    userFeatures: await resolveUserFeatures(container, userId, auth.tenantId, organizationId)
  };
}
async function loadCustomerSummaries(em, entityIds, tenantId, organizationId) {
  if (!entityIds.length) return /* @__PURE__ */ new Map();
  const entities = await findWithDecryption(em, CustomerEntity, { id: { $in: entityIds } }, void 0, { tenantId, organizationId });
  return new Map(
    entities.map((entity) => [
      entity.id,
      {
        id: entity.id,
        displayName: entity.displayName ?? null,
        kind: entity.kind ?? null
      }
    ])
  );
}
async function hydrateCanonicalInteractions({
  em,
  container,
  auth,
  selectedOrganizationId,
  interactions,
  enrich = false
}) {
  if (interactions.length === 0) return [];
  const authorIds = Array.from(
    new Set(
      interactions.map((interaction) => typeof interaction.authorUserId === "string" ? interaction.authorUserId : null).filter((value) => !!value)
    )
  );
  const dealIds = Array.from(
    new Set(
      interactions.map((interaction) => typeof interaction.dealId === "string" ? interaction.dealId : null).filter((value) => !!value)
    )
  );
  const tenantId = auth.tenantId ?? null;
  const organizationId = selectedOrganizationId ?? null;
  const [users, deals, customFieldValues] = await Promise.all([
    authorIds.length > 0 ? findWithDecryption(em, User, { id: { $in: authorIds } }, void 0, { tenantId, organizationId }) : Promise.resolve([]),
    dealIds.length > 0 ? findWithDecryption(em, CustomerDeal, { id: { $in: dealIds } }, void 0, { tenantId, organizationId }) : Promise.resolve([]),
    loadCustomFieldValues({
      em,
      entityId: CUSTOMER_INTERACTION_ENTITY_ID,
      recordIds: interactions.map((interaction) => interaction.id),
      tenantIdByRecord: Object.fromEntries(interactions.map((interaction) => [interaction.id, interaction.tenantId])),
      organizationIdByRecord: Object.fromEntries(interactions.map((interaction) => [interaction.id, interaction.organizationId])),
      tenantFallbacks: [auth.tenantId].filter((value) => !!value)
    })
  ]);
  const userMap = new Map(
    users.map((user) => [
      user.id,
      {
        name: user.name ?? null,
        email: user.email ?? null
      }
    ])
  );
  const dealMap = new Map(deals.map((deal) => [deal.id, deal.title]));
  const baseItems = interactions.map((interaction) => {
    const entityId = typeof interaction.entity === "string" ? interaction.entity : interaction.entity.id;
    return {
      id: interaction.id,
      entityId,
      dealId: interaction.dealId ?? null,
      interactionType: interaction.interactionType,
      title: interaction.title ?? null,
      body: interaction.body ?? null,
      status: interaction.status,
      scheduledAt: interaction.scheduledAt ? interaction.scheduledAt.toISOString() : null,
      occurredAt: interaction.occurredAt ? interaction.occurredAt.toISOString() : null,
      priority: interaction.priority ?? null,
      authorUserId: interaction.authorUserId ?? null,
      ownerUserId: interaction.ownerUserId ?? null,
      appearanceIcon: interaction.appearanceIcon ?? null,
      appearanceColor: interaction.appearanceColor ?? null,
      source: interaction.source ?? null,
      duration: interaction.durationMinutes ?? null,
      location: interaction.location ?? null,
      allDay: interaction.allDay ?? null,
      recurrenceRule: interaction.recurrenceRule ?? null,
      recurrenceEnd: interaction.recurrenceEnd ? interaction.recurrenceEnd.toISOString() : null,
      participants: interaction.participants ?? null,
      reminderMinutes: interaction.reminderMinutes ?? null,
      visibility: interaction.visibility ?? null,
      linkedEntities: interaction.linkedEntities ?? null,
      guestPermissions: interaction.guestPermissions ?? null,
      organizationId: interaction.organizationId,
      tenantId: interaction.tenantId,
      createdAt: interaction.createdAt.toISOString(),
      updatedAt: interaction.updatedAt.toISOString(),
      authorName: interaction.authorUserId ? userMap.get(interaction.authorUserId)?.name ?? null : null,
      authorEmail: interaction.authorUserId ? userMap.get(interaction.authorUserId)?.email ?? null : null,
      dealTitle: interaction.dealId ? dealMap.get(interaction.dealId) ?? null : null,
      customValues: normalizeInteractionCustomValues(customFieldValues[interaction.id])
    };
  });
  if (!enrich) return baseItems;
  const enricherContext = await buildCustomersInteractionEnricherContext(
    container,
    auth,
    selectedOrganizationId
  );
  const enriched = await applyResponseEnrichers(baseItems, "customers.interaction", enricherContext);
  return baseItems.map((item, index) => mergeAdditiveRecord(item, enriched.items[index]));
}
export {
  buildCustomersInteractionEnricherContext,
  hydrateCanonicalInteractions,
  loadCustomerSummaries
};
//# sourceMappingURL=interactionReadModel.js.map
