import { evaluateExpression } from "./expression-evaluator.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("business_rules").child({ component: "rule-evaluator" });
async function evaluate(rules, data, context) {
  const startTime = Date.now();
  const matchedRules = [];
  const failedRules = [];
  const errors = [];
  let anyEvaluationCompleted = false;
  const sortedRules = sortRulesByPriority(rules);
  for (const rule of sortedRules) {
    try {
      const result = await evaluateSingleRule(rule, data, context);
      if (result.evaluationCompleted) {
        anyEvaluationCompleted = true;
      }
      if (result.evaluationCompleted && result.conditionsPassed) {
        matchedRules.push(rule);
      } else {
        failedRules.push(rule);
      }
      if (result.error) {
        errors.push(`Rule ${rule.ruleId}: ${result.error}`);
      }
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error);
      errors.push(`Rule ${rule.ruleId}: ${errorMessage}`);
      failedRules.push(rule);
    }
  }
  const evaluationTime = Math.max(0, Date.now() - startTime);
  const conditionsPassed = matchedRules.length > 0;
  return {
    conditionsPassed,
    evaluationCompleted: anyEvaluationCompleted,
    matchedRules,
    failedRules,
    evaluationTime,
    errors: errors.length > 0 ? errors : void 0
  };
}
async function evaluateSingleRule(rule, data, context) {
  const startTime = Date.now();
  logger.debug("Evaluating rule", {
    ruleId: rule.ruleId,
    ruleName: rule.ruleName,
    ruleType: rule.ruleType,
    entityType: rule.entityType,
    eventType: rule.eventType,
    conditions: rule.conditionExpression
  });
  try {
    if (!rule.enabled) {
      logger.debug("Rule is disabled", { ruleId: rule.ruleId });
      return {
        rule,
        conditionsPassed: false,
        evaluationCompleted: false,
        evaluationTime: 0,
        error: "Rule is disabled"
      };
    }
    if (!isRuleEffective(rule)) {
      logger.debug("Rule is not effective (outside date range)", { ruleId: rule.ruleId });
      return {
        rule,
        conditionsPassed: false,
        evaluationCompleted: false,
        evaluationTime: 0,
        error: "Rule is not effective (outside date range)"
      };
    }
    const conditionsPassed = await evaluateConditions(rule.conditionExpression, data, context);
    const evaluationTime = Math.max(0, Date.now() - startTime);
    logger.debug("Rule evaluated", {
      ruleId: rule.ruleId,
      conditionsPassed,
      evaluationTimeMs: evaluationTime
    });
    return {
      rule,
      conditionsPassed,
      evaluationCompleted: true,
      evaluationTime
    };
  } catch (error) {
    const evaluationTime = Math.max(0, Date.now() - startTime);
    const errorMessage = error instanceof Error ? error.message : String(error);
    logger.debug("Rule evaluation error", { ruleId: rule.ruleId, message: errorMessage });
    return {
      rule,
      conditionsPassed: false,
      evaluationCompleted: false,
      evaluationTime,
      error: errorMessage
    };
  }
}
async function evaluateConditions(conditions, data, context) {
  if (!conditions) {
    return true;
  }
  try {
    const expression = conditions;
    return evaluateExpression(expression, data, context);
  } catch (error) {
    throw new Error(`Condition evaluation failed: ${error instanceof Error ? error.message : String(error)}`);
  }
}
function sortRulesByPriority(rules) {
  return [...rules].sort((a, b) => {
    if (b.priority !== a.priority) {
      return b.priority - a.priority;
    }
    return a.ruleId.localeCompare(b.ruleId);
  });
}
function isRuleEffective(rule) {
  const now = /* @__PURE__ */ new Date();
  if (rule.effectiveFrom && rule.effectiveFrom > now) {
    return false;
  }
  if (rule.effectiveTo && rule.effectiveTo < now) {
    return false;
  }
  return true;
}
function filterRulesByContext(rules, entityType, eventType) {
  return rules.filter((rule) => {
    if (entityType && rule.entityType !== entityType) {
      return false;
    }
    if (eventType && rule.eventType && rule.eventType !== eventType) {
      return false;
    }
    return true;
  });
}
function getApplicableRules(rules, entityType, eventType) {
  const filtered = filterRulesByContext(rules, entityType, eventType);
  const enabled = filtered.filter((rule) => rule.enabled);
  const effective = enabled.filter((rule) => isRuleEffective(rule));
  return sortRulesByPriority(effective);
}
export {
  evaluate,
  evaluateConditions,
  evaluateSingleRule,
  filterRulesByContext,
  getApplicableRules,
  sortRulesByPriority
};
//# sourceMappingURL=rule-evaluator.js.map
