import type { ApplicationError, CommonApplicationErrorKind } from '@core/shared/errors';

export abstract class RacingApplicationError
  extends Error
  implements ApplicationError<CommonApplicationErrorKind | string, unknown>
{
  readonly type = 'application' as const;
  readonly context = 'racing-application';
  abstract readonly kind: CommonApplicationErrorKind | string;

  constructor(message: string) {
    super(message);
    Object.setPrototypeOf(this, new.target.prototype);
  }
}

export type RacingEntityType =
  | 'race'
  | 'league'
  | 'team'
  | 'season'
  | 'sponsorship'
  | 'sponsorshipRequest'
  | 'driver'
  | 'membership'
  | 'sponsor'
  | 'protest';

export interface EntityNotFoundDetails {
  entity: RacingEntityType;
  id: string;
}

export class EntityNotFoundError
  extends RacingApplicationError
  implements ApplicationError<'not_found', EntityNotFoundDetails>
{
  readonly kind = 'not_found' as const;
  readonly details: EntityNotFoundDetails;

  constructor(details: EntityNotFoundDetails) {
    super(`${details.entity} not found for id: ${details.id}`);
    this.details = details;
  }
}

export type PermissionDeniedReason =
  | 'NOT_LEAGUE_ADMIN'
  | 'NOT_LEAGUE_OWNER'
  | 'NOT_TEAM_OWNER'
  | 'NOT_ACTIVE_MEMBER'
  | 'NOT_MEMBER'
  | 'TEAM_OWNER_CANNOT_LEAVE'
  | 'UNAUTHORIZED';

export class PermissionDeniedError
  extends RacingApplicationError
  implements ApplicationError<'forbidden', PermissionDeniedReason>
{
  readonly kind = 'forbidden' as const;

  constructor(public readonly reason: PermissionDeniedReason, message?: string) {
    super(message ?? `Permission denied: ${reason}`);
  }

  get details(): PermissionDeniedReason {
    return this.reason;
  }
}

export class BusinessRuleViolationError
  extends RacingApplicationError
  implements ApplicationError<'conflict', undefined>
{
  readonly kind = 'conflict' as const;

  constructor(message: string) {
    super(message);
  }
}