import { Result } from "../Result";

/**
 * Mutation Contract
 *
 * Purpose: Framework-agnostic write operations
 *
 * Architecture:
 * - Server Action constructs Mutation
 * - Mutation constructs Service
 * - Service creates own dependencies (API Client, Logger, ErrorReporter)
 * - Service returns Result<void, DomainError>
 * - Mutation maps DomainError → MutationError
 * - Mutation returns Result<void, MutationError>
 * - No HTTP/API calls directly
 * - No 'use client' directive
 * - No 'use server' directive
 * - Must be in lib/mutations/
 * - Must be named *Mutation
 * - Can be called from Server Actions
 * - Single responsibility: ONE operation per mutation
 *
 * Pattern:
 * Server Action → Mutation → Service → API Client
 *
 * Example:
 * ```typescript
 * export class UpdateUserStatusMutation implements Mutation<UpdateUserStatusInput, void> {
 *   async execute(input: UpdateUserStatusInput): Promise<Result<void, MutationError>> {
 *     const service = new UserService();
 *     const result = await service.updateUserStatus(input.userId, input.status);
 *
 *     if (result.isErr()) {
 *       return Result.err(mapToMutationError(result.error));
 *     }
 *
 *     return Result.ok(undefined);
 *   }
 * }
 * ```
 *
 * Design Principle:
 * Each mutation does ONE thing. If you need multiple operations,
 * create multiple mutation classes (e.g., UpdateUserStatusMutation, DeleteUserMutation).
 * This follows the same pattern as Page Queries.
 *
 * @template TInput - The input type for the mutation
 * @template TOutput - The output type on success
 * @template TError - The error type (default: string for backward compatibility)
 */

export interface Mutation<TInput = void, TOutput = void, TError = string> {
  /**
   * Execute the mutation
   *
   * Manual construction pattern:
   * ```typescript
   * const service = new MyService();
   * const result = await service.doWrite(input);
   * if (result.isErr()) {
   *   return Result.err(mapToMutationError(result.error));
   * }
   * return Result.ok(undefined);
   * ```
   *
   * @param input - Mutation input
   * @returns Promise<Result<TOutput, TError>>
   */
  execute(input: TInput): Promise<Result<TOutput, TError>>;
}