import { transition, trigger, useAnimation } from "@angular/animations";
import { DOCUMENT } from "@angular/common";
import { Component, Inject, OnInit, ViewChild } from "@angular/core";
import {
  AbstractControl,
  FormBuilder,
  FormGroup,
  Validators,
} from "@angular/forms";
import {
  MatDialog,
  MatDialogRef,
  MAT_DIALOG_DATA,
} from "@angular/material/dialog";
import { MatAccordion } from "@angular/material/expansion";
import { slideInRight } from "ng-animate";
import { tap } from "rxjs/operators";
import { ProjectService } from "src/app/services/projects.service";
import { ReportingService } from "src/app/services/reporting.service";
import { ToastService } from "src/app/services/toast.service";
import { ProjectsStore } from "src/app/stores/projects.store";
import origineOperation from "src/assets/data/origine_operation.json";
import dataStatut from "src/assets/data/statut.json";
import offerType from "src/assets/data/type_offre.json";
import { StorageService } from 'src/app/core/services/storage.service';
import {
  getListViewElements,
  addObject,
  addDataStorage,
  updateObject,
  updateDataStorage,
  massUpdateDataStorage,
} from "src/app/custom/common";
import { DataService } from "src/app/core/services/data.service";

@Component({
  selector: "app-projects1",
  templateUrl: "./projects.component.html",
  styleUrls: ["./projects.component.scss"],
  animations: [
    trigger("slideInRight", [transition("* => *", useAnimation(slideInRight))]),
  ],
})
export class ProjectsComponent implements OnInit {
  public statuts = dataStatut;
  public origine_operation = origineOperation;
  public dataContrepartie!: [];
  public isLoadingResultContrepartie = false;
  public dataBeneficiaire!: [];
  public autocomplete_selected = "";
  public isLoadingResultBeneficiaire = false;
  public keyword = "name";
  public isRequis = true;
  public dataSignatureName!: [];
  public isLoadingResultSignatureName = false;
  public dataDemandeur!: [];
  public isLoadingResultDemandeur = false;
  public dataInstallateur!: [];
  public isLoadingResultInstallateur = false;

  public dataObjects: any[] = [];
  public isLoadingSearchObject = false;

  // Map pour stocker les IDs des champs de référence sélectionnés
  // Clé: nom du champ, Valeur: ID sélectionné
  private selectedReferenceIds: Map<string, number> = new Map();

  public dataSousAcjent!: [];
  public isLoadingSousAjenct = false;

  public record!: [];
  public isLoadingDepot = false;

  public dataBook!: [];
  public isLoadingBook = false;

  public dataMandataire!: [];
  public isLoadingMandataire = false;

  public slideInRight: any;
  public offer_type = offerType;
  public errorMsg = "";
  public panelOpenState = false;
  public form!: FormGroup;
  public isEdit = false;
  public isEditMultiple = false;
  public labelButton: string = "Enregister";
  public labelLoading: string = "Création en cours ...";
  public metadatas!: any;
  public metadatasSections!: any[];
  public modulename!: any;
  public moduleLabel!: string;
  public isLoadingDetails: boolean = false;

  @ViewChild(MatAccordion)
  accordion!: MatAccordion;
  public submitted = false;
  public isLoading = false;
  public formBuilderArray = {};
  constructor(
    public dialog: MatDialog,
    private formBuilder: FormBuilder,
    private projectService: ProjectService,
    private toast: ToastService,
    private reporting: ReportingService,
    public projectStore: ProjectsStore,
    @Inject(MAT_DIALOG_DATA) public data: any,
    @Inject(DOCUMENT) private document: Document,
    public dialogRef: MatDialogRef<ProjectsComponent>,
    public storage: StorageService,
    public dataService: DataService
  ) {}

  async ngOnInit() {
    this.isLoadingDetails = true;

    // 🔍 Debug: données reçues par le dialog
    console.log('🔍 Dialog data received:', this.data);
    console.log('🔍 Data has ID?', this.data?.id);
    console.log('🔍 Data is array?', Array.isArray(this.data));
    console.log('🔍 Data length?', Array.isArray(this.data) ? this.data.length : 'N/A');

    const dd = this.storage.getItem("__domaineDD");
    const __domainedd = dd ? JSON.parse(dd) : {};
    this.modulename =
      this.data && this.data.context && this.data.context.from != undefined
        ? this.data.context.from
        : __domainedd.modulename;

    // Debug des données de domaine
    console.log('Debug __domainedd:', __domainedd);
    console.log('Debug __domainedd.modules:', __domainedd?.modules);
    
    // Utiliser directement le mapping manuel
    this.moduleLabel = this.getModuleDisplayName(this.modulename);
    let lvs = this.storage.getItem("__lvs");
    let __lvs = lvs ? JSON.parse(lvs) : {};

    // ⚡ Optimisation: chargement asynchrone avec cache intelligent
    if (__lvs == null || __lvs[this.modulename] == undefined) {
      console.log(`🚀 Chargement des métadonnées pour ${this.modulename}...`);
      const startTime = performance.now();
      __lvs = await getListViewElements(this.modulename, this.dataService);
      const endTime = performance.now();
      console.log(`✅ Métadonnées chargées en ${(endTime - startTime).toFixed(2)}ms`);
    } else {
      console.log(`⚡ Métadonnées trouvées en cache pour ${this.modulename}`);
    }

    // Charger les métadonnées CreateView (pas de .data dans la structure)
    this.metadatas = __lvs[this.modulename]?.CreateView?.fields;

    console.log('Debug modulename:', this.modulename);
    console.log('Debug moduleLabel final:', this.moduleLabel);
    console.log('🔍 metadatas après CreateView:', this.metadatas);

    if (
      this.data &&
      ((Array.isArray(this.data) &&
        this.data.length > 0 &&
        this.data[0].id != null) ||
        this.data.id != null)
    ) {
      this.metadatas = __lvs[this.modulename]?.UpdateView?.fields;
      console.log('🔍 metadatas après UpdateView:', this.metadatas);
    }

    // Si pas de métadonnées, initialiser avec un tableau vide pour éviter les erreurs
    if (!this.metadatas) {
      console.warn(`⚠️ Pas de métadonnées CreateView/UpdateView pour ${this.modulename}`);
      console.warn(`⚠️ Clés disponibles dans __lvs[${this.modulename}]:`, Object.keys(__lvs[this.modulename] || {}));
      this.metadatas = [];
    }

    if (this.modulename === "requetes") {
      const user = JSON.parse(this.storage.getItem("__user") || "{}");
      if (user.role !== "Admin" && Array.isArray(this.metadatas)) {
        this.metadatas = this.metadatas.map((item: any) => {
          if (
            item?.name === "status" &&
            item?.type === "picklist" &&
            Array.isArray(item.options)
          ) {
            item.options = item.options.filter(
              (opt: any) => opt && opt.value === "À Traiter"
            );
          }

          if (
            item?.name === "assigner_a" &&
            item?.type === "picklist" &&
            Array.isArray(item.options)
          ) {
            item.options = item.options.filter(
              (opt: any) => opt && opt.value === "Admin"
            );
          }

          return item;
        });
      }
    }
    if (this.modulename === "driver_block_records") {
      const user = JSON.parse(this.storage.getItem("__user") || "{}");
      
      if (Array.isArray(this.metadatas)) {
        this.metadatas = this.metadatas.map((item: any) => {
          if (
            item?.name === "status" &&
            item?.type === "picklist" &&
            Array.isArray(item.options)
          ) {
           
            item.options = item.options.filter((opt: any) => {
              if (user.role === "Admin") {
                return opt;
              } else {
                return opt && opt.value !== "unblock";
              }
            });
          }
    
          return item;
        });
      }
    }
    
    if (
      this.data &&
      ((Array.isArray(this.data) &&
        this.data.length > 0 &&
        this.data[0].id != null &&
        this.data[0].status === "Terminer") ||
        (this.data.id != null && this.data.status === "Terminer"))
    ) {
      this.metadatas = this.metadatas.map((item: any) => {
        if (
          item?.name === "status" &&
          item?.type === "picklist" &&
          Array.isArray(item.options)
        ) {
          item.options = item.options.filter(
            (opt: any) => opt && opt.value === "Terminer"
          );
        }
        return item;
      });
    }

    // Détecter le mode d'édition multiple AVANT la création du formulaire
    if (this.data && this.data.length > 0) {
      this.isEditMultiple = true;
      this.labelButton = "Modifier";
      this.labelLoading = "Modifications multiple en cours ...";
    }

    // 🔍 Debug: construction du formulaire
    console.log('🔍 Building form with metadatas:', this.metadatas?.length, 'fields');
    console.log('🔍 Edit mode check - this.data?.id:', this.data?.id);

    // Vérifier que metadatas existe et est un tableau
    if (Array.isArray(this.metadatas)) {
      for (let i = 0; i < this.metadatas.length; i += 1) {
        const fieldName = this.metadatas[i].name;
        const fieldValue = this.data && this.data.id ? this.data[fieldName] : "";

        // 🔍 Debug: valeur de chaque champ
        if (this.data?.id && i < 3) { // Log des 3 premiers champs en mode édition
          console.log(`🔍 Field ${fieldName}:`, fieldValue);
        }

        let object = {
          [fieldName]: [
            fieldValue,
            // En mode massEdit, aucun champ n'est requis
            this.metadatas[i].mandatory && !this.isEditMultiple ? [Validators.required] : [],
          ],
        };
        this.formBuilderArray = { ...this.formBuilderArray, ...object };
      }
    }

    // Toujours initialiser le formulaire, même si vide
    this.form = this.formBuilder.group(this.formBuilderArray);

    // Grouper les metadatas en sections pour les accordéons
    this.createMetadatasSections();
    this.document.body.classList.add("pop-element");
    if (this.data && this.data.id) {
      this.isEdit = true;
      this.labelButton = "Modifier";
      this.labelLoading = "Modifications en cours ...";
    }
    this.isLoadingDetails = false;
  }

  public closeDialog() {
    this.dialogRef.close();
  }

  get f(): { [key: string]: AbstractControl } {
    return this.form.controls;
  }

  public checkObjectNotEmpty(data: any) {
    data.map((data: any, key: any, el: any) => {
      // console.log("data", data);
      // console.log("key", key);
      // console.log("el", el);
    });
  }

  public shouldShowField(metadata: any): boolean {
    // Vérifier si le champ a un type reconnu
    const supportedTypes = ['string', 'currency', 'double', 'float', 'integer', 'text', 'datetime', 'date', 'picklist', 'reference'];
    return metadata && metadata.type && supportedTypes.includes(metadata.type);
  }

  private createMetadatasSections(): void {
    if (!this.metadatas || !Array.isArray(this.metadatas)) {
      this.metadatasSections = [];
      return;
    }

    // Grouper les champs par leur propriété 'bloc'
    const blocGroups = new Map<string, any[]>();

    this.metadatas.forEach((metadata: any) => {
      if (!this.shouldShowField(metadata)) return;

      // Utiliser le champ 'bloc' des métadonnées
      const blocName = metadata.bloc || 'Autres';

      if (!blocGroups.has(blocName)) {
        blocGroups.set(blocName, []);
      }

      blocGroups.get(blocName)!.push(metadata);
    });

    // Convertir en sections avec tri par sequencecreate
    this.metadatasSections = Array.from(blocGroups.entries())
      .map(([blocName, fields]) => ({
        title: blocName,
        icon: this.getIconForSection(blocName),
        fields: fields.sort((a, b) => (a.sequencecreate || 0) - (b.sequencecreate || 0))
      }))
      .filter(section => section.fields.length > 0);

    // S'assurer qu'il y a au moins une section si aucun bloc n'a été trouvé
    if (this.metadatasSections.length === 0) {
      this.metadatasSections = [{
        title: 'Informations ' + this.moduleLabel,
        icon: 'info',
        fields: this.metadatas.filter(metadata => this.shouldShowField(metadata))
      }];
    }
  }


  private getIconForSection(sectionName: string): string {
    const name = sectionName?.toLowerCase() || '';

    if (name.includes('général') || name.includes('general') || name.includes('info')) {
      return 'info';
    }
    if (name.includes('financ') || name.includes('money') || name.includes('montant')) {
      return 'attach_money';
    }
    if (name.includes('date') || name.includes('time') || name.includes('échéance')) {
      return 'event';
    }
    if (name.includes('référence') || name.includes('relation') || name.includes('link')) {
      return 'link';
    }
    if (name.includes('contact') || name.includes('personne') || name.includes('user')) {
      return 'person';
    }
    if (name.includes('document') || name.includes('fichier')) {
      return 'description';
    }
    if (name.includes('adresse') || name.includes('lieu') || name.includes('location')) {
      return 'place';
    }

    return 'folder';
  }

  public getModuleDisplayName(moduleName: string): string {
    // Mapping des noms techniques vers les labels utilisateur
    const moduleLabels: { [key: string]: string } = {
      'accounts': 'Compte',
      'Accounts': 'Compte',
      'contacts': 'Contact',
      'Contacts': 'Contact',
      'opportunities': 'Opportunité',
      'Opportunities': 'Opportunité',
      'projects': 'Projet',
      'Projects': 'Projet',
      'tasks': 'Tâche',
      'Tasks': 'Tâche',
      'events': 'Événement',
      'Events': 'Événement',
      'documents': 'Document',
      'Documents': 'Document',
      'helpdesk': 'Support',
      'HelpDesk': 'Support',
      'campaigns': 'Campagne',
      'Campaigns': 'Campagne',
      'products': 'Produit',
      'Products': 'Produit',
      'quotes': 'Devis',
      'Quotes': 'Devis',
      'invoices': 'Facture',
      'Invoices': 'Facture',
      'purchaseorder': 'Bon de commande',
      'PurchaseOrder': 'Bon de commande',
      'salesorder': 'Commande',
      'SalesOrder': 'Commande',
      'vendors': 'Fournisseur',
      'Vendors': 'Fournisseur',
      'assets': 'Actif',
      'Assets': 'Actif',
      'projecttask': 'Tâche de projet',
      'ProjectTask': 'Tâche de projet',
      'projectmilestone': 'Jalon de projet',
      'ProjectMilestone': 'Jalon de projet',
      'servicecontracts': 'Contrat de service',
      'ServiceContracts': 'Contrat de service',
      'services': 'Service',
      'Services': 'Service'
    };

    return moduleLabels[moduleName] || moduleName;
  }

  public async addProject() {
    console.log('🎯 addProject() appelé');
    console.log('📋 État du formulaire:', {
      valid: this.form.valid,
      invalid: this.form.invalid,
      value: this.form.value,
      errors: this.form.errors
    });

    this.submitted = true;
    if (this.form.invalid || this.isLoading) {
      console.error('❌ Formulaire invalide ou chargement en cours');
      console.error('Erreurs des champs:', this.getFormValidationErrors());
      this.toast.showError("Merci de vérifier les champs requis");
      return;
    }
    this.isLoading = true;
    console.log('✅ Début de la sauvegarde...');
    console.log('📝 Metadatas:', this.metadatas);
    console.log('📝 Data:', this.data);
    console.log('📝 Selected Reference IDs Map:', Array.from(this.selectedReferenceIds.entries()));

    let payload = {};
    try {
      for (let i = 0; i < this.metadatas.length; i += 1) {
        const fieldName = this.metadatas[i].name;
        const fieldValue = this.form.value[fieldName];
        const fieldType = this.metadatas[i].type;

        // Pour les champs de référence, utiliser l'ID stocké dans la Map
        if (fieldType === 'reference') {
          const storedId = this.selectedReferenceIds.get(fieldName);
          console.log(`🔍 Debug field ${fieldName}:`, {
            type: fieldType,
            rawValue: fieldValue,
            valueType: typeof fieldValue,
            hasId: fieldValue?.id,
            id: fieldValue?.id,
            storedId: storedId
          });

          // Priorité: 1) ID stocké dans la Map, 2) fieldValue.id (si objet), 3) fieldValue (sinon)
          let field = {
            [fieldName]: storedId !== undefined ? storedId : (fieldValue?.id || fieldValue),
          };
          payload = { ...payload, ...field };
        } else {
          // Pour les autres types, utiliser la valeur directement
          let field = {
            [fieldName]: fieldValue?.id ? fieldValue.id : fieldValue,
          };
          payload = { ...payload, ...field };
        }
      }
      console.log('📦 Payload construit:', payload);
    } catch (error) {
      console.error('❌ Erreur lors de la construction du payload:', error);
      this.isLoading = false;
      this.toast.showError('Erreur lors de la préparation des données');
      return;
    }

    let othersData = {};
    if (this.data != null && this.data.data != undefined) {
      othersData = {
        contextParent: this.data?.data?.contextParent,
        contextParentId: this.data?.data[this.data?.data?.contextParent]?.id,
      };
      console.log('📎 Données contextuelles:', othersData);
    }
    payload = { ...payload, ...othersData };

    if (this.modulename == "HelpDesk") {
      payload = { ...payload, ...{ "Statut finance": "Ouvert" } };
    }

    console.log('🔍 Vérification du type d\'opération...');
    console.log('📊 this.data:', this.data);
    console.log('📊 Array.isArray(this.data):', Array.isArray(this.data));
    console.log('📊 this.data.length:', Array.isArray(this.data) ? this.data.length : 'N/A');

    if (this.data && this.data.length > 0) {
      console.log('🔄 Mode: Modification multiple');
      this.projectService
        .massEdit(payload, this.data, this.modulename)
        .pipe(
          tap(
            (res: any) => {
              if (res && res.success) {
                console.log('data', res.records);
                massUpdateDataStorage(this.modulename, res.records);
                this.toast.showSuccess("Modifications multiple avec succès");
                this.dialogRef.close({ action: "updated" });
                this.isLoading = false;
              } else {
                const errorMessage = res?.error || "L'autorisation d'effectuer l'opération est refusée pour l'identifiant";
                this.toast.showError(errorMessage);
                this.dialogRef.close({ error: errorMessage });
                this.isLoading = false;
              }
            },
            (error) => {
              this.isLoading = false;
              console.error('❌ Erreur lors de la modification multiple:', error);
              const errorMessage = "Erreur lors de la modification multiple";
              this.toast.showError(errorMessage);
              this.dialogRef.close({ error: errorMessage });
            }
          )
        )
        .subscribe();
    }
    if (this.data && this.data.id) {
      console.log('✏️ Mode: Modification unitaire');
      try {
        let objName = this.data?.data?.from;
        if(objName === undefined){
          objName = this.modulename;
        }
        console.log('🎯 Modification de:', objName, 'UUID:', this.data?.uuid);
        const dd = this.storage.getItem("__domaineDD");
        const __domainedd = dd ? JSON.parse(dd) : {};
        console.log('🌐 Domaine:', __domainedd.domaine);

        let res = await updateObject(
          __domainedd.domaine,
          objName,
          payload,
          this.data?.uuid,
          this.dataService
        );
        this.isLoading = false;
        payload = { ...payload, id: this.data.id };
        console.log('📥 Réponse modification:', res);

        if (res && res.success) {
          updateDataStorage(this.modulename, res.record);
          this.toast.showSuccess("Donnée modifiée avec succès");
          // Retourner l'information de succès pour que la vue detail puisse se rafraîchir
          this.dialogRef.close({ action: "updated", record: res.record });
        } else {
          const errorMessage = res?.error || "Erreur lors de la modification";
          this.toast.showError(errorMessage);
          // Retourner l'erreur pour que la vue detail puisse l'afficher
          this.dialogRef.close({ error: errorMessage });
          return;
        }
      } catch (error) {
        this.isLoading = false;
        console.error('❌ Exception lors de la modification:', error);
        const errorMessage = "Erreur technique lors de la modification";
        this.toast.showError(errorMessage);
        this.dialogRef.close({ error: errorMessage });
        return;
      }
    }

    console.log('🆕 Vérification mode création...');
    console.log('📊 Condition création: !this.data =', !this.data);
    console.log('📊 Condition création: this.data?.data?.from =', this.data?.data?.from);
    console.log('📊 Condition création: this.data?.id =', this.data?.id);

    // Mode création : soit pas de data, soit data sans id (création simple), soit data.data.from (création depuis une autre vue)
    if (!this.data || !this.data.id || (this.data && this.data.data && this.data.data.from)) {
      console.log('➕ Mode: Création');
      try {
        const dd = this.storage.getItem("__domaineDD");
        const __domainedd = dd ? JSON.parse(dd) : {};
        const moduleName = this.data?.data?.from || this.modulename;

        console.log('🌐 Domaine:', __domainedd.domaine);
        console.log('📦 Module:', moduleName);
        console.log('📤 Payload final:', payload);

        let res = await addObject(
          __domainedd.domaine,
          moduleName,
          payload,
          this.dataService
        );
        this.isLoading = false;

        console.log('📥 Réponse création:', res);

        if (res && res.success) {
          console.log('✅ Création réussie:', res.record);
          addDataStorage(moduleName, res.record);
          this.toast.showSuccess("Donnée créée avec succès");
          // Retourner l'information de succès
          this.dialogRef.close({ action: "created", record: res.record });
          return;
        } else {
          console.error('❌ Création échouée:', res);
          const errorMessage = res?.error || "Erreur lors de la création";
          this.toast.showError(errorMessage);
          this.dialogRef.close({ error: errorMessage });
          return;
        }
      } catch (error) {
        this.isLoading = false;
        console.error('❌ Exception lors de la création:', error);
        const errorMessage = "Erreur technique lors de la création";
        this.toast.showError(errorMessage);
        this.dialogRef.close({ error: errorMessage });
        return;
      }
    }

    console.log('⚠️ Aucune condition de sauvegarde remplie - fin de la fonction');
    this.isLoading = false;
  }

  public formatDateToBdd(date: string) {
    let d = new Date(date),
      month = "" + (d.getMonth() + 1),
      day = "" + d.getDate(),
      year = d.getFullYear();

    if (month.length < 2) month = "0" + month;
    if (day.length < 2) day = "0" + day;

    return [year, month, day].join("-");
  }

  public getServerResponseObject(event: string, module: string) {
    this.isLoadingSearchObject = true;
    if (event) {
      this.projectService.getByModule(module, event).subscribe(
        (data) => {
          data.length > 0 ? (this.dataObjects = data) : (this.dataObjects = []);
          this.isLoadingSearchObject = false;
        },
        (err) => {
          (this.errorMsg = "erreur depuis nos serveur , desole"),
            (this.isLoadingSearchObject = false);
        }
      );
    } else {
      this.isLoadingSearchObject = false;
    }
  }

  public triggerFunction(event: any) {
    if (event.key === "Enter") {
      var text = (this.form.value.descriptions += "\n");
    //  console.log(text);
      this.form.patchValue({
        descriptions: text,
      });
    }
  }

  public displayFn(item: any): string {
    // Gérer les différents formats d'objets: {name: ...} ou {value: ...}
    return item ? (item.value || item.name || item) : '';
  }

  public selectEvent(event: any, fieldName: string) {
    const selectedItem = event.option.value;
    if (selectedItem && fieldName) {
      console.log(`🔍 BEFORE patchValue - ${fieldName}:`, {
        selectedItem,
        currentFormValue: this.form.get(fieldName)?.value,
        hasId: !!selectedItem?.id,
        id: selectedItem?.id
      });

      // Stocker l'ID dans la Map pour l'utiliser lors de l'envoi
      if (selectedItem.id) {
        this.selectedReferenceIds.set(fieldName, selectedItem.id);
        console.log(`💾 Stored ID for ${fieldName}:`, selectedItem.id);
      }

      // Stocker l'objet complet dans le form control (pour l'affichage)
      // L'ID sera extrait au moment de l'envoi dans addProject()
      this.form.patchValue({
        [fieldName]: selectedItem
      });

      console.log(`✅ AFTER patchValue - ${fieldName}:`, {
        id: selectedItem.id,
        value: selectedItem.value || selectedItem.name,
        fullObject: selectedItem,
        formValue: this.form.get(fieldName)?.value,
        storedId: this.selectedReferenceIds.get(fieldName)
      });

      // Vider la liste d'autocomplétion après sélection
      this.dataObjects = [];
    }
  }

  public selectEventGroup(item: any) {
    //  this.form.value.account_name = item.name;
    // do something with selected item
  }

  public onChangeSearch(val: string) {
    // fetch remote data from here
    // And reassign the 'data' which is binded to 'data' property.
  }

  public onFocused(e: any, autocomplete: string) {
    // Vider la liste précédente quand on change de champ
    this.dataObjects = [];
    this.autocomplete_selected = autocomplete;
  }
  public clearInput() {
    this.autocomplete_selected = "";
    this.dataObjects = [];
  }
  public searchCleared() {
    this.dataContrepartie = [];
  }

  ngOnDestroy() {
    if (this.dialog.openDialogs.length === 0) {
      this.document.body.classList.remove("pop-element");
    }
  }

  /**
   * Helper pour debug: récupère toutes les erreurs de validation
   */
  private getFormValidationErrors(): any[] {
    const errors: any[] = [];
    Object.keys(this.form.controls).forEach(key => {
      const control = this.form.get(key);
      if (control && control.errors) {
        errors.push({
          field: key,
          errors: control.errors
        });
      }
    });
    return errors;
  }
}
