import { LiveAnnouncer } from '@angular/cdk/a11y';
import {
  ChangeDetectorRef,
  Component,
  Input,
  OnInit,
  SimpleChanges,
  ViewChild,
} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, Sort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { tap } from 'rxjs/operators';
import { EventService } from 'src/app/core/services/event.service';
import { DataService } from 'src/app/core/services/data.service';
import { ToastService } from 'src/app/services/toast.service';
import { VueDetailComponent } from 'src/app/components/vue-detail/projets/vue-detail.component';

import { ProjectsStore } from 'src/app/stores/projects.store';
import { Tab } from 'src/app/models/tab';
@Component({
  selector: 'app-table-vue-details',
  templateUrl: './table-vue-details.component.html',
  styleUrls: ['./table-vue-details.component.scss'],
})
export class TableVueDetailsComponent implements OnInit {
  @Input() displayedColumns!: string[];
  @Input() relatedTo!: string;
  @Input() from!: any;
  public isLoadingDetails = false;
  public currentTab: any;


  @Input() typeTabs!: string;
  @Input() dataSource = new MatTableDataSource<any>();
  @ViewChild(MatSort)
  sort: MatSort = new MatSort();
  @ViewChild(MatPaginator)
  paginator!: MatPaginator;
  private levelContextuel!: any;
  constructor(
    private changeDetectorRefs: ChangeDetectorRef,
    private _liveAnnouncer: LiveAnnouncer,
    private dataService: DataService,
    public dialog: MatDialog,
    private toast: ToastService,
    public projectStore: ProjectsStore,
    private contextuel: EventService,
  ) {
    
  }

  ngOnInit(): void {
    this.projectStore
    .select('currentTab')
    .pipe(
      tap((res: any) => {
        this.currentTab = res
      })
    )
    .subscribe();
    this.changeDetectorRefs.detectChanges();
    this.contextuel.level$.subscribe((number_contextuel) => {
      this.levelContextuel = number_contextuel;
      // console.log('niumber', number_contextuel);
    });

    // Debug: Logs pour analyser le mapping métadonnées/données
    console.log('🔍 TableVueDetails DEBUG:');
    console.log('displayedColumns (transformés):', this.displayedColumns);
    console.log('dataSource:', this.dataSource);
    console.log('typeTabs:', this.typeTabs);
  }

  ngOnChanges(changes: SimpleChanges) {
    if (this.dataSource !== undefined) {
      this.dataSource.data = this.dataSource as any;
      this.dataSource.sort = this.sort;
      this.dataSource.paginator = this.paginator;
      
      // Debug: Comparaison des colonnes vs clés réelles des données
      console.log('📊 ngOnChanges - Colonnes transformées:', this.displayedColumns);
      if (this.dataSource?.data && this.dataSource.data.length > 0) {
        console.log('📊 Premier élément de données:', this.dataSource.data[0]);
        console.log('📊 Clés réelles des données:', Object.keys(this.dataSource.data[0]));
        
        // Analyser le mapping
        console.log('🔍 Analyse du mapping:');
        if (this.displayedColumns) {
          this.displayedColumns.forEach(col => {
            const hasKey = this.dataSource.data[0].hasOwnProperty(col);
            console.log(`  "${col}" → ${hasKey ? '✅ EXISTE' : '❌ MANQUE'}`);
          });
        }
      }
    } else {
      this.dataSource = this.dataSource as any;
    }
  }

  details(data?: any) {
    // Incrémenter le niveau AVANT d'ouvrir le dialog
    this.contextuel.incrementLevel();
    const newLevel = this.contextuel.getCurrentLevel();
    console.log('📊 table-vue-details incrémente niveau:', newLevel);

    // Calculer la config cascade
    const cascadeConfig = this.getCascadeDialogConfig(newLevel);

    data['from'] = this.from;
    // res.record['id'] = this.relatedTo;
    // res.record['tt'] = this.typeTabs
    const dialogRef = this.dialog.open(VueDetailComponent, {
      data: data,
      ...cascadeConfig
    });

    // Décrémenter le niveau après fermeture du dialog
    dialogRef.afterClosed().subscribe(() => {
      this.contextuel.decrementLevel();
      console.log('📊 table-vue-details décrémente niveau:', this.contextuel.getCurrentLevel());
    });
  }

  /**
   * Calcule la configuration du dialog pour l'effet cascade
   */
  private getCascadeDialogConfig(currentLevel: number): any {
    const baseWidth = 69;
    const widthReduction = 3;

    const maxWidth = `${baseWidth - (widthReduction * currentLevel)}vw`;
    const position = { right: '0px' }; // Toujours fixé à droite

    console.log(`🎨 Cascade niveau ${currentLevel}: maxWidth=${maxWidth}`);

    return {
      maxWidth,
      position,
      panelClass: ['animate__animated', 'animate__slideInRight', `cascade-level-${currentLevel}`]
    };
  }

  /**
   * Vérifie si une valeur est une référence navigable (objet avec id/uuid et name)
   */
  isReferenceValue(value: any): boolean {
    return value && typeof value === 'object' && !Array.isArray(value)
      && (value.id || value.uuid) && value.name;
  }

  /**
   * Ouvre la vue détail d'un élément référencé
   */
  openReferenceDetail(value: any, column: string): void {
    if (!value || typeof value !== 'object') return;

    const refModule = column;

    this.contextuel.incrementLevel();
    const newLevel = this.contextuel.getCurrentLevel();
    const cascadeConfig = this.getCascadeDialogConfig(newLevel);

    const refData = {
      ...value,
      contextParent: refModule,
      from: refModule
    };

    const dialogRef = this.dialog.open(VueDetailComponent, {
      data: refData,
      ...cascadeConfig
    });

    dialogRef.afterClosed().subscribe(() => {
      this.contextuel.decrementLevel();
    });
  }

  isValidDate(date: any): boolean {
    return !isNaN(Date.parse(date));
  }

  ngAfterViewInit() {
    if (this.dataSource != undefined) {
      this.dataSource.sort = this.sort;
      setTimeout(() => {
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
        this.dataSource.sortingDataAccessor = (item: any, property: any) => {
          // property = this.sortBy;
          switch (property) {
            case 'project_name': {
              let newDate = new Date(item['Created At']);

              return newDate;
            }

            case 'Date engagement operation': {
              let newDate = new Date(item['Date engagement operation']);
             // console.log(newDate);
              return newDate;
            }
            default: {
              return item[property];
            }
          }
        };
      }, 2500);
    }
  }

  /** Announce the change in sort state for assistive technology. */
  announceSortChange(sortState: Sort) {
    // This example uses English messages. If your application supports
    // multiple language, you would internationalize these strings.
    // Furthermore, you can customize the message to add additional
    // details about the values being sorted.
    if (sortState.direction) {
      this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`);
    } else {
      this._liveAnnouncer.announce('Sorting cleared');
    }
  }

  /**
   * Vérifie si une valeur est un objet (et pas null ou un array)
   */
  isObject(value: any): boolean {
    return value !== null && typeof value === 'object' && !Array.isArray(value);
  }

  /**
   * Retourne l'affichage approprié pour un objet contextuel
   */
  getObjectDisplay(obj: any): string {
    if (!obj) return '';
    
    // Si l'objet a une propriété name, l'utiliser
    if (obj.name) return obj.name;
    
    // Si l'objet a une propriété label, l'utiliser
    if (obj.label) return obj.label;
    
    // Si l'objet a une propriété title, l'utiliser
    if (obj.title) return obj.title;
    
    // Si l'objet a une propriété value, l'utiliser
    if (obj.value !== undefined) return obj.value.toString();
    
    // Si l'objet est un objet complexe avec des propriétés mais pas de nom
    const keys = Object.keys(obj);
    if (keys.length > 0) {
      // Essayer d'afficher la première propriété string non-null
      for (const key of keys) {
        if (typeof obj[key] === 'string' && obj[key].trim() !== '') {
          return obj[key];
        }
      }
      // Sinon, afficher une représentation simple
      return `{${keys.length} propriété${keys.length > 1 ? 's' : ''}}`;
    }
    
    // Fallback pour les objets vides ou non gérés
    return JSON.stringify(obj);
  }

  /**
   * Méthodes de détection des types de colonnes
   * Adaptées pour les noms transformés par transformField()
   */
  isDateColumn(column: string): boolean {
    const col = column.toLowerCase();
    return col.includes('date') || col.includes('created') || col.includes('updated');
  }

  isVolumeColumn(column: string): boolean {
    const col = column.toLowerCase();
    return col.includes('volume');
  }

  isPriceColumn(column: string): boolean {
    const col = column.toLowerCase();
    return col.includes('prix') || col.includes('price');
  }

  isAmountColumn(column: string): boolean {
    const col = column.toLowerCase();
    return col.includes('montant') || col.includes('amount');
  }

  isTotalColumn(column: string): boolean {
    const col = column.toLowerCase();
    return col.includes('total') || col.includes('total_en');
  }

  isPositionValueColumn(column: string): boolean {
    const col = column.toLowerCase();
    return col.includes('valeur') && col.includes('position');
  }

  isOperationNameColumn(column: string): boolean {
    const col = column.toLowerCase();
    return col.includes('nom') && col.includes('operation');
  }

  /**
   * Vérifie si la colonne contient des objets contextuels
   */
  isContextualObjectColumn(column: string): boolean {
    return !this.isDateColumn(column) && 
           !this.isVolumeColumn(column) && 
           !this.isPriceColumn(column) && 
           !this.isAmountColumn(column) && 
           !this.isTotalColumn(column) && 
           !this.isPositionValueColumn(column) && 
           !this.isOperationNameColumn(column);
  }

  /**
   * Nouvelles méthodes pour le design amélioré
   */
  getColumnDisplayName(column: string): string {
    const columnNames: { [key: string]: string } = {
      'name': 'Nom',
      'firstname': 'Prénom',
      'lastname': 'Nom de famille',
      'email': 'Email',
      'phone': 'Téléphone',
      'mobile': 'Mobile',
      'description': 'Description',
      'montant': 'Montant',
      'statut': 'Statut',
      'reference': 'Référence',
      'created_at': 'Créé le',
      'updated_at': 'Modifié le',
      'date_de_reception': 'Date de réception',
      'sens': 'Sens',
      'compte': 'Compte',
      'frais_operation': 'Frais',
      'transaction_no': 'N° Transaction'
    };

    return columnNames[column] || this.formatColumnName(column);
  }

  private formatColumnName(column: string): string {
    return column
      .replace(/_/g, ' ')
      .replace(/\b\w/g, l => l.toUpperCase());
  }

  getCellTooltip(row: any, column: string): string {
    const value = row[column];
    
    if (!value && value !== 0) {
      return '';
    }

    if (this.isObject(value)) {
      return JSON.stringify(value, null, 2);
    }

    return String(value);
  }

  getCellClass(column: string): string {
    const classes = ['text-ellipsis'];
    
    if (this.isAmountColumn(column) || this.isPriceColumn(column) || this.isTotalColumn(column)) {
      classes.push('amount-cell');
    } else if (this.isDateColumn(column)) {
      classes.push('date-cell');
    } else if (column === 'statut' || column === 'status') {
      classes.push('status-cell');
    } else if (column === 'email') {
      classes.push('email-cell');
    } else if (column === 'phone' || column === 'mobile') {
      classes.push('phone-cell');
    }
    
    return classes.join(' ');
  }

  getStatusClass(status: string): string {
    const statusMap: { [key: string]: string } = {
      'actif': 'status-success',
      'active': 'status-success', 
      'validé': 'status-success',
      'completed': 'status-success',
      'inactif': 'status-danger',
      'inactive': 'status-danger',
      'bloqué': 'status-danger',
      'blocked': 'status-danger',
      'en_attente': 'status-warning',
      'pending': 'status-warning',
      'brouillon': 'status-info',
      'draft': 'status-info'
    };
    
    return statusMap[status?.toLowerCase()] || 'status-default';
  }

  getFormattedCellValue(row: any, column: string): string {
    const value = row[column];
    
    if (!value && value !== 0) {
      return '-';
    }

    // Formatage des dates
    if (this.isDateColumn(column) && this.isValidDate(value)) {
      return new Date(value).toLocaleDateString('fr-FR');
    }

    // Formatage des montants
    if (this.isAmountColumn(column) || this.isPriceColumn(column) || this.isTotalColumn(column)) {
      const numValue = parseFloat(value);
      if (!isNaN(numValue)) {
        return new Intl.NumberFormat('fr-FR', {
          style: 'currency',
          currency: 'EUR',
          minimumFractionDigits: 2
        }).format(numValue);
      }
    }

    // Formatage des volumes
    if (this.isVolumeColumn(column)) {
      const numValue = parseFloat(value);
      if (!isNaN(numValue)) {
        return new Intl.NumberFormat('fr-FR', {
          minimumFractionDigits: 0,
          maximumFractionDigits: 3
        }).format(numValue);
      }
    }

    // Gestion des objets
    if (this.isObject(value)) {
      return this.getObjectDisplay(value);
    }

    // Limitation de longueur avec ellipsis
    const stringValue = String(value);
    const maxLength = this.getMaxLengthForColumn(column);
    
    if (stringValue.length > maxLength) {
      return stringValue.substring(0, maxLength) + '...';
    }

    return stringValue;
  }

  private getMaxLengthForColumn(column: string): number {
    if (column === 'description') return 50;
    if (column === 'name' || column === 'firstname' || column === 'lastname') return 25;
    if (column === 'email') return 30;
    return 40;
  }
}
