function toVar(name) {
  return name.charAt(0).toLowerCase() + name.slice(1);
}
function toMethod(words) {
  return words.trim().replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/^\w/, (c) => c.toLowerCase());
}
function resolveValue(rawValue, ctx) {
  const value = rawValue.trim().replace(/^['"]|['"]$/g, "");
  if (/^(current\s*time|now|timestamp)$/i.test(value)) {
    return "new Date().toISOString()";
  }
  if (value === "true" || value === "false") return value;
  if (/^-?\d+(\.\d+)?$/.test(value)) return value;
  const declared = ctx.declaredVars || /* @__PURE__ */ new Set();
  const params = ctx.parameterNames || [];
  const rootMatch = value.match(/^([a-zA-Z_][a-zA-Z0-9_]*)(\.[a-zA-Z0-9_.]+)?$/);
  if (rootMatch) {
    const root = rootMatch[1];
    if (declared.has(root) || params.includes(root)) {
      return value;
    }
  }
  const tokens = value.toLowerCase().split(/\s+/);
  for (const declaredName of [...declared, ...params]) {
    const normalized = declaredName.toLowerCase();
    if (tokens.includes(normalized)) return declaredName;
  }
  const calcMatch = value.match(/^(?:the\s+|calculated\s+|computed\s+|resulting\s+)(\w+)/i);
  if (calcMatch) {
    const field = calcMatch[1];
    const stepResults = [...declared].filter((v) => /^step\d+Result$/.test(v)).sort().reverse();
    if (stepResults.length > 0) {
      return `(${stepResults[0]} as any).${field} /* TODO: verify field name */`;
    }
  }
  if (/\s/.test(value)) {
    return `/* TODO: resolve "${value}" \u2014 no matching declared variable */ null`;
  }
  return `'${value.replace(/'/g, "\\'")}'`;
}
const STEP_CONVENTIONS = [
  // --- Validation ---
  {
    name: "validate",
    pattern: /^validate\s+(.+)/i,
    generateCall: (m, ctx) => `    // Step ${ctx.stepNum}: Validate ${m[1]}
    // TODO: Add validation logic for ${m[1]}
    }`
  },
  // --- Check / Guard ---
  {
    name: "check",
    pattern: /^check\s+(.+)/i,
    generateCall: (m, ctx) => {
      const condition = m[1];
      const methodName = toMethod("check " + condition);
      return `    // Step ${ctx.stepNum}: Check ${condition}
    // TODO: Implement check \u2014 ${condition}
    // const checkResult = ...
    // if (!checkResult) throw new Error('Check failed: ${condition}');`;
    }
  },
  // --- Find / Lookup ---
  {
    name: "find",
    pattern: /^find\s+(\w+)\s+by\s+(\w+)/i,
    generateCall: (m, ctx) => {
      const model = m[1];
      const field = m[2];
      const modelVar = toVar(model);
      const params = ctx.parameterNames || [];
      const declared = ctx.declaredVars || /* @__PURE__ */ new Set();
      const idParam = field === "id" ? params.find((p) => p === `${modelVar}Id`) || params.find((p) => p === "id") || `${modelVar}Id` : params.find((p) => p === field) || `params.${field}`;
      if (declared.has(modelVar)) {
        return `    // Step ${ctx.stepNum}: Find ${model} by ${field} (already loaded)`;
      }
      declared.add(modelVar);
      return `    // Step ${ctx.stepNum}: Find ${model} by ${field}
    const ${modelVar} = await prisma.${modelVar}.findUniqueOrThrow({ where: { ${field}: ${idParam} } });`;
    }
  },
  // --- Create ---
  {
    name: "create",
    pattern: /^create\s+(\w+)(?:\s+(?:with\s+)?(.+))?/i,
    generateCall: (m, ctx) => {
      const model = m[1];
      const modelVar = toVar(model);
      const paramNames = ctx.parameterNames || [];
      const dataFields = paramNames.length > 0 ? `{ ${paramNames.join(", ")} }` : "data";
      return `    // Step ${ctx.stepNum}: Create ${model}
    const ${modelVar} = await prisma.${modelVar}.create({ data: ${dataFields} });`;
    }
  },
  // --- Update field ---
  {
    name: "update-field",
    pattern: /^update\s+(\w+)\s+(\w+)\s+to\s+(.+)/i,
    generateCall: (m, ctx) => {
      const model = m[1];
      const field = m[2];
      const rawValue = m[3];
      const modelVar = toVar(model);
      const val = resolveValue(rawValue, ctx);
      return `    // Step ${ctx.stepNum}: Update ${model} ${field} to ${rawValue.trim()}
    await prisma.${modelVar}.update({
      where: { id: ${modelVar}.id },
      data: { ${field}: ${val} },
    });`;
    }
  },
  // --- Generic update ---
  {
    name: "update",
    pattern: /^update\s+(\w+)(?:\s+(.+))?/i,
    generateCall: (m, ctx) => {
      const model = m[1];
      const modelVar = toVar(model);
      return `    // Step ${ctx.stepNum}: Update ${model}
    await prisma.${modelVar}.update({
      where: { id: ${modelVar}.id },
      data: params,
    });`;
    }
  },
  // --- Delete ---
  {
    name: "delete",
    pattern: /^delete\s+(\w+)/i,
    generateCall: (m, ctx) => {
      const model = m[1];
      const modelVar = toVar(model);
      return `    // Step ${ctx.stepNum}: Delete ${model}
    await prisma.${modelVar}.delete({ where: { id: ${modelVar}.id } });`;
    }
  },
  // --- Transition / Evolve ---
  {
    name: "transition",
    pattern: /^transition\s+(\w+)\s+to\s+(\w+)/i,
    generateCall: (m, ctx) => {
      const model = m[1];
      const state = m[2];
      const modelVar = toVar(model);
      return `    // Step ${ctx.stepNum}: Transition ${model} to ${state}
    if (${modelVar}.status === '${state}') throw new Error('${model} is already ${state}');
    await prisma.${modelVar}.update({
      where: { id: ${modelVar}.id },
      data: { status: '${state}' },
    });`;
    }
  },
  // --- Set field ---
  {
    name: "set",
    pattern: /^set\s+(\w+)\s+to\s+(.+)/i,
    generateCall: (m, ctx) => {
      const field = m[1];
      const rawValue = m[2];
      const modelVar = toVar(ctx.prismaModel);
      const val = resolveValue(rawValue, ctx);
      return `    // Step ${ctx.stepNum}: Set ${field} to ${rawValue.trim()}
    await prisma.${modelVar}.update({
      where: { id: ${modelVar}.id },
      data: { ${field}: ${val} },
    });`;
    }
  },
  // --- Increment ---
  {
    name: "increment",
    pattern: /^increment\s+(\w+)\s+by\s+(\w+)/i,
    generateCall: (m, ctx) => {
      const field = m[1];
      const amount = m[2];
      const modelVar = toVar(ctx.prismaModel);
      const amountVal = /^\d+$/.test(amount) ? amount : amount;
      return `    // Step ${ctx.stepNum}: Increment ${field} by ${amount}
    await prisma.${modelVar}.update({
      where: { id: ${modelVar}.id },
      data: { ${field}: { increment: ${amountVal} } },
    });`;
    }
  },
  // --- Decrement ---
  {
    name: "decrement",
    pattern: /^decrement\s+(\w+)\s+by\s+(\w+)/i,
    generateCall: (m, ctx) => {
      const field = m[1];
      const amount = m[2];
      const modelVar = toVar(ctx.prismaModel);
      const amountVal = /^\d+$/.test(amount) ? amount : amount;
      return `    // Step ${ctx.stepNum}: Decrement ${field} by ${amount}
    await prisma.${modelVar}.update({
      where: { id: ${modelVar}.id },
      data: { ${field}: { decrement: ${amountVal} } },
    });`;
    }
  },
  // NOTE: "calculate X" is intentionally NOT a convention — it falls through to AI
  // behaviors because calculations are domain-specific pure functions that benefit
  // from AI generation with the full input context.
  // --- Send event ---
  {
    name: "send-event",
    pattern: /^(?:send|emit|publish)\s+(\w+)\s+event/i,
    generateCall: (m, ctx) => {
      const event = m[1];
      return `    // Step ${ctx.stepNum}: Emit ${event} event
    await eventBus.publish('${event}', { ${toVar(ctx.prismaModel)}Id: ${toVar(ctx.prismaModel)}.id, operation: '${ctx.operationName}', timestamp: new Date().toISOString() });`;
    }
  },
  // --- Send notification ---
  {
    name: "send-notification",
    pattern: /^send\s+(\w+)\s+notification/i,
    generateCall: (m, ctx) => {
      const type = m[1];
      return `    // Step ${ctx.stepNum}: Send ${type} notification
    await eventBus.publish('${type}Notification', { ${toVar(ctx.prismaModel)}Id: ${toVar(ctx.prismaModel)}.id, operation: '${ctx.operationName}' });`;
    }
  },
  // --- Call service ---
  {
    name: "call-service",
    pattern: /^call\s+(\w+)\.(\w+)/i,
    generateCall: (m, ctx) => {
      const service = m[1];
      const method = m[2];
      return `    // Step ${ctx.stepNum}: Call ${service}.${method}
    await ${toVar(service)}.${method}({ ${(ctx.parameterNames || []).join(", ")} });`;
    }
  },
  // --- Return ---
  {
    name: "return",
    pattern: /^return\s+(.+)/i,
    generateCall: (m, ctx) => {
      const value = m[1].trim();
      const isModel = /^(updated|created|the)\s+/i.test(value) || value === ctx.modelName;
      if (isModel) {
        return `    // Step ${ctx.stepNum}: Return result
    return ${toVar(ctx.prismaModel)};`;
      }
      return `    // Step ${ctx.stepNum}: Return ${value}
    return ${value};`;
    }
  }
];
function matchStep(step, ctx) {
  for (const convention of STEP_CONVENTIONS) {
    const match = step.match(convention.pattern);
    if (match) {
      return {
        call: convention.generateCall(match, ctx),
        helperMethod: convention.generateMethod?.(match, ctx),
        matched: true
      };
    }
  }
  const functionName = toMethod(step);
  const declared = Array.from(ctx.declaredVars || []);
  const paramNames = ctx.parameterNames || [];
  const inputs = [...paramNames, ...declared];
  const resultVar = ctx.resultName || `step${ctx.stepNum}Result`;
  const inputObj = inputs.length > 0 ? `{ ${inputs.join(", ")} }` : "{}";
  if (ctx.declaredVars) ctx.declaredVars.add(resultVar);
  return {
    call: `    // Step ${ctx.stepNum}: ${step} [AI-generated \u2014 pure function]
    const ${resultVar} = await aiBehaviors.${functionName}(${inputObj});`,
    matched: false,
    functionName,
    inputs,
    resultVar
  };
}
export {
  STEP_CONVENTIONS,
  matchStep
};
