import { Component, Input, OnInit, OnChanges, SimpleChanges, ViewEncapsulation, ElementRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

// ✨ Import da interface de comparação mensal
export interface MonthlyComparison {
  currentTotal: number;
  previousTotal: number;
  percentageChange: number;
  trend: 'up' | 'down' | 'stable';
  currentCount: number;
  previousCount: number;
}

// 📊 Interface para dados do gráfico de despesas
export interface ExpenseData {
  type: 'Toll' | 'Parking' | 'Signature' | 'Others' | 'ApprovedCustomer' | 'AdvanceRequested' | 'AdvanceApproved' | 'AdvanceRefused' | 'Fuel' | 'GRAVISSIMA' | 'GRAVE' | 'MÉDIA' | 'LEVE';
  value: number;
  count: number;
  companyName?: string; // ✅ NOVO: Nome da empresa
}

// 🏢 Interface para dados agrupados por empresa
export interface CompanyExpenseData {
  companyName: string;
  totalValue: number;
  totalCount: number;
  expenses: ExpenseData[];
}

// 🎨 Interface para configuração visual
export interface ExpenseChartConfig {
  title?: string;
  showPercentages?: boolean;
  showCounts?: boolean;
  animated?: boolean;
  height?: string;
  groupByCompany?: boolean; // ✅ NOVO: Mostrar agrupamento por empresa
  showCompanyFilter?: boolean; // ✅ NOVO: Mostrar filtro de empresa
}

@Component({
  selector: 'app-expense-chart',
  standalone: true,
  imports: [CommonModule, FormsModule],
  templateUrl: './expense-chart.component.html',
  styleUrl: './expense-chart.component.scss',
  encapsulation: ViewEncapsulation.None
})
export class ExpenseChartComponent implements OnInit, OnChanges {
  @Input() data: ExpenseData[] = [];
  @Input() comparison?: MonthlyComparison; // ✨ NOVO: Dados de comparação mensal
  @Input() config: ExpenseChartConfig = {
    title: 'Despesas por Tipo',
    showPercentages: true,
    showCounts: true,
    animated: true,
    height: '400px',
    groupByCompany: false,
    showCompanyFilter: false
  };

  isDarkMode = false;
  
  // 🏢 Dados agrupados por empresa
  companyData: CompanyExpenseData[] = [];
  selectedCompany: string = 'all';
  companyOptions: { value: string; label: string }[] = [];

  // 📊 Dados processados para visualização
  chartData: {
    type: string;
    label: string;
    value: number;
    count: number;
    percentage: number;
    color: string;
    icon: string;
    barHeight: number;
  }[] = [];

  totalValue = 0;
  totalCount = 0;

  // 🎨 Mapeamento de cores e ícones por tipo
  typeConfig = {
    // 🚛 Tipos de despesas RFID
    'Toll': {
      label: 'Pedágios',
      color: '#3B82F6', // Blue
      icon: 'fas fa-road'
    },
    'Parking': {
      label: 'Estacionamentos',
      color: '#10B981', // Green
      icon: 'fas fa-parking'
    },
    'Signature': {
      label: 'Assinaturas',
      color: '#F59E0B', // Yellow
      icon: 'fas fa-file-signature'
    },
    'Others': {
      label: 'Outros',
      color: '#8B5CF6', // Purple
      icon: 'fas fa-ellipsis-h'
    },
    // 💳 Tipos de status de pagamento
    'ApprovedCustomer': {
      label: 'Aprovado pelo Cliente',
      color: '#10B981', // Green
      icon: 'fas fa-check-circle'
    },
    'AdvanceRequested': {
      label: 'Solicitada Antecipação',
      color: '#F59E0B', // Yellow
      icon: 'fas fa-clock'
    },
    'AdvanceApproved': {
      label: 'Aprovado Antecipação',
      color: '#059669', // Dark Green
      icon: 'fas fa-thumbs-up'
    },
    'AdvanceRefused': {
      label: 'Recusado Antecipação',
      color: '#EF4444', // Red
      icon: 'fas fa-times-circle'
    },
    // ⛽ Tipo de combustível
    'Fuel': {
      label: 'Combustível',
      color: '#F97316', // Orange
      icon: 'fas fa-gas-pump'
    },
    // 🚨 Tipos de multas por severidade
    'GRAVISSIMA': {
      label: 'Multas Gravíssimas',
      color: '#DC2626', // Dark Red
      icon: 'fas fa-exclamation-triangle'
    },
    'GRAVE': {
      label: 'Multas Graves',
      color: '#EA580C', // Orange Red
      icon: 'fas fa-exclamation-circle'
    },
    'MÉDIA': {
      label: 'Multas Médias',
      color: '#F59E0B', // Yellow
      icon: 'fas fa-exclamation'
    },
    'LEVE': {
      label: 'Multas Leves',
      color: '#10B981', // Green
      icon: 'fas fa-info-circle'
    }
  };

  constructor(private elementRef: ElementRef) {}

  ngOnInit() {
    this.checkDarkMode();
    this.processData();
    
    // 🌙 Observar mudanças de tema
    this.observeThemeChanges();
  }

  ngOnChanges(changes: SimpleChanges) {
    if (changes['data']) {
      this.processData();
    }
  }

  private processData() {
    // Se deve agrupar por empresa, processar dados por empresa primeiro
    if (this.config.groupByCompany) {
      this.processCompanyData();
    }
    
    // Calcular totais com validação
    this.totalValue = this.data.reduce((sum, item) => {
      const value = typeof item.value === 'string' ? parseFloat(item.value) : Number(item.value);
      return sum + (isNaN(value) ? 0 : value);
    }, 0);
    
    this.totalCount = this.data.reduce((sum, item) => {
      const count = typeof item.count === 'string' ? parseInt(item.count) : Number(item.count);
      return sum + (isNaN(count) ? 0 : count);
    }, 0);

    // Processar dados para visualização (rosca sempre mostra total geral)
    this.chartData = this.getAggregatedDataByType()
      .map(item => {
        const typeConfig = this.typeConfig[item.type as keyof typeof this.typeConfig];
        
        if (!typeConfig) {
          return null;
        }
        
        const percentage = this.totalValue > 0 ? (item.value / this.totalValue) * 100 : 0;
        const maxValue = Math.max(...this.getAggregatedDataByType().map(d => d.value));
        const barHeight = maxValue > 0 ? (item.value / maxValue) * 100 : 0;



        return {
          type: item.type,
          label: typeConfig.label,
          value: item.value,
          count: item.count,
          percentage: Math.round(percentage * 10) / 10,
          color: typeConfig.color,
          icon: typeConfig.icon,
          barHeight: Math.max(barHeight, 5) // Mínimo de 5% para visualização
        };
      })
      .filter((item): item is NonNullable<typeof item> => item !== null)
      .sort((a, b) => b.value - a.value); // Ordenar por valor decrescente
  }

  // 🏢 Processar dados agrupados por empresa
  private processCompanyData() {
    const companyMap = new Map<string, { expenses: ExpenseData[]; totalValue: number; totalCount: number }>();
    
    // Agrupar dados por empresa
    this.data.forEach(item => {
      const companyName = item.companyName || 'Sem Empresa';
      
      if (!companyMap.has(companyName)) {
        companyMap.set(companyName, {
          expenses: [],
          totalValue: 0,
          totalCount: 0
        });
      }
      
      const company = companyMap.get(companyName)!;
      company.expenses.push(item);
      company.totalValue += Number(item.value) || 0;
      company.totalCount += Number(item.count) || 0;
    });
    
    // Converter para array e ordenar por valor total
    this.companyData = Array.from(companyMap.entries())
      .map(([companyName, data]) => ({
        companyName,
        totalValue: data.totalValue,
        totalCount: data.totalCount,
        expenses: data.expenses.sort((a, b) => b.value - a.value)
      }))
      .sort((a, b) => b.totalValue - a.totalValue);
    
    // Criar opções para o filtro de empresa
    this.companyOptions = [
      { value: 'all', label: 'Todas as Empresas' },
      ...this.companyData.map(company => ({
        value: company.companyName,
        label: company.companyName
      }))
    ];
  }

  // 📊 Agregar dados por tipo (para a rosca)
  private getAggregatedDataByType(): ExpenseData[] {
    const typeMap = new Map<string, { value: number; count: number }>();
    
    this.data.forEach(item => {
      const current = typeMap.get(item.type) || { value: 0, count: 0 };
      typeMap.set(item.type, {
        value: current.value + (Number(item.value) || 0),
        count: current.count + (Number(item.count) || 0)
      });
    });
    
    return Array.from(typeMap.entries()).map(([type, data]) => ({
      type: type as any,
      value: data.value,
      count: data.count
    }));
  }

  // 🏢 Filtrar empresa selecionada
  onCompanyFilterChange(companyName: string) {
    this.selectedCompany = companyName;
  }

  // 🏢 Obter top 3 empresas para um tipo específico
  getTopCompaniesForType(type: string): { name: string; value: number; count: number }[] {
    // Verificar se há dados com companyName válido para este tipo
    const itemsWithCompany = this.data.filter(item => 
      item.type === type && 
      item.companyName && 
      item.companyName.trim() !== '' && 
      item.companyName !== 'Empresa Não Informada'
    );
    
    // Se não há dados com empresa válida, retornar array vazio
    if (itemsWithCompany.length === 0) {
      return [];
    }
    
    // Agrupar dados por empresa para este tipo específico
    const companyMap = new Map<string, { value: number; count: number }>();
    
    itemsWithCompany.forEach(item => {
      const companyName = item.companyName!; // Já validado acima
      const value = Number(item.value) || 0;
      const count = Number(item.count) || 0;
      
      const current = companyMap.get(companyName) || { value: 0, count: 0 };
      companyMap.set(companyName, {
        value: current.value + value,
        count: current.count + count
      });
    });

    // Converter para array, ordenar por valor decrescente e limitar a 3
    const result = Array.from(companyMap.entries())
      .map(([name, data]) => ({
        name,
        value: data.value,
        count: data.count
      }))
      .sort((a, b) => b.value - a.value) // Ordem decrescente
      .slice(0, 3); // Limitar a 3 registros
    
    return result;
  }

  // 🎨 Gerar cor para empresa baseada no índice
  getCompanyColor(companyName: string, index: number): string {
    const colors = [
      '#10B981', // Verde
      '#8B5CF6', // Roxo  
      '#F59E0B', // Amarelo
      '#EF4444', // Vermelho
      '#06B6D4', // Ciano
      '#F97316'  // Laranja
    ];
    
    // Usar hash do nome para consistência, mas com fallback para índice
    let hash = 0;
    for (let i = 0; i < companyName.length; i++) {
      hash = ((hash << 5) - hash + companyName.charCodeAt(i)) & 0xffffffff;
    }
    
    const colorIndex = Math.abs(hash) % colors.length;
    return colors[colorIndex];
  }

  // 💰 Formatação de valores monetários


  formatCurrency(value: number | string | undefined | null): string {
    // Converter para número e validar
    const numValue = typeof value === 'string' ? parseFloat(value) : Number(value);
    
    if (!numValue || isNaN(numValue) || numValue === 0) return 'R$ 0,00';
    
    const absValue = Math.abs(numValue);
    
    if (absValue >= 1000000) {
      return `R$ ${(numValue / 1000000).toFixed(1).replace('.', ',')}M`;
    } else if (absValue >= 1000) {
      return `R$ ${(numValue / 1000).toFixed(1).replace('.', ',')}K`;
    } else {
      return `R$ ${numValue.toFixed(2).replace('.', ',').replace(/\B(?=(\d{3})+(?!\d))/g, '.')}`;
    }
  }

  // 📊 Formatação de percentuais
  formatPercentage(value: number | string | undefined | null): string {
    const numValue = typeof value === 'string' ? parseFloat(value) : Number(value);
    if (!numValue || isNaN(numValue)) return '0,0%';
    return `${numValue.toFixed(1).replace('.', ',')}%`;
  }

  // 🔢 Formatação de contadores
  formatCount(count: number | string | undefined | null): string {
    const numCount = typeof count === 'string' ? parseInt(count) : Number(count);
    if (!numCount || isNaN(numCount) || numCount === 0) return '0 registros';
    if (numCount === 1) return '1 registro';
    return `${numCount.toLocaleString('pt-BR')} registros`;
  }

  // 🎨 Gerar gradiente dinâmico para o donut
  getDonutGradient(): string {
    if (this.chartData.length === 0) return '';
    
    let gradient = '';
    let currentAngle = 0;
    
    this.chartData.forEach((item, index) => {
      const angle = (item.percentage / 100) * 360;
      
      if (index > 0) {
        gradient += `, `;
      }
      
      gradient += `${item.color} ${currentAngle}deg ${currentAngle + angle}deg`;
      currentAngle += angle;
    });
    
    return `conic-gradient(${gradient})`;
  }

  // 🌙 Detectar modo dark
  private checkDarkMode() {
    const htmlElement = document.documentElement;
    const bodyElement = document.body;
    
    this.isDarkMode = 
      htmlElement.getAttribute('data-theme') === 'dark' ||
      bodyElement.getAttribute('data-theme') === 'dark' ||
      htmlElement.classList.contains('dark') ||
      bodyElement.classList.contains('dark');
  }

  // 🌙 Observar mudanças de tema
  private observeThemeChanges() {
    // Observar mudanças no atributo data-theme do html
    const observer = new MutationObserver(() => {
      this.checkDarkMode();
    });

    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['data-theme', 'class']
    });

    observer.observe(document.body, {
      attributes: true,
      attributeFilter: ['data-theme', 'class']
    });
  }

  // ✨ NOVOS MÉTODOS para comparação mensal
  
  /**
   * 📈 Obter classe CSS para trend
   */
  getTrendClass(trend: 'up' | 'down' | 'stable'): string {
    return `trend-${trend}`;
  }

  /**
   * 🎯 Obter ícone para trend
   */
  getTrendIcon(trend: 'up' | 'down' | 'stable'): string {
    switch (trend) {
      case 'up': return 'fas fa-arrow-up';
      case 'down': return 'fas fa-arrow-down';
      case 'stable': return 'fas fa-minus';
      default: return 'fas fa-minus';
    }
  }

  /**
   * 🏷️ Obter label para trend
   */
  getTrendLabel(trend: 'up' | 'down' | 'stable'): string {
    switch (trend) {
      case 'up': return 'aumento';
      case 'down': return 'redução';
      case 'stable': return 'estável';
      default: return 'estável';
    }
  }
}
