import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core';
import { IconButtonComponent } from '../icon-button/icon-button.component';
import { IconComponent } from '../icon/icon.component';

@Component({
  selector: 'nj-pagination',
  templateUrl: './pagination.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [IconComponent, IconButtonComponent, CommonModule]
})
export class PaginationComponent {
  /**
   * Text alternative for assistive technologies for previous button
   * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label
   */
  @Input() ariaLabelNext: string;

  /**
   * Text alternative for assistive technologies for next button
   * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label
   */
  @Input() ariaLabelPrevious: string;

  /**
   * Total number of pages
   */
  @Input() count: number;

  /**
   * Current page
   */
  @Input() currentItem: number = 1;

  /**
   * Whether pagination should minify
   */
  @Input() shouldMinify = true;

  /**
   * Emits selected item on change
   */
  @Output() selectedItem = new EventEmitter<number>();

  constructor(private cdr: ChangeDetectorRef) {}

  /**
   * @ignore
   */
  getItems() {
    return Array.from({ length: this.count }, (_, i) => i + 1);
  }

  /**
   * @ignore
   */
  goToNext() {
    if (this.currentItem === this.count) {
      return;
    }
    this.currentItem = this.currentItem + 1;
    this.selectedItem?.emit(this.currentItem);
    this.cdr.markForCheck();
  }

  /**
   * @ignore
   */
  goToPrevious() {
    if (this.currentItem === 1) {
      return;
    }
    this.currentItem = this.currentItem - 1;
    this.selectedItem?.emit(this.currentItem);
    this.cdr.markForCheck();
  }

  /**
   * @ignore
   */
  goToItem(item: number) {
    if (item > this.count || this.currentItem < 1) {
      return;
    }
    this.currentItem = item;
    this.selectedItem?.emit(this.currentItem);
    this.cdr.markForCheck();
  }

  /**
   * @ignore
   */
  isItemVisible(item: number): boolean {
    // Always show first, last and selected item
    if (item === 1 || item === this.count || item === this.currentItem) {
      return true;
    }
    // Always show previous and next values of selected value
    if (item >= this.currentItem - 1 && item <= this.currentItem + 1) {
      return true;
    }
    if (item < 6 && this.currentItem < 4) {
      return true;
    }
    return item >= this.count - 4 && this.currentItem >= this.count - 2;
  }

  /**
   * @ignore
   */
  showMoreHorizontal(item: number): boolean {
    // We want to show on 2nd item if currentItem > 3 or in penultimate if currentItem is in last 3
    return (item === 2 && this.currentItem > 3) || (item === this.count - 1 && this.currentItem <= this.count - 3);
  }
}
