import { Component, ChangeDetectorRef } from "@angular/core";
import { CommonModule, DatePipe } from "@angular/common";

import { TitleService } from "../../shared/services/theme/title.service";
import { HeaderActionsService } from "../../shared/services/header-actions.service";
import { TollparkingService } from "./tollparking.service";
import { Tollparking } from "./tollparking.interface";
import { SnackNotifyService } from "../../shared/components/snack-notify/snack-notify.service";

import { TabSystemComponent } from "../../shared/components/tab-system/tab-system.component";
import { BaseDomainComponent, DomainConfig, DashboardKPI, DashboardChart } from "../../shared/components/base-domain/base-domain.component";
import { TabFormConfig } from "../../shared/interfaces/generic-tab-form.interface";
import { TabFormConfigService } from "../../shared/components/tab-system/services/tab-form-config.service";
import { DriversService } from "../drivers/drivers.service";
import { DateRangeShortcuts } from "../../shared/utils/date-range.utils";
import { firstValueFrom } from 'rxjs';
import { TollparkingDashboardComponent } from './dashboard/tollparking-dashboard.component';
/**
 * 🎯 TollparkingComponent - Gestão de Pedágio & Estacionamento
 * 
 * ✨ Implementa BaseDomainComponent + Registry Pattern
 * 🚀 Auto-registro de configurações para escalabilidade infinita!
 */
@Component({
  selector: 'app-tollparking',
  standalone: true,
  imports: [CommonModule, TabSystemComponent],
  providers: [DatePipe],
  templateUrl: './tollparking.component.html',
  styleUrl: './tollparking.component.scss'
})
export class TollparkingComponent extends BaseDomainComponent<Tollparking> {

  constructor(
    private tollparkingService: TollparkingService,
    titleService: TitleService,
    headerActionsService: HeaderActionsService,
    cdr: ChangeDetectorRef,
    private datePipe: DatePipe,
    private tabFormConfigService: TabFormConfigService,
    private serviceDrivers: DriversService,
    private snackNotifyService: SnackNotifyService
  ) {
    super(titleService, headerActionsService, cdr, tollparkingService);
    this.registerFormConfig();
  }

  private registerFormConfig(): void {
    this.tabFormConfigService.registerFormConfig('tollparking', () => this.getFormConfig());
  }

  protected override getDomainConfig(): DomainConfig {
    return {
      domain: 'tollparking',
      title: 'Pedágio & Estacionamento',
      showDashboardTab: true,
      entityName: 'tollparking',
      pageSize: 300,
      subTabs: ['dados'],
      dashboardConfig: {
        title: 'Dashboard de Pedágio & Estacionamento',
        showKPIs: false,        // Desabilitar KPIs padrão
        showCharts: false,      // Desabilitar gráficos padrão
        showRecentItems: false, // Desabilitar itens recentes padrão
        customComponent: { name: 'tollparking-dashboard' }, // ✨ Usar string identificadora
        customData: {
          entities: () => this.entities,
          totalItems: () => this.totalItems,
          isLoading: () => this.isLoading
        }
      },
      filterConfig: {     
        fieldsSearchDefault: ['license_plates'],
        dateRangeFilter: true,
        companyFilter: true,
      },
      bulkActions: [
        {
          id: 'export-data',
          label: 'Exportar Dados',
          icon: 'fas fa-download',
          requiresSelection: false,
          action: (selectedItems) => this.openexportDataLista()
        }
      ],
      columns: [
        {
          field: "type", 
          header: "Tipo", 
          sortable: true, 
          filterable: true, 
          search: true,
          searchField: "types",
          searchType: "select",
          searchOptions: [
            { value: "Toll", label: "Pedágio" },
            { value: "Parking", label: "Estacionamento" },
            { value: "Signature", label: "Assinatura" },
            { value: "Others", label: "Outros" }
          ],
          label: (value: any) => {
            switch(value) {
              case 'Toll': return 'Pedágio';
              case 'Parking': return 'Estacionamento';
              case 'Signature': return 'Assinatura';
              case 'Others': return 'Outros';
              default: return value || '-';
            }
          }
        },
        { field: "license_plate", 
          header: "Placa", 
          sortable: true, 
          filterable: true, 
          search: true,
          searchField: "license_plates",
          searchType: "text" 
        },        
        { field: "driver_name", 
          header: "Motorista", 
          sortable: true, 
          filterable: true, 
          // search: true, 
          // searchType: "text" 
        },
        { field: "description", 
          header: "Descrição", 
          sortable: true, 
          filterable: true, 
          // search: true, 
          // searchType: "text" 
        },
        { 
          field: "value", 
          header: "Valor", 
          sortable: true, 
          filterable: true, 
          // search: true, 
          // searchType: "number",          
          label: (value: any) => {
            if (!value) return '-';
            return `R$ ${Number(value).toLocaleString('pt-BR', { minimumFractionDigits: 2 })}`;
          },
          footer: {
            type: 'sum',
            format: 'currency',
            label: 'Total:',
            precision: 2
          }
        },
        { field: "date",
          header: "Data",
          sortable: true,
          filterable: true,
          // search: true,
          date:true,
          // searchType: "date",
        },
        { field: "code", 
          header: "Código", 
          sortable: true, 
          filterable: true, 
          search: false, 
          searchType: "number" },
        {
          field: "createdAt",
          header: "Criado em",
          sortable: true,
          filterable: true,
          // search: false,
          // searchType: "date",
          label: (date: any) => this.datePipe.transform(date, "dd/MM/yyyy HH:mm") || "-"
        }
      ]
    };
  }

  getFormConfig(): TabFormConfig {
    return {
      title: 'Dados do Tollparking',      
      entityType: 'Estac./Pedágio',
      fields: [],
      submitLabel: 'Salvar Tollparking',
      showCancelButton: true,
      subTabs: [
        {
          id: 'dados',
          label: 'Dados Básicos',
          icon: 'fa-info-circle',
          enabled: true,
          order: 1,
          templateType: 'fields',
          requiredFields: ['name'],
          fields: [
           {
              key: 'description',
              label: 'Descrição',
              type: 'text',
              required: true,
              disabled: true,
              placeholder: 'Digite a descrição'
            },
            {
              key: 'value',
              label: 'Valor',
              type: 'number',
              required: true,
              disabled: true,
              placeholder: 'Digite o valor'
            },
            {
              key: 'license_plate',
              label: 'Placa',
              type: 'text',
              required: true,
              disabled: true,
              placeholder: 'Digite a placa'
            },
            {
              key: 'date',
              label: 'Data',
              type: 'date',
              required: true,
              disabled: true,
              placeholder: 'Selecione a data'
            },
            {
              key: 'code',
              label: 'Código',
              type: 'text',
              required: true,
              disabled: true,
              placeholder: 'Digite o código'
            },
            {
              key: 'driverId',
              label: '',
              type: 'remote-select',
              labelField: 'driver_name',
              remoteConfig: {
                service: this.serviceDrivers,
                searchField: 'name',
                displayField: 'name',
                valueField: 'id',
                placeholder: 'Digite o nome do motorista...',
              }
            },
           
          ]
        }
      ]
    };
  }

  protected override getNewEntityData(): Partial<Tollparking> {
    return {
      
      
      
      
    };
  }

  // ========================================
  // 📊 EXPORTAÇÃO DE DADOS
  // ========================================

  private openexportDataLista(): void {
    // Mostrar opções de período para o usuário
    this.showPeriodSelectionModal();
  }

  /**
   * 📅 Mostrar modal de seleção de período
   */
  private showPeriodSelectionModal(): void {
    const periodOptions = [
      { label: 'Hoje', value: 'today', description: 'Dados de hoje' },
      { label: 'Ontem', value: 'yesterday', description: 'Dados de ontem' },
      { label: 'Últimos 7 dias', value: 'last7Days', description: 'Última semana' },
      { label: 'Últimos 30 dias', value: 'last30Days', description: 'Último mês' },
      { label: 'Mês atual', value: 'currentMonth', description: 'Do início do mês até hoje' },
      { label: 'Mês anterior', value: 'previousMonth', description: 'Mês anterior' },
      { label: 'Ano atual', value: 'currentYear', description: 'Do início do ano até hoje' },
      // { label: 'Todos os dados', value: 'all', description: 'Exportar todos os registros' }
    ];

    // Criar elementos do modal
    const modalHtml = `
      <div class="period-selection-modal">
        <h3>Selecione o período para exportação</h3>
        <div class="period-options">
          ${periodOptions.map(option => `
            <div class="period-option" data-value="${option.value}">
              <div class="option-label">${option.label}</div>
              <div class="option-description">${option.description}</div>
            </div>
          `).join('')}
        </div>
        <div class="modal-actions">
          <button class="btn-cancel">Cancelar</button>
        </div>
      </div>
    `;

    // Criar overlay
    const overlay = document.createElement('div');
    overlay.className = 'modal-overlay';
    overlay.innerHTML = modalHtml;
    document.body.appendChild(overlay);

    // Adicionar estilos
    this.addModalStyles();

    // Adicionar event listeners
    overlay.addEventListener('click', (e) => {
      const target = e.target as HTMLElement;
      
      if (target.classList.contains('modal-overlay') || target.classList.contains('btn-cancel')) {
        document.body.removeChild(overlay);
        return;
      }

      const periodOption = target.closest('.period-option') as HTMLElement;
      if (periodOption) {
        const selectedPeriod = periodOption.dataset['value'];
        document.body.removeChild(overlay);
        this.exportDataWithPeriod(selectedPeriod!);
      }
    });
  }

  /**
   * 📊 Exportar dados com período selecionado
   */
  private exportDataWithPeriod(period: string): void {
    let dateFilters: any = {};
    
    // Definir filtros baseado no período selecionado
    switch (period) {
      case 'today':
        dateFilters = DateRangeShortcuts.today();
        break;
      case 'yesterday':
        dateFilters = DateRangeShortcuts.yesterday();
        break;
      case 'last7Days':
        dateFilters = DateRangeShortcuts.last7Days();
        break;
      case 'last30Days':
        dateFilters = DateRangeShortcuts.last30Days();
        break;
        case 'previousMonth':
          dateFilters = DateRangeShortcuts.previousMonth();
          break;        
      case 'currentMonth':
        dateFilters = DateRangeShortcuts.currentMonth();
        break;
      case 'currentYear':
        dateFilters = DateRangeShortcuts.currentYear();
        break;
      case 'all':
      default:
        dateFilters = {}; // Sem filtros de data
        break;
    }

    // Fazer a requisição com os filtros
    this.tollparkingService.getTollparkings(1, 100000, dateFilters).subscribe((response: any) => {
      console.log('Resposta da API:', response);
      const data = response.data;
      
      if (!data || data.length === 0) {
        this.snackNotifyService.warning('Nenhum dado encontrado para exportar no período selecionado');
        return;
      }
      
      // Converter dados para CSV
      const csv = this.convertToCSV(data);
      
      // Criar nome do arquivo com período
      const periodLabel = this.getPeriodLabel(period);
      const fileName = `tollparking_${periodLabel}_${new Date().toISOString().split('T')[0]}.csv`;
      
      // Criar e baixar o arquivo CSV
      const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = fileName;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
      
      this.snackNotifyService.info(`Dados exportados para CSV com sucesso (${data.length} registros)`, { duration: 4000 });
    });
  }

  /**
   * 🏷️ Obter label do período para nome do arquivo
   */
  private getPeriodLabel(period: string): string {
    const labels: {[key: string]: string} = {
      'today': 'hoje',
      'yesterday': 'ontem',
      'last7Days': 'ultimos_7_dias',
      'last30Days': 'ultimos_30_dias',
      'currentMonth': 'mes_atual',
      'currentYear': 'ano_atual',
      'all': 'todos_dados'
    };
    return labels[period] || 'periodo_customizado';
  }

  /**
   * 🎨 Adicionar estilos do modal
   */
  private addModalStyles(): void {
    if (document.getElementById('period-modal-styles')) return;

    const styles = document.createElement('style');
    styles.id = 'period-modal-styles';
    styles.textContent = `
      .modal-overlay {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 10000;
      }
      
      .period-selection-modal {
        background: white;
        border-radius: 8px;
        padding: 24px;
        max-width: 500px;
        width: 90%;
        max-height: 80vh;
        overflow-y: auto;
      }
      
      .period-selection-modal h3 {
        margin: 0 0 20px 0;
        color: #333;
        font-size: 18px;
      }
      
      .period-options {
        display: grid;
        gap: 12px;
        margin-bottom: 20px;
      }
      
      .period-option {
        padding: 12px 16px;
        border: 2px solid #e0e0e0;
        border-radius: 6px;
        cursor: pointer;
        transition: all 0.2s ease;
      }
      
      .period-option:hover {
        border-color: #2196F3;
        background: #f5f5f5;
      }
      
      .option-label {
        font-weight: 600;
        color: #333;
        margin-bottom: 4px;
      }
      
      .option-description {
        font-size: 12px;
        color: #666;
      }
      
      .modal-actions {
        display: flex;
        justify-content: flex-end;
        gap: 12px;
      }
      
      .btn-cancel {
        padding: 8px 16px;
        border: 1px solid #ddd;
        background: white;
        border-radius: 4px;
        cursor: pointer;
      }
      
      .btn-cancel:hover {
        background: #f5f5f5;
      }
    `;
    document.head.appendChild(styles);
  }

  /**
   * 📊 Converter array de objetos para formato CSV
   */
  private convertToCSV(data: any[]): string {
    if (!data || data.length === 0) return '';
    
    const headers = Array.from(new Set(data.flatMap(obj => Object.keys(obj))));
    const csvHeaders = headers.join(',');
    
    const csvRows = data.map(obj => {
      return headers.map(header => {
        const value = obj[header];
        if (value === null || value === undefined) return '';
        const stringValue = String(value);
        if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) {
          return `"${stringValue.replace(/"/g, '""')}"`;
        }
        return stringValue;
      }).join(',');
    });
    
    return [csvHeaders, ...csvRows].join('\n');
  }

  // ========================================
  // 📊 DASHBOARD PERSONALIZADO
  // ========================================

  /**
   * 🎯 KPIs customizados para dashboard de Pedágio & Estacionamento
   */
  private getCustomKPIs(): DashboardKPI[] {
    if (!this.entities || this.entities.length === 0) {
      return [];
    }

    const now = new Date();
    const currentMonth = now.getMonth();
    const currentYear = now.getFullYear();
    
    // Calcular dados dos últimos 3 meses
    const last3MonthsData = this.getLast3MonthsData();
    const currentMonthData = this.getCurrentMonthData();
    const previousMonthData = this.getPreviousMonthData();
    
    // Top 10 veículos por valor total
    const topVehiclesByValue = this.getTopVehiclesByValue(10);
    
    // Evolução mensal
    const monthlyEvolution = this.getMonthlyEvolution();

    return [
      {
        id: 'top-vehicle-value',
        label: 'Maior Gasto (Veículo)',
        value: topVehiclesByValue.length > 0 ? 
          `R$ ${topVehiclesByValue[0].totalValue.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}` : 
          'R$ 0,00',
        icon: 'fas fa-trophy',
        color: 'warning',
        trend: 'up',
        change: topVehiclesByValue.length > 0 ? topVehiclesByValue[0].license_plate : '-'
      },
      {
        id: 'monthly-evolution',
        label: 'Evolução Mensal',
        value: monthlyEvolution.trend === 'up' ? '↗️' : monthlyEvolution.trend === 'down' ? '↘️' : '→',
        icon: 'fas fa-chart-line',
        color: monthlyEvolution.trend === 'up' ? 'success' : monthlyEvolution.trend === 'down' ? 'danger' : 'info',
        trend: monthlyEvolution.trend,
        change: `${monthlyEvolution.percentage}%`
      },
      {
        id: 'active-vehicles',
        label: 'Veículos Ativos (3 meses)',
        value: last3MonthsData.uniqueVehicles,
        icon: 'fas fa-car',
        color: 'primary',
        trend: 'stable',
        change: 'últimos 90 dias'
      },
      {
        id: 'avg-monthly-cost',
        label: 'Gasto Médio Mensal',
        value: `R$ ${last3MonthsData.avgMonthlyValue.toLocaleString('pt-BR', { minimumFractionDigits: 2 })}`,
        icon: 'fas fa-calculator',
        color: 'info',
        trend: monthlyEvolution.avgTrend,
        change: 'últimos 3 meses'
      }
    ];
  }

  /**
   * 📈 Gráficos customizados para dashboard
   */
  private getCustomCharts(): DashboardChart[] {
    if (!this.entities || this.entities.length === 0) {
      return [];
    }

    const topVehicles = this.getTopVehiclesByValue(10);
    const monthlyData = this.getMonthlyEvolutionData();
    const typeDistribution = this.getTypeDistribution();

    return [
      {
        id: 'top-vehicles-chart',
        title: 'Top 10 Veículos por Valor Total',
        type: 'bar',
        data: topVehicles.map(v => ({
          label: v.license_plate,
          value: v.totalValue,
          count: v.count,
          avgValue: v.avgValue
        }))
      },
      {
        id: 'monthly-evolution-chart',
        title: 'Evolução dos Últimos 3 Meses',
        type: 'line',
        data: monthlyData
      },
      {
        id: 'type-distribution-chart',
        title: 'Distribuição por Tipo',
        type: 'pie',
        data: typeDistribution
      }
    ];
  }

  // ========================================
  // 🔢 MÉTODOS DE CÁLCULO DE DADOS
  // ========================================

  /**
   * 📊 Obter dados dos últimos 3 meses
   */
  private getLast3MonthsData() {
    const now = new Date();
    const threeMonthsAgo = new Date(now.getFullYear(), now.getMonth() - 3, 1);
    
    const recentData = this.entities.filter((item: any) => {
      const itemDate = new Date(item.date || item.created_at);
      return itemDate >= threeMonthsAgo;
    });

    const totalValue = recentData.reduce((sum: number, item: any) => sum + (Number(item.value) || 0), 0);
    const uniqueVehicles = new Set(recentData.map((item: any) => item.license_plate)).size;
    const avgMonthlyValue = totalValue / 3;

    return {
      totalValue,
      uniqueVehicles,
      avgMonthlyValue,
      count: recentData.length
    };
  }

  /**
   * 📊 Obter dados do mês atual
   */
  private getCurrentMonthData() {
    const now = new Date();
    const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
    
    const currentMonthData = this.entities.filter((item: any) => {
      const itemDate = new Date(item.date || item.created_at);
      return itemDate >= startOfMonth;
    });

    return {
      totalValue: currentMonthData.reduce((sum: number, item: any) => sum + (Number(item.value) || 0), 0),
      count: currentMonthData.length,
      uniqueVehicles: new Set(currentMonthData.map((item: any) => item.license_plate)).size
    };
  }

  /**
   * 📊 Obter dados do mês anterior
   */
  private getPreviousMonthData() {
    const now = new Date();
    const startOfPreviousMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
    const endOfPreviousMonth = new Date(now.getFullYear(), now.getMonth(), 0);
    
    const previousMonthData = this.entities.filter((item: any) => {
      const itemDate = new Date(item.date || item.created_at);
      return itemDate >= startOfPreviousMonth && itemDate <= endOfPreviousMonth;
    });

    return {
      totalValue: previousMonthData.reduce((sum: number, item: any) => sum + (Number(item.value) || 0), 0),
      count: previousMonthData.length,
      uniqueVehicles: new Set(previousMonthData.map((item: any) => item.license_plate)).size
    };
  }

  /**
   * 🏆 Obter top veículos por valor total
   */
  private getTopVehiclesByValue(limit: number = 10) {
    const vehicleStats = new Map();

    this.entities.forEach((item: any) => {
      const plate = item.license_plate;
      const value = Number(item.value) || 0;

      if (!vehicleStats.has(plate)) {
        vehicleStats.set(plate, {
          license_plate: plate,
          totalValue: 0,
          count: 0,
          avgValue: 0
        });
      }

      const stats = vehicleStats.get(plate);
      stats.totalValue += value;
      stats.count += 1;
      stats.avgValue = stats.totalValue / stats.count;
    });

    return Array.from(vehicleStats.values())
      .sort((a, b) => b.totalValue - a.totalValue)
      .slice(0, limit);
  }

  /**
   * 📈 Obter evolução mensal
   */
  private getMonthlyEvolution() {
    const currentMonth = this.getCurrentMonthData();
    const previousMonth = this.getPreviousMonthData();

    if (previousMonth.totalValue === 0) {
      return {
        trend: 'stable' as const,
        percentage: '0',
        avgTrend: 'stable' as const
      };
    }

    const valueChange = ((currentMonth.totalValue - previousMonth.totalValue) / previousMonth.totalValue) * 100;
    const countChange = ((currentMonth.count - previousMonth.count) / previousMonth.count) * 100;

    return {
      trend: valueChange > 5 ? 'up' as const : valueChange < -5 ? 'down' as const : 'stable' as const,
      percentage: valueChange.toFixed(1),
      avgTrend: countChange > 5 ? 'up' as const : countChange < -5 ? 'down' as const : 'stable' as const
    };
  }

  /**
   * 📊 Obter dados de evolução mensal para gráfico
   */
  private getMonthlyEvolutionData() {
    const monthlyData = [];
    const now = new Date();

    for (let i = 2; i >= 0; i--) {
      const monthDate = new Date(now.getFullYear(), now.getMonth() - i, 1);
      const nextMonthDate = new Date(now.getFullYear(), now.getMonth() - i + 1, 1);
      
      const monthData = this.entities.filter((item: any) => {
        const itemDate = new Date(item.date || item.created_at);
        return itemDate >= monthDate && itemDate < nextMonthDate;
      });

      const totalValue = monthData.reduce((sum: number, item: any) => sum + (Number(item.value) || 0), 0);
      const uniqueVehicles = new Set(monthData.map((item: any) => item.license_plate)).size;

      monthlyData.push({
        month: monthDate.toLocaleDateString('pt-BR', { month: 'short', year: 'numeric' }),
        totalValue,
        count: monthData.length,
        uniqueVehicles
      });
    }

    return monthlyData;
  }

  /**
   * 🥧 Obter distribuição por tipo
   */
  private getTypeDistribution() {
    const typeStats = new Map();

    this.entities.forEach((item: any) => {
      const type = item.type || 'Outros';
      
      if (!typeStats.has(type)) {
        typeStats.set(type, {
          type,
          count: 0,
          totalValue: 0
        });
      }

      const stats = typeStats.get(type);
      stats.count += 1;
      stats.totalValue += Number(item.value) || 0;
    });

    return Array.from(typeStats.values()).map(stat => ({
      label: this.getTypeLabel(stat.type),
      value: stat.totalValue,
      count: stat.count,
      percentage: ((stat.count / this.entities.length) * 100).toFixed(1)
    }));
  }

  /**
   * 🏷️ Obter label traduzido do tipo
   */
  private getTypeLabel(type: string): string {
    const typeLabels: { [key: string]: string } = {
      'Toll': 'Pedágio',
      'Parking': 'Estacionamento',
      'Signature': 'Assinatura',
      'Others': 'Outros'
    };
    return typeLabels[type] || type;
  }
}