import { Component, EventEmitter, Output } from '@angular/core';
import { MatTableDataSource } from "@angular/material/table";
import { SelectionModel } from "@angular/cdk/collections";
import { HttpClient } from "@angular/common/http";
import { ToastrService } from "ngx-toastr";
import { ActivatedRoute, Router } from "@angular/router";
import { ConfigService } from '@services/config.service';

@Component({
  selector: 'app-deploy-image',
  templateUrl: './deploy-image.component.html',
  styleUrl: './deploy-image.component.css'
})
export class DeployImageComponent {
  baseUrl: string;
  @Output() dataChange = new EventEmitter<any>();

  errorMessage = '';
  clientId: string | null = null;
  partitions: any[] = [];
  images: any[] = [];
  selectedImage: any = null;
  selectedMethod: string | null = null;
  selectedPartition: any = null;
  mcastIp: string = '';
  mcastPort: Number = 0;
  mcastMode: string = '';
  mcastSpeed: Number = 0;
  mcastMaxClients: Number = 0;
  mcastMaxTime: Number = 0;
  p2pMode: string = '';
  p2pTime: Number = 0;
  client: any = null;
  clientData: any = [];
  loading: boolean = false;
  allSelected = true;

  protected p2pModeOptions = [
    { name: 'Leecher', value: 'leecher' },
    { name: 'Peer', value: 'peer' },
    { name: 'Seeder', value: 'seeder' },
  ];
  protected multicastModeOptions = [
    { name: 'Half duplex', value: "half" },
    { name: 'Full duplex', value: "full" },
  ];

  selectedClients: any[] = [];
  selectedModelClient: any = null;
  filteredPartitions: any[] = [];
  selectedRepository: any = null;

  allMethods = [
    'uftp',
    'udpcast',
    'udpcast-direct',
    'unicast',
    'unicast-direct',
    'p2p'
  ];

  dataSource = new MatTableDataSource<any>();
  columns = [
    {
      columnDef: 'diskNumber',
      header: 'Disco',
      cell: (partition: any) => `${partition.diskNumber}`
    },
    {
      columnDef: 'partitionNumber',
      header: 'Particion',
      cell: (partition: any) => `${partition.partitionNumber}`
    },
    {
      columnDef: 'size',
      header: 'Tamaño',
      cell: (partition: any) => `${partition.size} MB`
    },
    {
      columnDef: 'filesystem',
      header: 'Sistema de ficheros',
      cell: (partition: any) => `${partition.filesystem}`
    },
    {
      columnDef: 'operativeSystem',
      header: 'SO',
      cell: (partition: any) => `${partition.operativeSystem?.name}`
    }
  ];

  displayedColumns = ['select', ...this.columns.map(column => column.columnDef)];
  selection = new SelectionModel(true, []);

  constructor(
    private http: HttpClient,
    private toastService: ToastrService,
    private configService: ConfigService,
    private router: Router,
    private route: ActivatedRoute
  ) {
    this.baseUrl = this.configService.apiUrl;
    this.route.queryParams.subscribe(params => {
      if (params['clientData']) {
        this.clientData = JSON.parse(params['clientData']);
      }
    });
    this.clientId = this.clientData?.length ? this.clientData[0]['@id'] : null;
    this.clientData.forEach((client: { selected: boolean; status: string}) => {
      if (client.status === 'og-live') {
        client.selected = true;
      }
    });
    this.selectedClients = this.clientData.filter(
      (client: { status: string }) => client.status === 'og-live'
    );

    this.selectedModelClient = this.clientData[0];
    if (this.selectedModelClient) {
      this.loadPartitions(this.selectedModelClient);
    }
  }

  isMethod(method: string): boolean {
    return this.selectedMethod === method;
  }

  toggleClientSelection(client: any) {
    client.selected = !client.selected;
    this.updateSelectedClients();
  }

  updateSelectedClients() {
    this.selectedClients = this.clientData.filter(
      (client: { selected: boolean; state: string }) => client.selected && client.state === "og-live"
    );

    if (!this.selectedClients.includes(this.selectedModelClient)) {
      this.selectedModelClient = null;
      this.filteredPartitions = [];
    }
  }

  getPartitionsTooltip(client: any): string {
    if (!client.partitions || client.partitions.length === 0) {
      return 'No hay particiones disponibles';
    }

    return client.partitions
      .map((p: { partitionNumber: any; size: any; filesystem: any }) => `#${p.partitionNumber} ${p.filesystem} - ${p.size / 1024 }GB`)
      .join('\n');
  }

  loadPartitions(client: any) {
    if (client.selected) {
      this.http.get(`${this.baseUrl}${client.uuid}`).subscribe(
        (fullClientData: any) => {
          this.filteredPartitions = fullClientData.partitions;
          this.selectedRepository = fullClientData.repository ?? null;

          if (fullClientData.partitions) {
            this.filteredPartitions = fullClientData.partitions.filter((partition: any) => {
              return partition.partitionNumber !== 0;
            });
            this.p2pMode = fullClientData.organizationalUnit?.networkSettings?.p2pMode;
            this.p2pTime = fullClientData.organizationalUnit?.networkSettings?.p2pTime;
            this.mcastSpeed = fullClientData.organizationalUnit?.networkSettings?.mcastSpeed;
            this.mcastMode = fullClientData.organizationalUnit?.networkSettings?.mcastMode;
            this.mcastPort = fullClientData.organizationalUnit?.networkSettings?.mcastPort;
            this.mcastIp = fullClientData.organizationalUnit?.networkSettings?.mcastIp;
          }

          this.loadImages();
        },
        (error) => {
          console.error('Error al cargar los datos completos del cliente:', error);
        }
      );
    } else {
      this.selectedClients = this.selectedClients.filter(c => c.uuid !== client.uuid);
      this.filteredPartitions = [];
    }
  }


  toggleSelectAll() {
    this.allSelected = !this.allSelected;
    this.clientData.forEach((client: { selected: boolean; status: string }) => {
      if (client.status === "og-live") {
        client.selected = this.allSelected;
      }
    });
  }

  loadImages() {
    const repositoryId = this.selectedRepository?.id;

    if (!repositoryId) {
      console.error('Error: No se encontró repositoryId en el cliente seleccionado.');
      return;
    }

    const url = `${this.baseUrl}/image-image-repositories?status=success&repository.id=${repositoryId}&page=1&itemsPerPage=1000`;

    this.http.get(url).subscribe(
      (response: any) => {
        this.images = response?.['hydra:member'] || [];
      },
      (error) => {
        console.error('Error al cargar las imágenes:', error);
      }
    );
  }

  validateImageSize() {
    if (this.selectedImage && this.selectedPartition) {
      if ((this.selectedImage.datasize / 1024) / 1024 > this.selectedPartition.size) {

        this.errorMessage = "El tamaño de la imagen seleccionada excede el tamaño de la partición.";
        return false;
      }
    }
    this.errorMessage = "";
    return true;
  }

  save(): void {
    this.loading = true;

    if (!this.selectedClients.length) {
      this.toastService.error('Debe seleccionar al menos un cliente');
      this.loading = false;
      return;
    }

    if (!this.selectedImage) {
      this.toastService.error('Debe seleccionar una imagen');
      this.loading = false;
      return;
    }

    if (!this.selectedMethod) {
      this.toastService.error('Debe seleccionar un método');
      this.loading = false;
      return;
    }

    if (!this.selectedPartition) {
      this.toastService.error('Debe seleccionar una partición');
      this.loading = false;
      return;
    }

    this.toastService.info('Preparando petición de despliegue');

    const payload = {
      clients: this.selectedClients.map((client: any) => client.uuid),
      method: this.selectedMethod,
      // partition: this.selectedPartition['@id'],
      diskNumber: this.selectedPartition.diskNumber,
      partitionNumber: this.selectedPartition.partitionNumber,
      p2pMode: this.p2pMode,
      p2pTime: this.p2pTime,
      mcastIp: this.mcastIp,
      mcastPort: this.mcastPort,
      mcastMode: this.mcastMode,
      mcastSpeed: this.mcastSpeed,
      maxTime: this.mcastMaxTime,
      maxClients: this.mcastMaxClients,
    };

    this.http.post(`${this.baseUrl}/image-image-repositories/${this.selectedImage.uuid}/deploy-image`, payload)
      .subscribe({
        next: (response) => {
          this.toastService.success('Petición de despliegue enviada correctamente');
          this.loading = false;
          this.router.navigate(['/commands-logs']);
        },
        error: (error) => {
          this.toastService.error(error.error['hydra:description'], 'Se ha detectado un error en el despliegue de imágenes.', {
            "closeButton": true,
            "newestOnTop": false,
            "progressBar": false,
            "positionClass": "toast-bottom-right",
            "timeOut": 0,
            "extendedTimeOut": 0,
            "tapToDismiss": false
          });
          this.loading = false;
        }
      });
  }
}
