import {
  Component,
  Input,
  Output,
  EventEmitter,
  OnInit,
  HostListener,
  TemplateRef,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'ccl-pagination',
  standalone: true,
  imports: [CommonModule, FormsModule],
  templateUrl: './pagination.html',
  styleUrls: ['./pagination.css'],
})
export class PaginationComponent implements OnInit {
  @Input() currentPage = 1;
  @Input() totalPages?: number; // optional for load-more / infinite
  @Input() totalItems?: number; // for detailed mode/range display
  @Input() pageSize: number = 10;
  @Input() pageSizeOptions: number[] = [10, 25, 50, 100];
  @Input() variant: 'numbers' | 'load-more' | 'infinite-scroll' | 'detailed' = 'numbers';
  @Input() showFirstLast = false;
  // Optional custom templates for previous/next buttons
  @Input() prevButtonTemplate?: TemplateRef<unknown>;
  @Input() nextButtonTemplate?: TemplateRef<unknown>;

  @Output() pageChange = new EventEmitter<number>();
  @Output() pageSizeChange = new EventEmitter<number>();

  ngOnInit() {
    const total = this.totalPagesResolved;
    if (total && this.currentPage > total) {
      this.currentPage = total;
    }
  }

  goToPage(page: number) {
    const total = this.totalPagesResolved;
    if (page < 1 || (total && page > total)) return;
    this.currentPage = page;
    this.pageChange.emit(this.currentPage);
  }

  nextPage() {
    this.goToPage(this.currentPage + 1);
  }

  prevPage() {
    this.goToPage(this.currentPage - 1);
  }

  loadMore() {
    this.goToPage(this.currentPage + 1);
  }

  // Infinite scroll detection
  @HostListener('window:scroll', [])
  onScroll() {
    if (this.variant === 'infinite-scroll') {
      const threshold = 300; // px from bottom
      if (
        window.innerHeight + window.scrollY >=
        document.body.offsetHeight - threshold
      ) {
        this.loadMore();
      }
    }
  }

  get pages(): number[] {
    if (!this.totalPagesResolved) return [];
    // collapse large sets → simple for now
    return Array.from({ length: this.totalPagesResolved }, (_, i) => i + 1);
  }

  get totalPagesResolved(): number | undefined {
    if (this.totalPages != null) return this.totalPages;
    if (this.totalItems != null && this.pageSize) {
      return Math.max(1, Math.ceil(this.totalItems / this.pageSize));
    }
    return undefined;
  }

  get rangeStart(): number | undefined {
    if (this.totalItems == null) return undefined;
    return (this.currentPage - 1) * this.pageSize + 1;
  }

  get rangeEnd(): number | undefined {
    if (this.totalItems == null) return undefined;
    const end = this.currentPage * this.pageSize;
    return Math.min(this.totalItems, end);
  }

  onPageSizeChange(newSize: number) {
    const parsed = Number(newSize);
    if (!parsed || parsed === this.pageSize) return;
    this.pageSize = parsed;
    this.pageSizeChange.emit(this.pageSize);
    // Reset to first page when page size changes
    this.goToPage(1);
  }
}
