import { Injectable, ComponentRef, ViewContainerRef, Type } from '@angular/core';
import { AddressFormComponent } from '../components/address-form/address-form.component';
import { TestDynamicComponent } from '../components/test-dynamic/test-dynamic.component';
import { ImageUploaderComponent } from '../components/image-uploader/image-uploader.component';
import { AccountPayableItemsComponent } from '../../domain/finances/account-payable/components/account-payable-items/account-payable-items.component';
import { CsvImporterComponent } from '../components/csv-importer/csv-importer.component';
import { VehicleLocationTrackerComponent } from '../components/vehicle-location-tracker/vehicle-location-tracker.component';
import { RouteLocationTrackerComponent } from '../components/route-location-tracker/route-location-tracker.component';
import { RouteStopsComponent } from '../../domain/routes/route-stops/route-stops.component';
import { RouteMapComponent } from '../../domain/routes/route-stops/components/route-map/route-map.component';
import { RouteStepsComponent } from '../../domain/routes/route-steps/route-steps.component';
import { VehicleTollParkingComponent } from '../../domain/vehicles/components/vehicle-tollparking/vehicle-tollparking.component';
import { VehicleDevicetrackerComponent } from '../../domain/vehicles/components/vehicle-devicetracker/vehicle-devicetracker.component';
import { DevicetrackerComponent } from '../../domain/devicetracker/devicetracker.component';
import { FinesListComponent } from '../../domain/fines/components/fines-list/fines-list.component';
import { VehicleFuelcontrollComponent } from '../../domain/vehicles/components/vehicle-fuelcontroll/vehicle-fuelcontroll.component';

/**
 * 🎯 DynamicComponentResolverService
 * 
 * Resolve e cria componentes dinamicamente baseado na configuração das sub-abas.
 * Evita que o HTML do GenericTabFormComponent se torne uma enciclopédia de componentes.
 */
@Injectable({
  providedIn: 'root'
})
export class DynamicComponentResolverService {

  // 🎯 Registry de componentes disponíveis
  private componentRegistry: Map<string, Type<any>> = new Map<string, Type<any>>([
    ['app-address-form', AddressFormComponent],
    ['app-test-dynamic', TestDynamicComponent],
    ['app-photos-form', ImageUploaderComponent],
    ['app-account-payable-items', AccountPayableItemsComponent],
    ['app-csv-importer', CsvImporterComponent],
    ['app-vehicle-location-tracker', VehicleLocationTrackerComponent],
    ['app-route-location-tracker', RouteLocationTrackerComponent],
    // ['app-route-stops', RouteStopsComponent],
    ['app-route-steps', RouteStepsComponent],
    ['app-vehicle-tollparking', VehicleTollParkingComponent],
    ['app-vehicle-devicetracker', VehicleDevicetrackerComponent],
    ['app-devicetracker', DevicetrackerComponent],
    ['app-fines-list', FinesListComponent],
    ['app-vehicle-fuelcontroll', VehicleFuelcontrollComponent],
    // Aqui podem ser adicionados outros componentes conforme necessário
    // ['app-documents-form', DocumentsFormComponent],
  ]);

  constructor() { }

  /**
   * Resolve um componente baseado no seletor
   */
  resolveComponent(selector: string): Type<any> | null {
    return this.componentRegistry.get(selector) || null;
  }

  /**
   * Cria um componente dinamicamente
   */
  createComponent<T>(
    selector: string,
    viewContainer: ViewContainerRef,
    inputs?: { [key: string]: any },
    outputs?: { [key: string]: (event: any) => void }
  ): ComponentRef<T> | null {
    console.log(`🔍 [DynamicResolver] Tentando criar componente: ${selector}`);
    console.log(`🔍 [DynamicResolver] Inputs:`, inputs);
    console.log(`🔍 [DynamicResolver] Outputs:`, outputs);
    
    const componentType = this.resolveComponent(selector);
    
    if (!componentType) {
      console.error(`❌ [DynamicResolver] Componente '${selector}' não encontrado no registry`);
      console.log(`📋 [DynamicResolver] Componentes disponíveis:`, this.getRegisteredComponents());
      return null;
    }

    console.log(`✅ [DynamicResolver] Componente '${selector}' encontrado no registry`);

    // Limpar container
    viewContainer.clear();
    console.log(`🧹 [DynamicResolver] Container limpo`);

    // Criar componente
    try {
      const componentRef = viewContainer.createComponent<T>(componentType);
      console.log(`🚀 [DynamicResolver] Componente criado com sucesso:`, componentRef);

      // Aplicar inputs
      if (inputs) {
        console.log(`📥 [DynamicResolver] Aplicando inputs...`);
        Object.keys(inputs).forEach(key => {
          if (componentRef.instance && typeof componentRef.instance === 'object' && key in componentRef.instance) {
            (componentRef.instance as any)[key] = inputs[key];
            console.log(`✅ [DynamicResolver] Input aplicado: ${key} =`, inputs[key]);
          } else {
            console.warn(`⚠️ [DynamicResolver] Input '${key}' não encontrado na instância do componente`);
          }
        });
      }

      // Aplicar outputs
      if (outputs) {
        console.log(`📤 [DynamicResolver] Aplicando outputs...`);
        Object.keys(outputs).forEach(key => {
          if (componentRef.instance && typeof componentRef.instance === 'object' && key in componentRef.instance) {
            const eventEmitter = (componentRef.instance as any)[key];
            if (eventEmitter && typeof eventEmitter.subscribe === 'function') {
              eventEmitter.subscribe(outputs[key]);
              console.log(`✅ [DynamicResolver] Output conectado: ${key}`);
            } else {
              console.warn(`⚠️ [DynamicResolver] Output '${key}' não é um EventEmitter`);
            }
          } else {
            console.warn(`⚠️ [DynamicResolver] Output '${key}' não encontrado na instância do componente`);
          }
        });
      }

      // Detectar mudanças
      componentRef.changeDetectorRef.detectChanges();
      console.log(`🔄 [DynamicResolver] Detecção de mudanças aplicada`);

      return componentRef;
    } catch (error) {
      console.error(`❌ [DynamicResolver] Erro ao criar componente '${selector}':`, error);
      return null;
    }
  }

  /**
   * Registra um novo componente no registry
   */
  registerComponent(selector: string, componentType: Type<any>): void {
    this.componentRegistry.set(selector, componentType);
  }

  /**
   * Lista todos os componentes registrados
   */
  getRegisteredComponents(): string[] {
    return Array.from(this.componentRegistry.keys());
  }
} 