import { Component, Inject, OnInit, Optional } from '@angular/core';
import { MatDialogRef } from "@angular/material/dialog";
import { HttpClient } from "@angular/common/http";
import { ToastrService } from "ngx-toastr";
import { MAT_DIALOG_DATA } from "@angular/material/dialog";
import { DataService } from '../../../services/data.service';
import { ConfigService } from '@services/config.service';

@Component({
  selector: 'app-create-multiple-client',
  templateUrl: './create-multiple-client.component.html',
  styleUrl: './create-multiple-client.component.css'
})
export class CreateMultipleClientComponent implements OnInit {
  baseUrl: string = this.configService.apiUrl;
  parentUnits: any[] = [];
  parentUnitsWithPaths: { id: string, name: string, path: string }[] = [];
  uploadedClients: any[] = [];
  loading: boolean = false;
  displayedColumns: string[] = ['name', 'ip', 'mac'];
  showTextarea: boolean = true;
  organizationalUnit: any;
  regex: RegExp = /host\s+(\S+)\s*\{\s*hardware\s+ethernet\s+([a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5});\s*fixed-address\s+((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?));\s*\}/g;

  constructor(
    @Optional() private dialogRef: MatDialogRef<CreateMultipleClientComponent>,
    @Inject(MAT_DIALOG_DATA) private data: any,
    private http: HttpClient,
    private configService: ConfigService,
    private toastService: ToastrService,
    private dataService: DataService
  ) {
    this.baseUrl = this.configService.apiUrl;
  }

  ngOnInit(): void {
    this.loadParentUnits();

    if (this.data?.organizationalUnit) {
      this.organizationalUnit = this.data.organizationalUnit['@id'];
    }
  }

  loadParentUnits(): void {
    this.loading = true;
    const url = `${this.baseUrl}/organizational-units?page=1&itemsPerPage=10000`;

    this.http.get<any>(url).subscribe(
      response => {
        this.parentUnits = response['hydra:member'];
        this.parentUnitsWithPaths = this.parentUnits.map(unit => ({
          id: unit['@id'],
          name: unit.name,
          path: this.dataService.getOrganizationalUnitPath(unit, this.parentUnits)
        }));
        this.loading = false;
      },
      error => {
        console.error('Error fetching parent units:', error);
        this.loading = false;
      }
    );
  }

  getSelectedParentName(): string | undefined {
    const parentId = this.organizationalUnit;
    return this.parentUnitsWithPaths.find(unit => unit.id === parentId)?.name;
  }

  setOrganizationalUnit(organizationalUnit: any): void {
    this.organizationalUnit = organizationalUnit.value;
  }

  onFileUpload(event: any): void {
    const file = event.target.files[0];
    if (file) {
      const reader = new FileReader();

      reader.onload = (e: any) => {
        const textData = e.target.result;
        let match;
        const clients = [];

        while ((match = this.regex.exec(textData)) !== null) {
          clients.push({
            name: match[1],
            mac: match[2],
            ip: match[4]
          });
        }

        if (clients.length > 0) {
          this.uploadedClients = clients;
          this.toastService.success('Archivo cargado correctamente, los datos están listos para enviarse.', 'Éxito');
          this.showTextarea = false;
        } else {
          this.toastService.error('No se encontraron datos válidos', 'Error');
          this.showTextarea = true;
        }
      };

      reader.readAsText(file);
    }
  }

  onTextarea(text: string): void {
    let match;
    const clients = [];

    while ((match = this.regex.exec(text)) !== null) {
      clients.push({
        name: match[1],
        mac: match[2],
        ip: match[4]
      });
    }

    if (clients.length > 0) {
      this.uploadedClients = clients;
      this.toastService.success('Datos cargados correctamente, los datos están listos para enviarse.', 'Éxito');
      this.showTextarea = false;
    } else {
      this.toastService.error('No se encontraron datos válidos', 'Error');
      this.showTextarea = true;
    }
  }

  onSubmit(): void {
    if (this.uploadedClients.length > 0) {
      let successCount = 0;
      let errorMessages: string[] = [];

      this.uploadedClients.forEach(client => {
        const formData = {
          organizationalUnit: this.organizationalUnit,
          name: client.name || null,
          mac: client.mac || null,
          ip: client.ip || null,
        };

        this.http.post(`${this.baseUrl}/clients`, formData).subscribe(
          response => {
            successCount++;
            if (successCount + errorMessages.length === this.uploadedClients.length) {
              this.showFinalToast(successCount, errorMessages);
            }
          },
          error => {
            errorMessages.push(`Error al crear el cliente ${client.name}: ${error.error['hydra:description']}`);
            if (successCount + errorMessages.length === this.uploadedClients.length) {
              this.showFinalToast(successCount, errorMessages);
            }
          }
        );
      });
    } else {
      this.toastService.error('No hay clientes cargados para añadir', 'Error');
    }
  }

  showFinalToast(successCount: number, errorMessages: string[]): void {
    if (successCount > 0) {
      this.toastService.success(`${successCount} clientes creados exitosamente`, 'Éxito');
    }
    if (errorMessages.length > 0) {
      errorMessages.forEach(message => this.toastService.error(message, 'Error'));
    }
    this.dialogRef.close({
      success: successCount > 0,
      organizationalUnit: this.organizationalUnit,
    });
  }

  onNoClick(): void {
    this.dialogRef.close();
  }
}
