import { Component, computed, input, output, signal, TemplateRef, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { TableModule } from 'primeng/table';
import { ButtonModule } from 'primeng/button';
import { ProgressSpinnerModule } from 'primeng/progressspinner';
import { MenuModule } from 'primeng/menu';
import { DialogModule } from 'primeng/dialog';
import { CheckboxModule } from 'primeng/checkbox';
import { TooltipModule } from 'primeng/tooltip';
import { ExportService, ExportColumn } from '../../../core/services/export.service';

export interface TableColumn {
  field: string;
  header: string;
  sortable?: boolean;
  exportable?: boolean;
  /** Custom transform for export */
  exportTransform?: (value: any, row: any) => string;
}

@Component({
  selector: 'app-data-table',
  standalone: true,
  imports: [CommonModule, FormsModule, TranslateModule, TableModule, ButtonModule, ProgressSpinnerModule, MenuModule, DialogModule, CheckboxModule, TooltipModule],
  template: `
    @if (loading() && !lazy()) {
      <div class="loading-state">
        <p-progressSpinner strokeWidth="3" />
        <p>{{ 'COMMON.LOADING' | translate }}</p>
      </div>
    } @else if (error()) {
      <div class="error-state">
        <i class="pi pi-exclamation-triangle"></i>
        <p>{{ error() }}</p>
        <p-button
          [label]="'COMMON.RETRY' | translate"
          icon="pi pi-refresh"
          (onClick)="retry.emit()"
          severity="secondary"
        />
      </div>
    } @else {
      <div class="table-card">
        <!-- Top toolbar: filters + export buttons -->
        <div class="table-toolbar">
          @if (filtersTpl()) {
            <div class="toolbar-filters">
              <ng-container *ngTemplateOutlet="filtersTpl()!" />
            </div>
          }
          @if (exportable()) {
            <div class="toolbar-actions">
              <p-button
                icon="pi pi-file-excel"
                [pTooltip]="'COMMON.EXPORT_EXCEL' | translate"
                tooltipPosition="bottom"
                severity="success"
                [outlined]="true"
                [rounded]="true"
                size="small"
                (onClick)="onExportExcel()"
              />
              <p-button
                icon="pi pi-file-pdf"
                [pTooltip]="'COMMON.EXPORT_PDF' | translate"
                tooltipPosition="bottom"
                severity="danger"
                [outlined]="true"
                [rounded]="true"
                size="small"
                (onClick)="onExportPdf()"
              />
              <p-button
                icon="pi pi-sliders-h"
                [pTooltip]="'COMMON.CUSTOMIZE_COLUMNS' | translate"
                tooltipPosition="bottom"
                severity="secondary"
                [outlined]="true"
                [rounded]="true"
                size="small"
                (onClick)="columnDialogVisible.set(true)"
              />
            </div>
          }
        </div>

        <p-table
          [value]="filteredData() ?? data()"
          [paginator]="true"
          [rows]="rows()"
          [rowsPerPageOptions]="rowsPerPageOptions()"
          [showCurrentPageReport]="true"
          currentPageReportTemplate="{first} - {last} {{ 'COMMON.OF' | translate }} {totalRecords}"
          [globalFilterFields]="globalFilterFields()"
          styleClass="p-datatable-sm"
          [lazy]="lazy()"
          (onLazyLoad)="onLazyLoad.emit($event)"
          [totalRecords]="totalRecords()"
          [loading]="loading()"
          [first]="first()"
          [sortField]="sortField()"
          [sortOrder]="sortOrder()"
        >
          <ng-template #header>
            <tr>
              @for (col of visibleColumns(); track col.field) {
                @if (col.sortable) {
                  <th [pSortableColumn]="col.field">{{ col.header | translate }} <p-sortIcon [field]="col.field" /></th>
                } @else {
                  <th>{{ col.header | translate }}</th>
                }
              }
            </tr>
          </ng-template>
          <ng-template #body let-item>
            <ng-container [ngTemplateOutlet]="$any(bodyTpl())" [ngTemplateOutletContext]="{ $implicit: item }" />
          </ng-template>
          <ng-template #emptymessage>
            <tr>
              <td [attr.colspan]="effectiveColSpan()" class="text-center">{{ emptyMessageKey() | translate }}</td>
            </tr>
          </ng-template>
        </p-table>
      </div>

      <!-- Column Customization Dialog -->
      <p-dialog
        [header]="'COMMON.CUSTOMIZE_COLUMNS' | translate"
        [(visible)]="columnDialogVisible"
        [modal]="true"
        [style]="{ width: '400px' }"
      >
        <div class="column-list">
          @for (col of columns(); track col.field) {
            <div class="column-item">
              <p-checkbox
                [binary]="true"
                [(ngModel)]="columnVisibility[col.field]"
                [inputId]="'col-' + col.field"
              />
              <label [for]="'col-' + col.field" class="column-label">{{ col.header | translate }}</label>
            </div>
          }
        </div>
        <ng-template #footer>
          <p-button
            [label]="'COMMON.SELECT_ALL' | translate"
            icon="pi pi-check-square"
            severity="secondary"
            [outlined]="true"
            size="small"
            (onClick)="selectAllColumns()"
          />
          <p-button
            [label]="'COMMON.CLOSE' | translate"
            icon="pi pi-times"
            severity="secondary"
            size="small"
            (onClick)="columnDialogVisible.set(false)"
          />
        </ng-template>
      </p-dialog>
    }
  `,
  styles: [`
    .table-toolbar {
      display: flex;
      align-items: stretch;
      gap: 0;
      padding: 0.5rem 0;
    }
    .toolbar-filters { flex: 1; min-width: 0; }
    .toolbar-filters ::ng-deep .filter-bar {
      margin-bottom: 0;
      border-start-start-radius: 8px;
      border-end-start-radius: 8px;
      border-start-end-radius: 0;
      border-end-end-radius: 0;
      border-inline-end: none;
    }
    .toolbar-actions {
      display: flex;
      align-items: center;
      gap: 0.35rem;
      flex-shrink: 0;
      padding: 0 0.75rem;
      background: var(--p-surface-card);
      border: 1px solid var(--p-surface-border);
      border-inline-start: none;
      border-start-end-radius: 8px;
      border-end-end-radius: 8px;
    }
    .column-list { display: flex; flex-direction: column; gap: 0.75rem; }
    .column-item { display: flex; align-items: center; gap: 0.5rem; }
    .column-label { font-size: 0.85rem; cursor: pointer; }
  `],
})
export class DataTableComponent {
  private exportService = inject(ExportService);
  private translate = inject(TranslateService);

  // Data
  data = input<any[]>([]);
  loading = input(false);
  error = input<string | null>(null);
  filteredData = input<any[] | null>(null);

  // Server-side pagination
  lazy = input(false);
  totalRecords = input(0);
  first = input(0);
  onLazyLoad = output<any>();

  // Columns (data-driven header)
  columns = input<TableColumn[]>([]);

  // Export
  exportable = input(true);
  exportFilename = input('export');
  exportTitle = input('');

  // Common
  rows = input(25);
  rowsPerPageOptions = input([10, 25, 50, 100]);
  emptyMessageKey = input('COMMON.NO_DATA');
  globalFilterFields = input<string[]>([]);
  colSpan = input(0);
  sortField = input<string>('');
  sortOrder = input<number>(1);

  effectiveColSpan = computed(() => this.colSpan() || this.visibleColumns().length || 7);

  retry = output<void>();

  // Templates
  bodyTpl = input<TemplateRef<any>>();
  filtersTpl = input<TemplateRef<any>>();

  // Column visibility
  columnVisibility: Record<string, boolean> = {};
  columnDialogVisible = signal(false);

  visibleColumns = computed(() => {
    const cols = this.columns();
    // Initialize visibility for any new columns
    for (const col of cols) {
      if (!(col.field in this.columnVisibility)) {
        this.columnVisibility[col.field] = true;
      }
    }
    return cols.filter(c => this.columnVisibility[c.field] !== false);
  });

  selectAllColumns(): void {
    for (const col of this.columns()) {
      this.columnVisibility[col.field] = true;
    }
  }

  onExportExcel(): void {
    const exportCols = this.getExportColumns();
    const exportData = this.filteredData() ?? this.data();
    this.exportService.exportExcel(exportData, exportCols, this.exportFilename());
  }

  onExportPdf(): void {
    const exportCols = this.getExportColumns();
    const exportData = this.filteredData() ?? this.data();
    this.exportService.exportPdf(exportData, exportCols, this.exportFilename(), this.exportTitle());
  }

  private getExportColumns(): ExportColumn[] {
    return this.visibleColumns()
      .filter(c => c.exportable !== false)
      .map(c => ({
        field: c.field,
        header: c.header,
        transform: c.exportTransform,
      }));
  }
}
