import { Component, DestroyRef, computed, inject, input, output, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { Subject, debounceTime, distinctUntilChanged } from 'rxjs';

export type DataListView = 'table' | 'tile' | 'detail';
export type DataListDensity = 'compact' | 'comfortable' | 'spacious';

@Component({
  selector: 'app-data-list',
  standalone: true,
  templateUrl: './data-list.html'
})
export class DataList {
  private readonly destroyRef = inject(DestroyRef);
  private readonly searchTerms$ = new Subject<string>();

  readonly title = input.required<string>();
  readonly subtitle = input('');
  readonly addLabel = input('Add');
  readonly searchPlaceholder = input('Search...');
  readonly totalRecords = input(0);
  readonly pageIndex = input(1);
  readonly pageSize = input(10);
  readonly pageSizeOptions = input<readonly number[]>([5, 10, 20, 50]);
  readonly loading = input(false);
  readonly emptyMessage = input('No records found.');
  readonly emptyDescription = input('Try changing your search or filters.');
  readonly showFilters = input(true);

  readonly searchChanged = output<string>();
  readonly addClicked = output<void>();
  readonly pageChanged = output<{ pageIndex: number; pageSize: number }>();
  readonly filtersCleared = output<void>();
  readonly filtersApplied = output<void>();

  readonly view = signal<DataListView>('table');
  readonly density = signal<DataListDensity>('comfortable');
  readonly filtersOpen = signal(false);
  readonly totalPages = computed(() => Math.max(1, Math.ceil(this.totalRecords() / this.pageSize())));
  readonly startRecord = computed(() => this.totalRecords() ? (this.pageIndex() - 1) * this.pageSize() + 1 : 0);
  readonly endRecord = computed(() => Math.min(this.pageIndex() * this.pageSize(), this.totalRecords()));
  readonly visiblePages = computed(() => {
    const total = this.totalPages();
    const current = this.pageIndex();
    const start = Math.max(1, Math.min(current - 2, total - 4));
    return Array.from({ length: Math.min(5, total) }, (_, index) => start + index);
  });
  readonly contentSpacingClass = computed(() => ({
    compact: 'gap-3', comfortable: 'gap-4', spacious: 'gap-6'
  })[this.density()]);
  readonly cardPaddingClass = computed(() => ({
    compact: 'p-3', comfortable: 'p-4', spacious: 'p-6'
  })[this.density()]);

  constructor() {
    this.searchTerms$.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      takeUntilDestroyed(this.destroyRef)
    ).subscribe(value => this.searchChanged.emit(value));
  }

  setView(view: DataListView): void { this.view.set(view); }
  setDensity(event: Event): void { this.density.set((event.target as HTMLSelectElement).value as DataListDensity); }
  onSearch(value: string): void { this.searchTerms$.next(value.trim()); }
  goToPage(page: number): void {
    if (page >= 1 && page <= this.totalPages() && page !== this.pageIndex()) {
      this.pageChanged.emit({ pageIndex: page - 1, pageSize: this.pageSize() });
    }
  }
  onPageSizeChange(event: Event): void {
    const pageSize = Number((event.target as HTMLSelectElement).value);
    if (pageSize && pageSize !== this.pageSize()) this.pageChanged.emit({ pageIndex: 0, pageSize });
  }
}
