/**
 * @copyright 2026 NHCarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */

import { Component, Input, Output, EventEmitter, computed } from '@angular/core';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-pagination',
  standalone: true,
  imports: [CommonModule],
  template: `
    <nav class="pagination-container" aria-label="Pagination">
      <div class="pagination-info" role="status" aria-live="polite">
        Showing {{ startItem() }} - {{ endItem() }} of {{ totalItems }} items
      </div>

      <div class="pagination-controls" role="navigation" aria-label="Page navigation">
        <button
          (click)="onPageChange(1)"
          [disabled]="currentPage === 1"
          class="btn btn-sm pagination-btn"
          aria-label="Go to first page"
          type="button"
        >
          <span aria-hidden="true">⟪</span>
        </button>

        <button
          (click)="onPageChange(currentPage - 1)"
          [disabled]="currentPage === 1"
          class="btn btn-sm pagination-btn"
          aria-label="Go to previous page"
          type="button"
        >
          <span aria-hidden="true">←</span>
        </button>

        <div class="page-numbers" role="group" aria-label="Page numbers">
          @for (page of pageNumbers(); track page) {
            @if (page === '...') {
              <span class="page-ellipsis" aria-hidden="true">{{ page }}</span>
            } @else {
              <button
                (click)="onPageChange(+page)"
                [class.active]="currentPage === +page"
                [attr.aria-current]="currentPage === +page ? 'page' : null"
                [attr.aria-label]="'Go to page ' + page"
                class="btn btn-sm pagination-btn page-number"
                type="button"
              >
                {{ page }}
              </button>
            }
          }
        </div>

        <button
          (click)="onPageChange(currentPage + 1)"
          [disabled]="currentPage === totalPages()"
          class="btn btn-sm pagination-btn"
          aria-label="Go to next page"
          type="button"
        >
          <span aria-hidden="true">→</span>
        </button>

        <button
          (click)="onPageChange(totalPages())"
          [disabled]="currentPage === totalPages()"
          class="btn btn-sm pagination-btn"
          aria-label="Go to last page"
          type="button"
        >
          <span aria-hidden="true">⟫</span>
        </button>
      </div>

      <div class="page-size-selector">
        <label for="page-size">Items per page:</label>
        <select
          id="page-size"
          [value]="pageSize"
          (change)="onPageSizeChange($event)"
          class="page-size-select"
          aria-label="Select number of items per page"
        >
          <option value="10">10</option>
          <option value="25">25</option>
          <option value="50">50</option>
          <option value="100">100</option>
        </select>
      </div>
    </nav>
  `,
  styles: [`
    .pagination-container {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 1rem 0;
      flex-wrap: wrap;
      gap: 1rem;
    }

    .pagination-info {
      color: var(--witch-plum);
      font-size: 0.9rem;
    }

    .pagination-controls {
      display: flex;
      align-items: center;
      gap: 0.5rem;
    }

    .pagination-btn {
      padding: 0.25rem 0.75rem;
      border: 1px solid var(--witch-lavender);
      background: var(--witch-moon);
      color: var(--witch-purple);
      border-radius: 4px;
      cursor: pointer;
      transition: all 0.2s;
      min-width: 2.5rem;
    }

    .pagination-btn:hover:not(:disabled) {
      background: var(--witch-lavender);
      border-color: var(--witch-mauve);
      transform: translateY(-1px);
    }

    .pagination-btn:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }

    .pagination-btn.active {
      background: #8b6f47;
      color: white;
      border-color: #8b6f47;
    }

    .page-numbers {
      display: flex;
      align-items: center;
      gap: 0.25rem;
    }

    .page-number {
      min-width: 2.5rem;
    }

    .page-ellipsis {
      padding: 0 0.5rem;
      color: var(--witch-mauve);
    }

    .page-size-selector {
      display: flex;
      align-items: center;
      gap: 0.5rem;
    }

    .page-size-selector label {
      font-size: 0.9rem;
      color: var(--witch-plum);
    }

    .page-size-select {
      padding: 0.25rem 0.5rem;
      border: 2px solid var(--witch-lavender);
      border-radius: 4px;
      background: var(--witch-moon);
      color: var(--witch-purple);
      cursor: pointer;
      transition: border-color 0.2s;
    }

    .page-size-select:hover {
      border-color: var(--witch-mauve);
    }

    .page-size-select:focus {
      outline: none;
      border-color: var(--witch-rose);
      box-shadow: 0 0 0 3px rgba(168, 87, 126, 0.2);
    }

    @media (max-width: 768px) {
      .pagination-container {
        justify-content: center;
      }

      .pagination-controls {
        order: 2;
        width: 100%;
        justify-content: center;
      }

      .pagination-info {
        order: 1;
        width: 100%;
        text-align: center;
      }

      .page-size-selector {
        order: 3;
        width: 100%;
        justify-content: center;
      }
    }
  `]
})
export class PaginationComponent {
  @Input() currentPage = 1;
  @Input() pageSize = 25;
  @Input() totalItems = 0;
  @Output() pageChange = new EventEmitter<number>();
  @Output() pageSizeChange = new EventEmitter<number>();

  totalPages = computed(() => Math.ceil(this.totalItems / this.pageSize));

  startItem = computed(() => {
    if (this.totalItems === 0) return 0;
    return (this.currentPage - 1) * this.pageSize + 1;
  });

  endItem = computed(() => {
    return Math.min(this.currentPage * this.pageSize, this.totalItems);
  });

  pageNumbers = computed(() => {
    const total = this.totalPages();
    const current = this.currentPage;
    const pages: (number | string)[] = [];

    if (total <= 7) {
      // Show all pages if 7 or fewer
      for (let i = 1; i <= total; i++) {
        pages.push(i);
      }
    } else {
      // Always show first page
      pages.push(1);

      if (current <= 3) {
        // Near the beginning
        for (let i = 2; i <= 5; i++) {
          pages.push(i);
        }
        pages.push('...');
        pages.push(total);
      } else if (current >= total - 2) {
        // Near the end
        pages.push('...');
        for (let i = total - 4; i <= total; i++) {
          pages.push(i);
        }
      } else {
        // In the middle
        pages.push('...');
        pages.push(current - 1);
        pages.push(current);
        pages.push(current + 1);
        pages.push('...');
        pages.push(total);
      }
    }

    return pages;
  });

  onPageChange(page: number) {
    if (page >= 1 && page <= this.totalPages() && page !== this.currentPage) {
      this.pageChange.emit(page);
    }
  }

  onPageSizeChange(event: Event) {
    const target = event.target as HTMLSelectElement;
    const newSize = parseInt(target.value, 10);
    this.pageSizeChange.emit(newSize);
  }
}