/**
 * Domain Exceptions
 *
 * Custom exception classes for the MPC service.
 */

import { HttpException, HttpStatus } from '@nestjs/common';

/**
 * Domain layer exception (no HTTP awareness)
 */
export class DomainError extends Error {
  constructor(message: string) {
    super(message);
    this.name = 'DomainError';
    Object.setPrototypeOf(this, DomainError.prototype);
  }
}

/**
 * Application layer exception
 */
export class ApplicationError extends Error {
  constructor(
    message: string,
    public readonly code?: string,
  ) {
    super(message);
    this.name = 'ApplicationError';
    Object.setPrototypeOf(this, ApplicationError.prototype);
  }
}

/**
 * HTTP layer business exception
 */
export class BusinessException extends HttpException {
  constructor(
    message: string,
    public readonly code?: string,
    status: HttpStatus = HttpStatus.BAD_REQUEST,
  ) {
    super(
      {
        success: false,
        message,
        code,
      },
      status,
    );
  }
}

/**
 * Not found exception
 */
export class NotFoundException extends BusinessException {
  constructor(resource: string, id?: string) {
    super(
      id ? `${resource} with ID ${id} not found` : `${resource} not found`,
      'NOT_FOUND',
      HttpStatus.NOT_FOUND,
    );
  }
}

/**
 * Unauthorized exception
 */
export class UnauthorizedException extends BusinessException {
  constructor(message: string = 'Unauthorized') {
    super(message, 'UNAUTHORIZED', HttpStatus.UNAUTHORIZED);
  }
}

/**
 * Forbidden exception
 */
export class ForbiddenException extends BusinessException {
  constructor(message: string = 'Forbidden') {
    super(message, 'FORBIDDEN', HttpStatus.FORBIDDEN);
  }
}

/**
 * Conflict exception (for duplicate resources)
 */
export class ConflictException extends BusinessException {
  constructor(message: string) {
    super(message, 'CONFLICT', HttpStatus.CONFLICT);
  }
}

/**
 * Validation exception
 */
export class ValidationException extends BusinessException {
  constructor(
    message: string,
    public readonly errors?: Record<string, string[]>,
  ) {
    super(message, 'VALIDATION_ERROR', HttpStatus.BAD_REQUEST);
  }
}

/**
 * MPC-specific exceptions
 */
export class MPCSessionError extends ApplicationError {
  constructor(message: string, code?: string) {
    super(message, code || 'MPC_SESSION_ERROR');
    this.name = 'MPCSessionError';
  }
}

export class ShareNotFoundError extends ApplicationError {
  constructor(shareId?: string) {
    super(
      shareId ? `Share ${shareId} not found` : 'Share not found',
      'SHARE_NOT_FOUND',
    );
    this.name = 'ShareNotFoundError';
  }
}

export class ShareNotActiveError extends ApplicationError {
  constructor(status: string) {
    super(`Share is not active: ${status}`, 'SHARE_NOT_ACTIVE');
    this.name = 'ShareNotActiveError';
  }
}

export class KeygenFailedError extends ApplicationError {
  constructor(reason: string) {
    super(`Keygen failed: ${reason}`, 'KEYGEN_FAILED');
    this.name = 'KeygenFailedError';
  }
}

export class SigningFailedError extends ApplicationError {
  constructor(reason: string) {
    super(`Signing failed: ${reason}`, 'SIGNING_FAILED');
    this.name = 'SigningFailedError';
  }
}

export class DecryptionFailedError extends ApplicationError {
  constructor() {
    super('Failed to decrypt share data', 'DECRYPTION_FAILED');
    this.name = 'DecryptionFailedError';
  }
}
