import { SoundboardClip, SoundboardClipInfo } from './types';

/** Parallels custom-emoji/PackImageReader, for a soundboard clip. */
export class SoundboardClipReader {
  public readonly shortcode: string;

  public readonly url: string;

  private readonly clip: Omit<SoundboardClip, 'url'>;

  constructor(shortcode: string, url: string, clip: Omit<SoundboardClip, 'url'>) {
    this.shortcode = shortcode;
    this.url = url;
    this.clip = clip;
  }

  static fromClip(shortcode: string, clip: SoundboardClip): SoundboardClipReader | undefined {
    const { url } = clip;
    if (typeof url !== 'string' || !url.startsWith('mxc://')) return undefined;
    return new SoundboardClipReader(shortcode, url, clip);
  }

  get body(): string | undefined {
    const { body } = this.clip;
    return typeof body === 'string' ? body : undefined;
  }

  /** Display name — the clip body, falling back to the shortcode. */
  get name(): string {
    return this.body ?? this.shortcode;
  }

  get emoji(): string | undefined {
    const { emoji } = this.clip;
    return typeof emoji === 'string' && emoji.length > 0 ? emoji : undefined;
  }

  /** Per-clip volume 0–100; defaults to 100 when unset/invalid. */
  get volume(): number {
    const v = this.clip.volume;
    if (typeof v !== 'number' || Number.isNaN(v)) return 100;
    return Math.min(100, Math.max(0, v));
  }

  get info(): SoundboardClipInfo | undefined {
    return this.clip.info;
  }

  get content(): SoundboardClip {
    return {
      url: this.url,
      body: this.clip.body,
      emoji: this.clip.emoji,
      volume: this.clip.volume,
      info: this.clip.info,
    };
  }
}
