<section class="space-y-4">
  <div class="box custom-box !mb-0">
    <div class="box-header !items-start !gap-4 flex-col xl:flex-row xl:!items-center">
      <div class="min-w-0 me-auto">
        <h1 class="box-title !text-lg">{{ title() }}</h1>
        @if (subtitle()) { <p class="mt-1 text-sm text-textmuted dark:text-textmuted/80">{{ subtitle() }}</p> }
      </div>
      <div class="flex w-full flex-wrap items-center gap-2 xl:w-auto">
        <label class="relative min-w-[14rem] flex-1 xl:flex-none">
          <span class="sr-only">Search</span>
          <input #searchInput type="search" class="form-control !pe-9 xl:w-64" [placeholder]="searchPlaceholder()"
            (input)="onSearch(searchInput.value)" />
          <i class="ri-search-line absolute end-3 top-1/2 -translate-y-1/2 text-textmuted"></i>
        </label>
        @if (showFilters()) {
          <button type="button" class="ti-btn ti-btn-light !mb-0" [class.!border-primary]="filtersOpen()"
            [attr.aria-expanded]="filtersOpen()" (click)="filtersOpen.set(!filtersOpen())">
            <i class="ri-filter-3-line"></i><span>Filters</span>
          </button>
        }
        <div class="inline-flex rounded-md shadow-sm" role="group" aria-label="View">
          <button type="button" class="ti-btn !mb-0 !rounded-e-none" [class.ti-btn-primary-full]="view() === 'table'" [class.ti-btn-light]="view() !== 'table'" (click)="setView('table')" title="Table view"><i class="ri-list-check-2"></i><span class="hidden sm:inline">Table</span></button>
          <button type="button" class="ti-btn !mb-0 !rounded-none" [class.ti-btn-primary-full]="view() === 'tile'" [class.ti-btn-light]="view() !== 'tile'" (click)="setView('tile')" title="Tile view"><i class="ri-layout-grid-line"></i><span class="hidden sm:inline">Tile</span></button>
          <button type="button" class="ti-btn !mb-0 !rounded-s-none" [class.ti-btn-primary-full]="view() === 'detail'" [class.ti-btn-light]="view() !== 'detail'" (click)="setView('detail')" title="Detail view"><i class="ri-layout-row-line"></i><span class="hidden sm:inline">Detail</span></button>
        </div>
        <label class="flex items-center gap-2 text-sm"><span class="hidden sm:inline">Density</span>
          <select class="ti-form-select form-select-sm !w-auto" [value]="density()" (change)="setDensity($event)">
            <option value="compact">Compact</option><option value="comfortable">Comfortable</option><option value="spacious">Spacious</option>
          </select>
        </label>
        <button type="button" class="ti-btn ti-btn-primary-full !mb-0" (click)="addClicked.emit()"><i class="ri-add-line"></i>{{ addLabel() }}</button>
      </div>
    </div>
    @if (filtersOpen()) {
      <div class="box-body border-t border-defaultborder">
        <ng-content select="[dataListFilters]" />
        <div class="mt-4 flex justify-end gap-2">
          <button type="button" class="ti-btn ti-btn-light !mb-0" (click)="filtersCleared.emit()">Clear All</button>
          <button type="button" class="ti-btn ti-btn-primary-full !mb-0" (click)="filtersApplied.emit()">Apply Filters</button>
        </div>
      </div>
    }
  </div>

  <div class="box custom-box !mb-0">
    @if (loading()) {
      <div class="box-body flex min-h-48 flex-col items-center justify-center gap-3"><i class="ti ti-loader-2 animate-spin text-2xl"></i><span>Loading data...</span></div>
    } @else if (totalRecords() === 0) {
      <div class="box-body flex min-h-48 flex-col items-center justify-center text-center"><i class="ri-inbox-2-line mb-3 text-4xl text-textmuted"></i><h2 class="font-semibold">{{ emptyMessage() }}</h2><p class="mt-1 text-sm text-textmuted">{{ emptyDescription() }}</p></div>
    } @else {
      <div [class.hidden]="view() !== 'table'"><ng-content select="[dataListTable]" /></div>
      <div [class.hidden]="view() !== 'tile'" class="box-body"><div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4" [class]="'grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 ' + contentSpacingClass()"><ng-content select="[dataListTile]" /></div></div>
      <div [class.hidden]="view() !== 'detail'" class="box-body"><div class="grid grid-cols-1 lg:grid-cols-2 2xl:grid-cols-3" [class]="'grid grid-cols-1 lg:grid-cols-2 2xl:grid-cols-3 ' + contentSpacingClass()"><ng-content select="[dataListDetail]" /></div></div>
    }
    <div class="box-footer flex flex-col items-start justify-between gap-3 sm:flex-row sm:items-center">
      <div class="flex flex-wrap items-center gap-3 text-sm"><span>Showing <b>{{ startRecord() }}</b> to <b>{{ endRecord() }}</b> of <b>{{ totalRecords() }}</b> entries</span>
        <label class="flex items-center gap-2">Show <select class="ti-form-select form-select-sm !w-[4.75rem]" [value]="pageSize()" (change)="onPageSizeChange($event)">@for (size of pageSizeOptions(); track size) { <option [value]="size">{{ size }}</option> }</select></label>
      </div>
      <nav aria-label="Pagination" class="pagination-style-4"><ul class="ti-pagination mb-0">
        <li class="page-item" [class.disabled]="pageIndex() <= 1"><button type="button" class="page-link" [disabled]="pageIndex() <= 1" (click)="goToPage(pageIndex() - 1)"><i class="ri-arrow-left-s-line"></i></button></li>
        @for (page of visiblePages(); track page) { <li class="page-item"><button type="button" class="page-link" [class.active]="page === pageIndex()" (click)="goToPage(page)">{{ page }}</button></li> }
        <li class="page-item" [class.disabled]="pageIndex() >= totalPages()"><button type="button" class="page-link" [disabled]="pageIndex() >= totalPages()" (click)="goToPage(pageIndex() + 1)"><i class="ri-arrow-right-s-line"></i></button></li>
      </ul></nav>
    </div>
  </div>
</section>
