import { CommonModule } from '@angular/common';
import {
  AfterContentInit,
  ChangeDetectionStrategy,
  Component,
  ContentChildren,
  EventEmitter,
  Input,
  Output,
  QueryList,
  ViewEncapsulation
} from '@angular/core';
import { Utils } from '../../utils/utils.util';
import { AvatarComponent } from '../avatar/avatar.component';
import { AvatarSize } from '../avatar/avatar.model';
import { TooltipOptions } from '../tooltip/tooltip.model';

@Component({
  selector: 'nj-avatar-list',
  templateUrl: './avatar-list.component.html',
  styleUrls: ['./avatar-list.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  standalone: true,
  imports: [AvatarComponent, CommonModule]
})
export class AvatarListComponent implements AfterContentInit {
  /**
   * @ignore
   */
  private readonly avatarListClassName = 'nj-avatar-list';

  /**
   * @ignore
   */
  remainingCount: number;

  /**
   * @ignore
   */
  avatarsToDisplay: AvatarComponent[];

  /**
   *  Max number of avatar displayed
   **/
  @Input() max?: number = 4;

  /**
   *  Density of the avatar list
   **/
  @Input() density?: 'default' | 'compact';

  /**
   *  Avatars size
   **/
  @Input() size?: AvatarSize = 'md';

  /**
   * Remaining avatar Tooltip's options
   **/
  @Input() remainingTooltipOptions?: TooltipOptions;

  /**
   * Emits event on remaining count avatar mouse click
   */
  @Output() remainingClick: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

  /**
   * Label of the "show more" button.
   *
   * A function can be used to provide a dynamic label based on the number of remaining avatars in the list.
   */
  @Input() showMoreLabel: string | ((elementCount: number) => string);

  /**
   * @ignore
   */
  @ContentChildren(AvatarComponent)
  avatars: QueryList<AvatarComponent>;

  constructor() {}

  ngAfterContentInit() {
    this.remainingCount = this.avatars?.toArray()?.length - this.max;
    this.avatarsToDisplay = this.getAvatarsToDisplay();
  }

  /**
   * @ignore
   */
  getAvatarsToDisplay(): AvatarComponent[] {
    const avatarsArray = this.avatars?.toArray();
    if (Utils.isUndefinedOrNull(avatarsArray)) {
      return;
    }
    return avatarsArray.splice(0, this.max).map((avatar) => {
      avatar.size = this.size;
      return avatar;
    });
  }

  /**
   * @ignore
   */
  getAvatarListDensityClass(): string {
    if (!this.density || this.density === 'default') {
      return '';
    }
    return `${this.avatarListClassName}--${this.density}`;
  }

  /**
   * @ignore
   */
  getRemainingCountInitials(): string {
    return `+ ${this.remainingCount}`;
  }

  /**
   * @ignore
   */
  getRemainingCountLabel(): string {
    return typeof this.showMoreLabel === 'function' ? this.showMoreLabel(this.remainingCount) : this.showMoreLabel;
  }
}
