import { NgFor, NgIf } from '@angular/common';
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ApiService } from '@app/cores/services/api.service';
import { ToastModule } from 'primeng/toast';
import { MessageService } from 'primeng/api';
import { DropdownModule } from 'primeng/dropdown';
import { ProgressSpinnerModule } from 'primeng/progressspinner';

@Component({
  selector: 'app-relation-modal',
  standalone: true,
  imports: [NgIf, NgFor, FormsModule, ToastModule, DropdownModule, ProgressSpinnerModule],
  templateUrl: './relation-modal.component.html',
  styleUrls: ['./relation-modal.component.scss']
})
export class RelationModalComponent implements OnInit {
  @Input() relationModalId: string = 'relationModal';
  @Input() relationInfo: any = {};
  @Input() parentItem: any = {};
  
  @Output() onSave = new EventEmitter<any>();
  
  allItems: any[] = [];
  availableItems: any[] = [];
  selectedItems: any[] = [];
  selectedItem: any = null; // Pour les relations hasOne
  
  searchTerm: string = '';
  loading: boolean = false;
  
  get relationLabel(): string {
    return this.relationInfo.label || 'Relation';
  }
  
  constructor(
    private apiService: ApiService,
    private messageService: MessageService
  ) {}
  
  ngOnInit() {
    this.loadRelationData();
  }
  
  loadRelationData() {
    this.loading = true;
    
    // Charger les données de la relation
    this.apiService.get(this.relationInfo.apiRoute).subscribe({
      next: (response: any) => {
        this.allItems = response.data || [];
        
        // Charger les éléments déjà associés
        if (this.parentItem.id) {
          const parentResourcePath = `${this.parentItem.resourceName}/${this.parentItem.id}/${this.relationInfo.name}`;
          
          this.apiService.get(parentResourcePath).subscribe({
            next: (relResponse: any) => {
              if (this.relationInfo.type === 'hasOne') {
                // Pour hasOne, on sélectionne directement l'élément
                this.selectedItem = relResponse.data;
              } else {
                // Pour hasMany et belongsToMany, on remplit la liste d'éléments sélectionnés
                this.selectedItems = relResponse.data || [];
                this.updateAvailableItems();
              }
              this.loading = false;
            },
            error: (error: any) => {
              this.messageService.add({ 
                severity: 'error', 
                summary: 'Erreur', 
                detail: 'Impossible de charger les données de la relation'
              });
              this.loading = false;
            }
          });
        } else {
          this.updateAvailableItems();
          this.loading = false;
        }
      },
      error: (error: any) => {
        this.messageService.add({ 
          severity: 'error', 
          summary: 'Erreur', 
          detail: 'Impossible de charger les données disponibles'
        });
        this.loading = false;
      }
    });
  }
  
  updateAvailableItems() {
    // Filtrer les éléments disponibles (ceux qui ne sont pas déjà sélectionnés)
    const selectedIds = this.selectedItems.map(item => item.id);
    this.availableItems = this.allItems.filter(item => !selectedIds.includes(item.id));
    
    // Appliquer le filtre de recherche si nécessaire
    if (this.searchTerm) {
      this.filterItems();
    }
  }
  
  filterItems() {
    if (!this.searchTerm) {
      this.updateAvailableItems();
      return;
    }
    
    const term = this.searchTerm.toLowerCase();
    const optionLabel = this.relationInfo.optionLabel || 'name';
    
    // Filtrer les éléments disponibles
    const selectedIds = this.selectedItems.map(item => item.id);
    this.availableItems = this.allItems.filter(item => {
      // Pas déjà sélectionné et correspond au terme de recherche
      const notSelected = !selectedIds.includes(item.id);
      const labelValue = String(item[optionLabel] || '').toLowerCase();
      const matches = labelValue.includes(term);
      
      return notSelected && matches;
    });
  }
  
  addToSelected(item: any) {
    this.selectedItems.push(item);
    this.updateAvailableItems();
  }
  
  removeFromSelected(item: any) {
    const index = this.selectedItems.findIndex(i => i.id === item.id);
    if (index !== -1) {
      this.selectedItems.splice(index, 1);
      this.updateAvailableItems();
    }
  }
  
  saveRelation() {
    this.loading = true;
    
    if (!this.parentItem || !this.parentItem.id) {
      this.messageService.add({ 
        severity: 'error', 
        summary: 'Erreur', 
        detail: 'Élément parent non défini'
      });
      this.loading = false;
      return;
    }
    
    const parentResourcePath = `${this.parentItem.resourceName}/${this.parentItem.id}/${this.relationInfo.name}`;
    
    if (this.relationInfo.type === 'hasOne') {
      // Pour hasOne, nous envoyons l'ID de l'élément sélectionné
      const payload = {
        id: this.selectedItem ? this.selectedItem.id : null
      };
      
      this.apiService.put(parentResourcePath, payload).subscribe({
        next: (response: any) => {
          this.messageService.add({ 
            severity: 'success', 
            summary: 'Succès', 
            detail: 'Relation mise à jour avec succès'
          });
          this.loading = false;
          this.onSave.emit({
            type: this.relationInfo.type,
            name: this.relationInfo.name,
            data: this.selectedItem
          });
        },
        error: (error: any) => {
          this.messageService.add({ 
            severity: 'error', 
            summary: 'Erreur', 
            detail: 'Impossible de mettre à jour la relation'
          });
          this.loading = false;
        }
      });
    } else {
      // Pour hasMany et belongsToMany, nous envoyons un tableau d'IDs
      const ids = this.selectedItems.map(item => item.id);
      
      const payload = {
        ids: ids
      };
      
      this.apiService.put(parentResourcePath, payload).subscribe({
        next: (response: any) => {
          this.messageService.add({ 
            severity: 'success', 
            summary: 'Succès', 
            detail: 'Relations mises à jour avec succès'
          });
          this.loading = false;
          this.onSave.emit({
            type: this.relationInfo.type,
            name: this.relationInfo.name,
            data: this.selectedItems
          });
        },
        error: (error: any) => {
          this.messageService.add({ 
            severity: 'error', 
            summary: 'Erreur', 
            detail: 'Impossible de mettre à jour les relations'
          });
          this.loading = false;
        }
      });
    }
  }
}