// ─── Standardized Result Type ─────────────────────────────────────────────────
// Provides consistent error handling across the codebase.
// Use Result<T> for expected failures; reserve throw for truly unexpected errors.

/**
 * Error codes for categorizing failures.
 * Enables callers to programmatically handle specific error types.
 */
export const ErrorCode = {
  // Mana errors
  INSUFFICIENT_MANA: 'INSUFFICIENT_MANA',
  ELEMENT_NOT_UNLOCKED: 'ELEMENT_NOT_UNLOCKED',
  ELEMENT_MAX_CAPACITY: 'ELEMENT_MAX_CAPACITY',
  INVALID_ELEMENT: 'INVALID_ELEMENT',

  // Crafting errors
  INVALID_BLUEPRINT: 'INVALID_BLUEPRINT',
  BLUEPRINT_NOT_ACQUIRED: 'BLUEPRINT_NOT_ACQUIRED',
  MISSING_MATERIALS: 'MISSING_MATERIALS',
  INVALID_EQUIPMENT_TYPE: 'INVALID_EQUIPMENT_TYPE',
  INVALID_EFFECT: 'INVALID_EFFECT',
  EFFECT_NOT_ALLOWED: 'EFFECT_NOT_ALLOWED',
  STACKS_EXCEED_MAX: 'STACKS_EXCEED_MAX',
  INSUFFICIENT_CAPACITY: 'INSUFFICIENT_CAPACITY',
  EQUIPMENT_NOT_FOUND: 'EQUIPMENT_NOT_FOUND',
  DESIGN_NOT_FOUND: 'DESIGN_NOT_FOUND',
  EQUIPMENT_NOT_PREPARED: 'EQUIPMENT_NOT_PREPARED',
  ALREADY_PREPARED: 'ALREADY_PREPARED',

  // Action state errors
  INVALID_ACTION_STATE: 'INVALID_ACTION_STATE',

  // Prestige errors
  INSUFFICIENT_INSIGHT: 'INSUFFICIENT_INSIGHT',
  GUARDIAN_NOT_DEFEATED: 'GUARDIAN_NOT_DEFEATED',
  PACT_ALREADY_SIGNED: 'PACT_ALREADY_SIGNED',
  PACT_SLOTS_FULL: 'PACT_SLOTS_FULL',
  RITUAL_IN_PROGRESS: 'RITUAL_IN_PROGRESS',
  PRESTIGE_MAX_LEVEL: 'PRESTIGE_MAX_LEVEL',
  INVALID_PRESTIGE_ID: 'INVALID_PRESTIGE_ID',

  // General
  INVALID_INPUT: 'INVALID_INPUT',
  NOT_INITIALIZED: 'NOT_INITIALIZED',
} as const;

export type ErrorCodeType = (typeof ErrorCode)[keyof typeof ErrorCode];

/**
 * Standard result type for operations that can fail.
 * T is the success payload type.
 */
export type Result<T = void> =
  | { success: true; data: T }
  | { success: false; error: string; code: ErrorCodeType };

/** Create a success result. */
export function ok<T>(data: T): Result<T> {
  return { success: true, data };
}

/** Create a void success result. */
export function okVoid(): Result<void> {
  return { success: true, data: undefined };
}

/** Create a failure result. */
export function fail(code: ErrorCodeType, error: string): Result<never> {
  return { success: false, error, code };
}

/** Create a failure result with a typed data field. */
export function failTyped<T>(code: ErrorCodeType, error: string): Result<T> {
  return { success: false, error, code };
}

/**
 * Unwrap a result, returning the data or a default value.
 */
export function unwrapOr<T>(result: Result<T>, defaultValue: T): T {
  return result.success ? result.data : defaultValue;
}

/**
 * Check if a result is a failure with a specific error code.
 */
export function isErrorCode<T>(result: Result<T>, code: ErrorCodeType): boolean {
  return !result.success && result.code === code;
}
