/**
 * ApiKey Entity
 *
 * Represents a programmatic API key for an organization.
 * Only GOLD and PLATINIUM subscribers can create and use API keys.
 *
 * Security model:
 * - The raw key is NEVER persisted — only its SHA-256 hash is stored.
 * - The full key is returned exactly once, at creation time.
 * - The keyPrefix (first 16 chars) is stored for display purposes.
 */

export interface ApiKeyProps {
  readonly id: string;
  readonly organizationId: string;
  readonly userId: string;
  readonly name: string;
  readonly keyHash: string;
  readonly keyPrefix: string;
  readonly isActive: boolean;
  readonly lastUsedAt: Date | null;
  readonly expiresAt: Date | null;
  readonly createdAt: Date;
  readonly updatedAt: Date;
}

export class ApiKey {
  private readonly props: ApiKeyProps;

  private constructor(props: ApiKeyProps) {
    this.props = props;
  }

  static create(params: {
    id: string;
    organizationId: string;
    userId: string;
    name: string;
    keyHash: string;
    keyPrefix: string;
    expiresAt?: Date | null;
  }): ApiKey {
    const now = new Date();
    return new ApiKey({
      id: params.id,
      organizationId: params.organizationId,
      userId: params.userId,
      name: params.name,
      keyHash: params.keyHash,
      keyPrefix: params.keyPrefix,
      isActive: true,
      lastUsedAt: null,
      expiresAt: params.expiresAt ?? null,
      createdAt: now,
      updatedAt: now,
    });
  }

  static fromPersistence(props: ApiKeyProps): ApiKey {
    return new ApiKey(props);
  }

  get id(): string {
    return this.props.id;
  }

  get organizationId(): string {
    return this.props.organizationId;
  }

  get userId(): string {
    return this.props.userId;
  }

  get name(): string {
    return this.props.name;
  }

  get keyHash(): string {
    return this.props.keyHash;
  }

  get keyPrefix(): string {
    return this.props.keyPrefix;
  }

  get isActive(): boolean {
    return this.props.isActive;
  }

  get lastUsedAt(): Date | null {
    return this.props.lastUsedAt;
  }

  get expiresAt(): Date | null {
    return this.props.expiresAt;
  }

  get createdAt(): Date {
    return this.props.createdAt;
  }

  get updatedAt(): Date {
    return this.props.updatedAt;
  }

  isExpired(): boolean {
    if (!this.props.expiresAt) return false;
    return this.props.expiresAt < new Date();
  }

  isValid(): boolean {
    return this.props.isActive && !this.isExpired();
  }

  revoke(): ApiKey {
    return new ApiKey({
      ...this.props,
      isActive: false,
      updatedAt: new Date(),
    });
  }

  recordUsage(): ApiKey {
    return new ApiKey({
      ...this.props,
      lastUsedAt: new Date(),
      updatedAt: new Date(),
    });
  }

  toObject(): ApiKeyProps {
    return { ...this.props };
  }
}
