import * as fs from "fs";
import * as path from "path";
import { fileURLToPath } from "node:url";
import { WorkflowDefinition } from "../data/entities.js";
import { BusinessRule } from "@open-mercato/core/modules/business_rules/data/entities";
import {
  invalidateBusinessRuleDiscoveryCache
} from "@open-mercato/core/modules/business_rules/lib/rule-engine";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("workflows");
const __esmDirname = path.dirname(fileURLToPath(import.meta.url));
function readExampleJson(fileName) {
  const candidates = [
    path.join(__esmDirname, "..", "examples", fileName),
    path.join(process.cwd(), "packages", "core", "src", "modules", "workflows", "examples", fileName),
    path.join(process.cwd(), "src", "modules", "workflows", "examples", fileName)
  ];
  const filePath = candidates.find((candidate) => fs.existsSync(candidate));
  if (!filePath) {
    throw new Error(`Missing workflow seed file: ${fileName}`);
  }
  return JSON.parse(fs.readFileSync(filePath, "utf8"));
}
function requireString(value, label) {
  if (typeof value === "string" && value.trim().length > 0) return value;
  throw new Error(`Invalid ${label} in workflow seed data.`);
}
async function seedWorkflowDefinition(em, scope, fileName) {
  const seed = readExampleJson(fileName);
  const workflowId = requireString(seed.workflowId, "workflowId");
  const existing = await em.findOne(WorkflowDefinition, {
    workflowId,
    tenantId: scope.tenantId,
    organizationId: scope.organizationId
  });
  if (existing) {
    const seedStepCount = seed.definition.steps.length;
    const existingStepCount = existing.definition.steps.length;
    const seedTransitionCount = seed.definition.transitions.length;
    const existingTransitionCount = existing.definition.transitions.length;
    const seedHasTransitionPreConditions = seed.definition.transitions.some(
      (t) => t.preConditions && t.preConditions.length > 0
    );
    const existingHasTransitionPreConditions = existing.definition.transitions.some(
      (t) => t.preConditions && t.preConditions.length > 0
    );
    const seedStartStep = seed.definition.steps.find((s) => s.stepType === "START");
    const existingStartStep = existing.definition.steps.find((s) => s.stepType === "START");
    const seedHasStartPreConditions = seedStartStep?.preConditions && seedStartStep.preConditions.length > 0;
    const existingHasStartPreConditions = existingStartStep?.preConditions && existingStartStep.preConditions.length > 0;
    const needsUpdate = seedStepCount !== existingStepCount || seedTransitionCount !== existingTransitionCount || seedHasStartPreConditions && !existingHasStartPreConditions || seedHasTransitionPreConditions && !existingHasTransitionPreConditions;
    if (needsUpdate) {
      logger.info("Updating seeded workflow", {
        component: "seed",
        workflowId,
        existingStepCount,
        seedStepCount,
        existingTransitionCount,
        seedTransitionCount
      });
      existing.definition = seed.definition;
      await em.flush();
      return true;
    }
    return false;
  }
  const workflow = em.create(WorkflowDefinition, {
    ...seed,
    workflowId,
    tenantId: scope.tenantId,
    organizationId: scope.organizationId
  });
  em.persist(workflow);
  await em.flush();
  return true;
}
async function seedGuardRules(em, scope, fileName, cache) {
  const seeds = readExampleJson(fileName);
  if (!Array.isArray(seeds)) {
    throw new Error("Invalid guard rules seed data.");
  }
  let seeded = 0;
  let skipped = 0;
  let updated = 0;
  for (const rule of seeds) {
    const ruleId = requireString(rule.ruleId, "ruleId");
    const existing = await em.findOne(BusinessRule, {
      ruleId,
      tenantId: scope.tenantId,
      organizationId: scope.organizationId
    });
    if (existing) {
      const needsUpdate = existing.entityType !== rule.entityType || existing.eventType !== rule.eventType;
      if (needsUpdate) {
        logger.info("Updating seeded business rule", {
          component: "seed",
          ruleId,
          entityType: rule.entityType,
          eventType: rule.eventType
        });
        existing.entityType = rule.entityType;
        existing.eventType = rule.eventType ?? null;
        updated += 1;
      } else {
        skipped += 1;
      }
      continue;
    }
    const entry = em.create(BusinessRule, {
      ruleId,
      ruleName: rule.ruleName,
      ruleType: rule.ruleType,
      entityType: rule.entityType,
      conditionExpression: rule.conditionExpression,
      eventType: rule.eventType,
      ruleCategory: rule.ruleCategory,
      description: rule.description,
      successActions: rule.successActions,
      failureActions: rule.failureActions,
      enabled: rule.enabled,
      priority: rule.priority,
      version: rule.version,
      effectiveFrom: rule.effectiveFrom,
      effectiveTo: rule.effectiveTo,
      createdBy: rule.createdBy,
      updatedBy: rule.updatedBy,
      tenantId: scope.tenantId,
      organizationId: scope.organizationId
    });
    em.persist(entry);
    seeded += 1;
  }
  if (seeded > 0 || updated > 0) {
    await em.flush();
    await invalidateBusinessRuleDiscoveryCache(cache, scope.tenantId, scope.organizationId);
  }
  return { seeded, skipped, updated };
}
async function seedExampleWorkflows(em, scope, options = {}) {
  await seedGuardRules(em, scope, "guard-rules-example.json", options.cache);
  await seedWorkflowDefinition(em, scope, "sales-pipeline-definition.json");
  await seedGuardRules(em, scope, "order-approval-guard-rules.json", options.cache);
}
export {
  seedExampleWorkflows
};
//# sourceMappingURL=seeds.js.map
