import { findOneWithDecryption, findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
async function matchContacts(em, participants, scope, deps) {
  const results = [];
  const entityClass = deps?.customerEntityClass;
  if (!entityClass) return participants.map((p) => ({
    participant: {
      name: p.name,
      email: p.email,
      role: p.role,
      matchedContactId: null,
      matchedContactType: null
    },
    match: null
  }));
  for (const participant of participants) {
    const match = await matchSingleContact(em, participant, scope, entityClass);
    results.push({
      participant: {
        name: participant.name,
        email: participant.email,
        role: participant.role,
        matchedContactId: match?.contactId || null,
        matchedContactType: match?.contactType || null,
        matchConfidence: match?.confidence
      },
      match
    });
  }
  return results;
}
async function matchSingleContact(em, participant, scope, entityClass) {
  if (!participant.email && !participant.name) return null;
  if (participant.email) {
    const emailMatch = await findOneWithDecryption(
      em,
      entityClass,
      {
        primaryEmail: participant.email.toLowerCase(),
        deletedAt: null,
        organizationId: scope.organizationId,
        tenantId: scope.tenantId
      },
      { orderBy: { createdAt: "DESC" } },
      { tenantId: scope.tenantId, organizationId: scope.organizationId }
    );
    if (emailMatch) {
      return {
        contactId: emailMatch.id,
        contactType: emailMatch.kind === "company" ? "company" : "person",
        contactName: emailMatch.displayName || participant.name,
        confidence: 1
      };
    }
  }
  const hasEmail = Boolean(participant.email);
  const hasName = participant.name && participant.name.length >= 2;
  if (!hasEmail && !hasName) return null;
  const decryptedResults = await findWithDecryption(
    em,
    entityClass,
    {
      deletedAt: null,
      organizationId: scope.organizationId,
      tenantId: scope.tenantId
    },
    { limit: 100, orderBy: { createdAt: "DESC" } },
    { tenantId: scope.tenantId, organizationId: scope.organizationId }
  );
  if (hasEmail) {
    const emailLower = participant.email.toLowerCase();
    const emailMatch = decryptedResults.find(
      (entity) => entity.primaryEmail && entity.primaryEmail.toLowerCase() === emailLower
    );
    if (emailMatch) {
      return {
        contactId: emailMatch.id,
        contactType: emailMatch.kind === "company" ? "company" : "person",
        contactName: emailMatch.displayName || participant.name,
        confidence: 1
      };
    }
  }
  if (hasName) {
    const normalizedSearch = participant.name.toLowerCase().trim();
    let bestMatch = null;
    for (const entity of decryptedResults) {
      const displayName = (entity.displayName || "").toLowerCase().trim();
      if (!displayName) continue;
      let score = 0;
      if (displayName === normalizedSearch) {
        score = 1;
      } else if (displayName.startsWith(normalizedSearch) || normalizedSearch.startsWith(displayName)) {
        score = 0.9;
      } else if (displayName.includes(normalizedSearch) || normalizedSearch.includes(displayName)) {
        score = 0.7;
      }
      if (score > 0 && (!bestMatch || score > bestMatch.score)) {
        bestMatch = { entity, score };
      }
    }
    if (bestMatch && bestMatch.score >= 0.7) {
      return {
        contactId: bestMatch.entity.id,
        contactType: bestMatch.entity.kind === "company" ? "company" : "person",
        contactName: bestMatch.entity.displayName || participant.name,
        confidence: bestMatch.score
      };
    }
  }
  return null;
}
export {
  matchContacts
};
//# sourceMappingURL=contactMatcher.js.map
