import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
import { CommonModule, DatePipe, CurrencyPipe } from '@angular/common';
import { Subject, takeUntil, catchError, of } from 'rxjs';

import { FinesService } from '../../fines.service';
import { Fines } from '../../fines.interface';
import { 
  FinesListConfig, 
  FinesListState, 
  FilterTab, 
  OrganizationType,
  ORGANIZATION_TYPE_MAP,
  FILTER_TAB_LABELS
} from './fines-list.interface';

/**
 * 🎯 FinesListComponent - Componente Reutilizável de Lista de Multas
 * 
 * Componente flexível que pode ser usado em diferentes contextos:
 * - Lista geral de multas
 * - Multas de um veículo específico  
 * - Multas de um motorista específico
 * - Integração em dashboards
 * 
 * ✨ Funcionalidades:
 * - Filtros por tipo de organização (Municipal, Estadual, Federal)
 * - Paginação integrada
 * - Ordenação por colunas
 * - Estados de loading, erro e vazio
 * - Responsivo e acessível
 * - Sistema global de status
 */
@Component({
  selector: 'app-fines-list',
  standalone: true,
  imports: [CommonModule],
  providers: [DatePipe, CurrencyPipe],
  templateUrl: './fines-list.component.html',
  styleUrl: './fines-list.component.scss'
})
export class FinesListComponent implements OnInit, OnDestroy {
  
  // ========================================
  // 🔧 INPUTS E OUTPUTS
  // ========================================
  
  @Input() config: FinesListConfig = {
    showNewButton: true,
    showFilters: true,
    readonly: false,
    pageSize: 10,
    maxHeight: '600px'
  };

  @Output() fineSelected = new EventEmitter<Fines>();
  @Output() newFineRequested = new EventEmitter<{ vehicleId?: number; driverId?: number }>();
  @Output() filterChanged = new EventEmitter<OrganizationType>();

  // ========================================
  // 🏗️ PROPRIEDADES DO COMPONENTE
  // ========================================
  
  state: FinesListState = {
    loading: false,
    error: null,
    fines: [],
    filteredFines: [],
    activeFilter: 'municipal',
    totalCount: 0,
    currentPage: 1
  };

  filterTabs: FilterTab[] = [];
  paginatedFines: Fines[] = [];
  totalPages = 0;
  
  // ✅ NOVO: Totais de valores das multas
  totalValues = {
    general: 0,
    municipal: 0,
    state: 0,
    federal: 0,
    filtered: 0
  };
  
  private destroy$ = new Subject<void>();
  private sortColumn = '';
  private sortDirection: 'asc' | 'desc' = 'desc';

  // ========================================
  // 🏗️ CONSTRUTOR E LIFECYCLE
  // ========================================
  
  constructor(
    private finesService: FinesService,
    private datePipe: DatePipe,
    private currencyPipe: CurrencyPipe,
    private cdr: ChangeDetectorRef
  ) {}

  ngOnInit(): void {
    this.initializeComponent();
    this.loadFines();
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  // ========================================
  // 🚀 INICIALIZAÇÃO
  // ========================================
  
  private initializeComponent(): void {
    // Configurar valores padrão
    this.config = {
      showNewButton: true,
      showFilters: true,
      readonly: false,
      pageSize: 10,
      maxHeight: '900px',
      ...this.config
    };

    // Inicializar abas de filtro
    this.initializeFilterTabs();
  }

  private initializeFilterTabs(): void {
    this.filterTabs = [
      {
        id: 'municipal',
        label: FILTER_TAB_LABELS.municipal,
        count: 0,
        active: true
      },
      {
        id: 'state',
        label: FILTER_TAB_LABELS.state,
        count: 0,
        active: false
      },
      {
        id: 'federal',
        label: FILTER_TAB_LABELS.federal,
        count: 0,
        active: false
      }
    ];
  }

  // ========================================
  // 📊 CARREGAMENTO DE DADOS
  // ========================================
  
  loadFines(): void {
    this.state.loading = true;
    this.state.error = null;
    this.cdr.detectChanges();

    // Construir filtros baseados na configuração
    const filters: any = {};
    
    if (this.config.vehicleId) {
      filters.vehicleIds = this.config.vehicleId;
    }
    
    if (this.config.driverId) {
      filters.driverId = this.config.driverId;
    }

    // Carregar multas do serviço
    this.finesService.getFiness(1, 100000, filters)
      .pipe(
        takeUntil(this.destroy$),
        catchError(error => {
          console.error('Erro ao carregar multas:', error);
          this.state.error = 'Erro ao carregar as multas. Tente novamente.';
          return of({ data: [], totalCount: 0, pageCount: 0, currentPage: 1 });
        })
      )
      .subscribe((response: any) => {
        this.state.fines = response.data || [];
        this.state.totalCount = response.totalCount || 0;
        this.state.loading = false;
        
        this.updateFilterTabs();
        this.applyCurrentFilter();
        this.cdr.detectChanges();
      });
  }

  // ========================================
  // 🏷️ FILTROS E ABAS
  // ========================================
  
  private updateFilterTabs(): void {
    // Contar multas por tipo de organização
    const counts = {
      municipal: 0,
      state: 0,
      federal: 0
    };

    this.state.fines.forEach(fine => {
      const orgType = this.getOrganizationType(fine.organization);
      counts[orgType]++;
    });

    // Atualizar contadores das abas
    this.filterTabs.forEach(tab => {
      tab.count = counts[tab.id];
    });

    // ✅ NOVO: Calcular totais de valores
    this.calculateTotalValues();
  }

  // ========================================
  // 💰 CÁLCULO DE VALORES TOTAIS
  // ========================================
  
  private calculateTotalValues(): void {
    // Resetar totais
    this.totalValues = {
      general: 0,
      municipal: 0,
      state: 0,
      federal: 0,
      filtered: 0
    };

    // Calcular totais por categoria
    this.state.fines.forEach(fine => {
      const value = Number(fine.fine_value) || 0;
      const orgType = this.getOrganizationType(fine.organization);
      
      this.totalValues.general += value;
      this.totalValues[orgType] += value;
    });

    // Calcular total filtrado
    this.state.filteredFines.forEach(fine => {
      const value = Number(fine.fine_value) || 0;
      this.totalValues.filtered += value;
    });
  }

  setActiveFilter(filter: OrganizationType): void {
    // Atualizar estado das abas
    this.filterTabs.forEach(tab => {
      tab.active = tab.id === filter;
    });

    this.state.activeFilter = filter;
    this.state.currentPage = 1;
    
    this.applyCurrentFilter();
    this.filterChanged.emit(filter);
  }

  private applyCurrentFilter(): void {
    if (!this.config.showFilters) {
      this.state.filteredFines = [...this.state.fines];
    } else {
      this.state.filteredFines = this.state.fines.filter(fine => {
        const orgType = this.getOrganizationType(fine.organization);
        return orgType === this.state.activeFilter;
      });
    }

    // ✅ NOVO: Recalcular total filtrado
    this.calculateFilteredTotal();
    this.updatePagination();
  }

  private calculateFilteredTotal(): void {
    this.totalValues.filtered = 0;
    this.state.filteredFines.forEach(fine => {
      const value = Number(fine.fine_value) || 0;
      this.totalValues.filtered += value;
    });
  }

  private getOrganizationType(organization: any): OrganizationType {
    if (!organization) return 'municipal';
    
    const orgString = typeof organization === 'string' ? organization : organization.toString();
    return ORGANIZATION_TYPE_MAP[orgString.toLowerCase()] || 'municipal';
  }

  // ========================================
  // 📄 PAGINAÇÃO
  // ========================================
  
  private updatePagination(): void {
    this.totalPages = Math.ceil(this.state.filteredFines.length / (this.config.pageSize || 10));
    
    // Garantir que a página atual seja válida
    if (this.state.currentPage > this.totalPages) {
      this.state.currentPage = Math.max(1, this.totalPages);
    }

    this.updatePaginatedFines();
  }

  private updatePaginatedFines(): void {
    const startIndex = (this.state.currentPage - 1) * (this.config.pageSize || 10);
    const endIndex = startIndex + (this.config.pageSize || 10);
    
    this.paginatedFines = this.state.filteredFines.slice(startIndex, endIndex);
  }

  goToPage(page: number): void {
    if (page >= 1 && page <= this.totalPages) {
      this.state.currentPage = page;
      this.updatePaginatedFines();
    }
  }

  getVisiblePages(): number[] {
    const pages: number[] = [];
    const maxVisible = 5;
    const half = Math.floor(maxVisible / 2);
    
    let start = Math.max(1, this.state.currentPage - half);
    let end = Math.min(this.totalPages, start + maxVisible - 1);
    
    // Ajustar início se necessário
    if (end - start + 1 < maxVisible) {
      start = Math.max(1, end - maxVisible + 1);
    }
    
    for (let i = start; i <= end; i++) {
      pages.push(i);
    }
    
    return pages;
  }

  // ========================================
  // 🔄 ORDENAÇÃO
  // ========================================
  
  sortBy(column: string): void {
    if (this.sortColumn === column) {
      this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
    } else {
      this.sortColumn = column;
      this.sortDirection = 'desc';
    }

    this.state.filteredFines.sort((a, b) => {
      let valueA: any = a[column as keyof Fines];
      let valueB: any = b[column as keyof Fines];

      // Tratamento especial para datas
      if (column === 'fine_date') {
        valueA = new Date(valueA || 0).getTime();
        valueB = new Date(valueB || 0).getTime();
      }

      // Tratamento especial para valores
      if (column === 'fine_value') {
        valueA = Number(valueA) || 0;
        valueB = Number(valueB) || 0;
      }

      if (valueA < valueB) {
        return this.sortDirection === 'asc' ? -1 : 1;
      }
      if (valueA > valueB) {
        return this.sortDirection === 'asc' ? 1 : -1;
      }
      return 0;
    });

    this.updatePaginatedFines();
  }

  // ========================================
  // 🎨 FORMATAÇÃO E EXIBIÇÃO
  // ========================================
  
  getDefaultTitle(): string {
    if (this.config.vehicleId) {
      return 'Multas do Veículo';
    }
    if (this.config.driverId) {
      return 'Multas do Motorista';
    }
    return 'Multas';
  }

  formatDate(date: any): string {
    if (!date) return '-';
    return this.datePipe.transform(date, 'dd/MM/yyyy') || '-';
  }

  formatCurrency(value: any): string {
    if (!value) return '-';
    return this.currencyPipe.transform(value, 'BRL', 'symbol', '1.2-2') || '-';
  }

  // ✅ NOVO: Formatação de valores totais
  getTotalValue(type: 'general' | 'municipal' | 'state' | 'federal' | 'filtered'): string {
    return this.formatCurrency(this.totalValues[type]);
  }

  getCurrentFilterTotal(): string {
    return this.formatCurrency(this.totalValues.filtered);
  }

  getGeneralTotal(): string {
    return this.formatCurrency(this.totalValues.general);
  }

  getLocationDisplay(fine: any): string {
    // Implementar lógica para exibir localização
    // Por enquanto, retorna um placeholder
    // return 'São Paulo - SP';
    return fine.locationName || 'Não informado';
  }

  getOrganizationLabel(organization: any): string {
    if (!organization) return '';
    
    const orgMap: { [key: string]: string } = {
      'municipality': 'Municipal',
      'state': 'Estadual',
      'federal': 'Federal',
      'company': 'Empresa',
      'other': 'Outro'
    };

    const orgString = typeof organization === 'string' ? organization : organization.toString();
    return orgMap[orgString.toLowerCase()] || orgString;
  }

  getDriverName(fine: Fines): string {
    // Implementar lógica para obter nome do motorista
    // Por enquanto, retorna um placeholder baseado no driverId
    if (fine.driverId) {
      return `Motorista ${fine.driverId}`;
    }
    return 'Não informado';
  }

  getStatusClass(status: any): string {
    if (!status) return 'status-unknown';
    
    const statusMap: { [key: string]: string } = {
      'pending': 'status-pending',
      'paid': 'status-paid',
      'approved': 'status-approved',
      'cancelled': 'status-cancelled'
    };

    return statusMap[status.toLowerCase()] || 'status-unknown';
  }

  getStatusLabel(status: any): string {
    if (!status) return 'Não informado';
    
    const statusMap: { [key: string]: string } = {
      'pending': 'Pendente',
      'paid': 'Pago',
      'approved': 'Aprovado',
      'cancelled': 'Cancelado'
    };

    return statusMap[status.toLowerCase()] || status;
  }

  getFilterLabel(filter: OrganizationType): string {
    return FILTER_TAB_LABELS[filter];
  }

  // ========================================
  // 🎯 EVENTOS E AÇÕES
  // ========================================
  
  onFineSelected(fine: Fines): void {
    this.fineSelected.emit(fine);
  }

  onNewFineClick(): void {
    const context: { vehicleId?: number; driverId?: number } = {};
    
    if (this.config.vehicleId) {
      context.vehicleId = this.config.vehicleId;
    }
    
    if (this.config.driverId) {
      context.driverId = this.config.driverId;
    }

    this.newFineRequested.emit(context);
  }

  // ========================================
  // 🔧 UTILITÁRIOS
  // ========================================
  
  trackByFineId(index: number, fine: Fines): any {
    return fine.id || index;
  }
}
