// client-list.component.ts
import { Component, OnInit, OnDestroy, ViewChild, ChangeDetectorRef, AfterViewInit } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import { MatPaginator, MatPaginatorModule, PageEvent } from '@angular/material/paginator';
import { MatSort, MatSortModule, Sort } from '@angular/material/sort';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatExpansionModule } from '@angular/material/expansion';
import { CommonModule } from '@angular/common';
import { Observable, Subject, BehaviorSubject } from 'rxjs';
import { debounceTime, distinctUntilChanged, takeUntil, startWith } from 'rxjs/operators';
import { ClientListService, ClientDetail, ClientMachine, ClientRefiller } from './client-list.service';

@Component({
  selector: 'app-client-list',
  standalone: true,
  imports: [
    CommonModule,
    ReactiveFormsModule,
    MatTableModule,
    MatPaginatorModule,
    MatSortModule,
    MatProgressBarModule,
    MatFormFieldModule,
    MatInputModule,
    MatButtonModule,
    MatIconModule,
    MatTooltipModule,
    MatExpansionModule
  ],
  templateUrl: './client-list.component.html',
  styleUrl: './client-list.component.scss'
})
export class ClientListComponent implements OnInit, OnDestroy, AfterViewInit {
  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  // Observables
  clients$!: Observable<ClientDetail[]>;
  private _unsubscribeAll: Subject<any> = new Subject<any>();
  
  // Data
  dataSource = new MatTableDataSource<ClientDetail>();
  private _clients: BehaviorSubject<ClientDetail[]> = new BehaviorSubject<ClientDetail[]>([]);
  
  // UI State
  isLoading: boolean = false;
  selectedClient: ClientDetail | null = null;
  
  // Search
  searchInputControl: FormControl = new FormControl('');
  
  // Pagination
  pagination = {
    length: 0,
    page: 0,
    size: 10
  };

  constructor(
    private _clientListService: ClientListService,
    private _changeDetectorRef: ChangeDetectorRef
  ) {}

  ngOnInit(): void {
    this.clients$ = this._clients.asObservable();

    // Setup search
    this.searchInputControl.valueChanges
      .pipe(
        takeUntil(this._unsubscribeAll),
        debounceTime(300),
        distinctUntilChanged(),
        startWith('')
      )
      .subscribe(() => {
        this.filterClients();
      });

    // Load clients
    this.loadClients();
  }

  ngAfterViewInit(): void {
    if (this.paginator) {
      this.paginator.page
        .pipe(takeUntil(this._unsubscribeAll))
        .subscribe((page: PageEvent) => {
          this.pagination.page = page.pageIndex;
          this.pagination.size = page.pageSize;
          this.filterClients();
        });
    }

    if (this.sort) {
      this.sort.sortChange
        .pipe(takeUntil(this._unsubscribeAll))
        .subscribe((sort: Sort) => {
          this.sortClients(sort);
        });
    }
  }

  ngOnDestroy(): void {
    this._unsubscribeAll.next(null);
    this._unsubscribeAll.complete();
  }

  /**
   * Load all clients with their details
   */
  loadClients(): void {
    this.isLoading = true;

    this._clientListService.getClientsWithDetails()
      .pipe(takeUntil(this._unsubscribeAll))
      .subscribe(
        (clients: ClientDetail[]) => {
          console.log('Loaded clients:', clients);
          this._clients.next(clients);
          this.pagination.length = clients.length;
          this.isLoading = false;
          this.filterClients();
          this._changeDetectorRef.markForCheck();
        },
        (error) => {
          console.error('Error loading clients:', error);
          this.isLoading = false;
        }
      );
  }

  /**
   * Filter clients based on search
   */
  filterClients(): void {
    let filteredClients = this._clients.getValue();
    const searchTerm = this.searchInputControl.value?.toLowerCase() || '';

    if (searchTerm) {
      filteredClients = filteredClients.filter(client => 
        client.username.toLowerCase().includes(searchTerm) ||
        client.email.toLowerCase().includes(searchTerm) ||
        client.contact.includes(searchTerm) ||
        (client.user_id && client.user_id.toLowerCase().includes(searchTerm)) ||
        client.refillers.some(r => 
          r.username.toLowerCase().includes(searchTerm) ||
          r.email.toLowerCase().includes(searchTerm)
        )
      );
    }

    this.pagination.length = filteredClients.length;
    
    const start = this.pagination.page * this.pagination.size;
    const end = start + this.pagination.size;
    filteredClients = filteredClients.slice(start, end);

    this.dataSource.data = filteredClients;
    this._changeDetectorRef.markForCheck();
  }

  /**
   * Sort clients
   */
  sortClients(sort: Sort): void {
    const clients = this._clients.getValue().slice();
    
    if (!sort.active || sort.direction === '') {
      this._clients.next(clients);
      return;
    }

    const sortedClients = clients.sort((a, b) => {
      const isAsc = sort.direction === 'asc';
      switch (sort.active) {
        case 'user_id': return this.compare(a.user_id, b.user_id, isAsc);
        case 'username': return this.compare(a.username, b.username, isAsc);
        case 'email': return this.compare(a.email, b.email, isAsc);
        case 'contact': return this.compare(a.contact, b.contact, isAsc);
        case 'machines_count': return this.compare(a.machines_count, b.machines_count, isAsc);
        case 'refillers_count': return this.compare(a.refillers_count, b.refillers_count, isAsc);
        default: return 0;
      }
    });

    this._clients.next(sortedClients);
    this.filterClients();
  }

  private compare(a: string | number | undefined, b: string | number | undefined, isAsc: boolean): number {
    return (a! < b! ? -1 : 1) * (isAsc ? 1 : -1);
  }

  /**
   * Toggle client details
   */
  toggleDetails(clientId?: number): void {
    if (this.selectedClient && this.selectedClient.id === clientId) {
      this.closeDetails();
      return;
    }

    const client = this._clients.getValue().find(c => c.id === clientId);
    if (client) {
      this.selectedClient = { ...client };
      
      // Load fresh data for machines and refillers
      this.loadClientDetails(client.id);
      
      this._changeDetectorRef.markForCheck();
    }
  }

  /**
   * Load detailed information for a client
   */
  private loadClientDetails(clientId: number): void {
    // Load all machines and filter by client_id
    this._clientListService.getClientsWithDetails()
      .pipe(takeUntil(this._unsubscribeAll))
      .subscribe(
        (clients) => {
          const clientData = clients.find(c => c.id === clientId);
          if (clientData && this.selectedClient && this.selectedClient.id === clientId) {
            // Update machines
            this.selectedClient.machines = clientData.machines;
            this.selectedClient.machines_count = clientData.machines_count;
            
            // Update refillers
            this.selectedClient.refillers = clientData.refillers;
            this.selectedClient.refillers_count = clientData.refillers_count;
            
            this._changeDetectorRef.markForCheck();
          }
        },
        (error) => {
          console.error('Error loading client details:', error);
        }
      );
  }

  /**
   * Close details panel
   */
  closeDetails(): void {
    this.selectedClient = null;
    this._changeDetectorRef.markForCheck();
  }

  /**
   * Get full file URL
   */
  getFullFileUrl(path: string | undefined): string | null {
    return this._clientListService.getFullFileUrl(path);
  }

  /**
   * Track by function for ngFor
   */
  trackByFn(index: number, item: any): any {
    return item.id || index;
  }

  /**
   * Get status badge class
   */
  getStatusClass(status: string): string {
    switch (status.toLowerCase()) {
      case 'active':
      case 'online':
        return 'bg-green-100 text-green-800';
      case 'inactive':
      case 'offline':
        return 'bg-gray-100 text-gray-800';
      case 'maintenance':
        return 'bg-yellow-100 text-yellow-800';
      default:
        return 'bg-gray-100 text-gray-800';
    }
  }

  /**
   * Refresh data
   */
  refresh(): void {
    this.loadClients();
  }
}