function generatePrismaService(context) {
  const { model, controller, spec, implType } = context;
  if (!model) {
    throw new Error("Model is required in template context");
  }
  const modelName = model.name;
  const serviceName = `${modelName}Service`;
  const prismaModel = modelName.charAt(0).toLowerCase() + modelName.slice(1);
  const imports = generateImports(modelName, implType);
  const methods = generateCRUDEMethods(modelName, prismaModel, model, implType);
  const validateMethod = generateValidationMethod(modelName, model, implType);
  return `${imports}

/**
 * ${serviceName}
 * Generated service for ${modelName} model
 *
 * Provides CURED operations (Create, Retrieve, Update, Evolve, Delete)
 * with Prisma ORM integration
 */
export class ${serviceName} {
  constructor(private prisma: PrismaClient) {}

${methods}

${validateMethod}
}
`;
}
function generateImports(modelName, implType) {
  const imports = [
    `import { PrismaClient, ${modelName} } from '@prisma/client';`
  ];
  return imports.join("\n");
}
function generateCRUDEMethods(modelName, prismaModel, model, implType) {
  const methods = [];
  methods.push(generateCreateMethod(modelName, prismaModel, model));
  methods.push(generateRetrieveMethod(modelName, prismaModel, model));
  methods.push(generateUpdateMethod(modelName, prismaModel, model));
  methods.push(generateEvolveMethod(modelName, prismaModel, model));
  methods.push(generateDeleteMethod(modelName, prismaModel, model));
  methods.push(generateListMethod(modelName, prismaModel, model));
  return methods.join("\n\n");
}
function generateCreateMethod(modelName, prismaModel, model) {
  return `  /**
   * Create a new ${modelName}
   */
  async create(data: Omit<${modelName}, 'id' | 'createdAt' | 'updatedAt'>): Promise<${modelName}> {
    // Validate before creating
    const validationResult = this.validate(data, { operation: 'create' });
    if (!validationResult.valid) {
      throw new Error(\`Validation failed: \${validationResult.errors.join(', ')}\`);
    }

    return await this.prisma.${prismaModel}.create({
      data: data as any
    });
  }`;
}
function generateRetrieveMethod(modelName, prismaModel, model) {
  return `  /**
   * Retrieve a ${modelName} by ID
   */
  async retrieve(id: string): Promise<${modelName} | null> {
    return await this.prisma.${prismaModel}.findUnique({
      where: { id }
    });
  }`;
}
function generateUpdateMethod(modelName, prismaModel, model) {
  return `  /**
   * Update a ${modelName}
   */
  async update(id: string, data: Partial<${modelName}>): Promise<${modelName}> {
    // Validate before updating
    const validationResult = this.validate(data, { operation: 'update' });
    if (!validationResult.valid) {
      throw new Error(\`Validation failed: \${validationResult.errors.join(', ')}\`);
    }

    return await this.prisma.${prismaModel}.update({
      where: { id },
      data: data as any
    });
  }`;
}
function generateEvolveMethod(modelName, prismaModel, model) {
  const hasLifecycle = model.lifecycle && model.lifecycle.length > 0;
  if (hasLifecycle) {
    return `  /**
   * Evolve a ${modelName} (lifecycle-aware update)
   * Handles state transitions according to lifecycle rules
   */
  async evolve(id: string, data: Partial<${modelName}>): Promise<${modelName}> {
    // Get current instance to check state
    const current = await this.retrieve(id);
    if (!current) {
      throw new Error('${modelName} not found');
    }

    // Validate state transition if status is being changed
    if (data.status && data.status !== current.status) {
      // TODO: Add lifecycle validation based on model.lifecycle
      // For now, allow any transition
    }

    // Validate data
    const validationResult = this.validate(data, { operation: 'evolve' });
    if (!validationResult.valid) {
      throw new Error(\`Validation failed: \${validationResult.errors.join(', ')}\`);
    }

    return await this.prisma.${prismaModel}.update({
      where: { id },
      data: data as any
    });
  }`;
  } else {
    return `  /**
   * Evolve a ${modelName} (same as update for models without lifecycle)
   */
  async evolve(id: string, data: Partial<${modelName}>): Promise<${modelName}> {
    return this.update(id, data);
  }`;
  }
}
function generateDeleteMethod(modelName, prismaModel, model) {
  const hasSoftDelete = model.metadata?.softDelete;
  if (hasSoftDelete) {
    return `  /**
   * Delete a ${modelName} (soft delete)
   */
  async delete(id: string): Promise<void> {
    await this.prisma.${prismaModel}.update({
      where: { id },
      data: {
        deletedAt: new Date(),
        isDeleted: true
      }
    });
  }`;
  } else {
    return `  /**
   * Delete a ${modelName}
   */
  async delete(id: string): Promise<void> {
    await this.prisma.${prismaModel}.delete({
      where: { id }
    });
  }`;
  }
}
function generateListMethod(modelName, prismaModel, model) {
  const hasSoftDelete = model.metadata?.softDelete;
  const whereClause = hasSoftDelete ? `
      where: { isDeleted: false },` : "";
  return `  /**
   * List all ${modelName}s
   */
  async list(): Promise<${modelName}[]> {
    return await this.prisma.${prismaModel}.findMany({${whereClause}
      orderBy: { createdAt: 'desc' }
    });
  }`;
}
function generateValidationMethod(modelName, model, implType) {
  return `  /**
   * Validate ${modelName} data
   * Unified validation method for all operations
   */
  validate(
    data: any,
    context: { operation: 'create' | 'update' | 'evolve' }
  ): { valid: boolean; errors: string[] } {
    const errors: string[] = [];

    // Required field validation (for create operation)
    if (context.operation === 'create') {
      ${generateRequiredFieldValidation(model)}
    }

    // Type validation
    ${generateTypeValidation(model)}

    // Constraint validation
    ${generateConstraintValidation(model)}

    return {
      valid: errors.length === 0,
      errors
    };
  }`;
}
function generateRequiredFieldValidation(model) {
  const requiredFields = model.attributes?.filter(
    (attr) => attr.constraints?.required && !["id", "createdAt", "updatedAt"].includes(attr.name)
  ) || [];
  if (requiredFields.length === 0) {
    return "// No required fields";
  }
  const validations = requiredFields.map(
    (field) => `if (data.${field.name} === undefined || data.${field.name} === null) {
        errors.push('${field.name} is required');
      }`
  ).join("\n      ");
  return validations;
}
function generateTypeValidation(model) {
  const fields = model.attributes || [];
  if (fields.length === 0) {
    return "// No type validation";
  }
  const validations = fields.filter((field) => !["id", "createdAt", "updatedAt"].includes(field.name)).map((field) => {
    const typeName = inferJsType(field.type);
    if (typeName === "string" || typeName === "number" || typeName === "boolean") {
      return `if (data.${field.name} !== undefined && typeof data.${field.name} !== '${typeName}') {
        errors.push('${field.name} must be a ${typeName}');
      }`;
    }
    return "";
  }).filter((v) => v).join("\n    ");
  return validations || "// No type validation needed";
}
function generateConstraintValidation(model) {
  const fields = model.attributes?.filter(
    (attr) => attr.constraints && Object.keys(attr.constraints).length > 0
  ) || [];
  if (fields.length === 0) {
    return "// No constraint validation";
  }
  const validations = fields.map((field) => {
    const constraints = [];
    if (field.constraints.unique) {
      constraints.push(`// TODO: Check uniqueness of ${field.name}`);
    }
    if (field.constraints.min !== void 0) {
      constraints.push(
        `if (data.${field.name} !== undefined && data.${field.name} < ${field.constraints.min}) {
        errors.push('${field.name} must be at least ${field.constraints.min}');
      }`
      );
    }
    if (field.constraints.max !== void 0) {
      constraints.push(
        `if (data.${field.name} !== undefined && data.${field.name} > ${field.constraints.max}) {
        errors.push('${field.name} must be at most ${field.constraints.max}');
      }`
      );
    }
    return constraints.join("\n    ");
  }).filter((v) => v).join("\n    ");
  return validations || "// No constraint validation needed";
}
function inferJsType(type) {
  const typeLower = type.toLowerCase();
  if (typeLower.includes("string") || typeLower.includes("text")) return "string";
  if (typeLower.includes("int") || typeLower.includes("number")) return "number";
  if (typeLower.includes("bool")) return "boolean";
  if (typeLower.includes("date")) return "object";
  return "any";
}
export {
  generatePrismaService as default
};
