import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { HttpClient } from "@angular/common/http";
import { ToastrService } from "ngx-toastr";
import { DataService } from "../../images/data.service";
import { ActivatedRoute } from "@angular/router";
import { MatTableDataSource } from "@angular/material/table";
import { DatePipe } from "@angular/common";
import { Observable } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { ServerInfoDialogComponent } from "../../ogdhcp/server-info-dialog/server-info-dialog.component";
import { ConfigService } from '@services/config.service';

@Component({
  selector: 'app-main-repository-view',
  templateUrl: './main-repository-view.component.html',
  styleUrl: './main-repository-view.component.css'
})
export class MainRepositoryViewComponent implements OnInit {
  baseUrl: string;
  private apiUrl: string;
  repositoryForm: FormGroup<any>;
  repositoryId: string | null = null;
  dataSource = new MatTableDataSource<any>();
  loading: boolean = false;
  diskUsage: any = {};
  servicesStatus: any = {};
  processesStatus: any = {};
  diskUsageChartData: any[] = [];
  ramUsageChartData: any[] = [];
  ramUsage: any = {};
  cpuUsage: any = {};
  alertMessage: string | null = null;
  length: number = 0;
  itemsPerPage: number = 10;
  page: number = 0;
  gradient: boolean = true;
  showLabels: boolean = true;
  isDoughnut: boolean = true;
  status: boolean = false;
  repositoryData: any = {};
  colorScheme: any = {
    domain: ['#FF6384', '#3f51b5']
  };

  filters: { [key: string]: string } = {};
  datePipe: DatePipe = new DatePipe('es-ES');
  columns = [
    {
      columnDef: 'id',
      header: 'Id',
      cell: (image: any) => `${image.id}`
    },
    {
      columnDef: 'name',
      header: 'Nombre de imagen',
      cell: (image: any) => `${image.name}`
    },
    {
      columnDef: 'imageRepository',
      header: 'Repositorio',
      cell: (image: any) => `${image.imageRepository?.name}`
    },
    {
      columnDef: 'remotePc',
      header: 'Remote Pc',
      cell: (image: any) => `${image.remotePc}`
    },
    {
      columnDef: 'created',
      header: 'Creado en repositorio',
      cell: (image: any) => `${image.created}`
    },
    {
      columnDef: 'imageFullsum',
      header: 'Fullsum',
      cell: (image: any) => `${image.imageFullsum}`
    },
    {
      columnDef: 'createdAt',
      header: 'Fecha de creación',
      cell: (image: any) => `${this.datePipe.transform(image.createdAt, 'dd/MM/yyyy hh:mm:ss')}`
    }
  ];
  displayedColumns = [...this.columns.map(column => column.columnDef), 'actions'];

  constructor(
    private fb: FormBuilder,
    private http: HttpClient,
    private toastService: ToastrService,
    private dataService: DataService,
    private route: ActivatedRoute,
    public dialog: MatDialog,
    private configService: ConfigService
  ) {
    this.baseUrl = this.configService.apiUrl;
    this.apiUrl = `${this.baseUrl}/images`;
    this.repositoryForm = this.fb.group({
      name: ['', Validators.required],
      ip: [''],
      comments: [''],
    });
  }

  ngOnInit() {
    this.repositoryId = this.route.snapshot.paramMap.get('id');
    this.loadStatus()
    this.load()
  }

  load(): void {
    const url = `${this.baseUrl}/image-repositories/${this.repositoryId}`;
    this.http.get(url).subscribe(
      (response: any) => {
        this.repositoryData = response;
        this.repositoryForm = this.fb.group({
          name: [response.name, Validators.required],
          ip: [response.ip],
          comments: [response.comments],
        });
      },
      (error) => {
        console.error('Error al cargar los datos del cliente:', error);
      }
    );
  }

  save(): void {
    const payload = {
      name: this.repositoryForm.value.name,
      ip: this.repositoryForm.value.ip,
      comments: this.repositoryForm.value.comments,
    };

    if (this.repositoryId) {
      this.http.put(`${this.baseUrl}/image-repositories/${this.repositoryId}`, payload).subscribe(
        (response) => {
          this.toastService.success('Imagen editada correctamente');
        },
        (error) => {
          this.toastService.error(error['error']['hydra:description']);
          console.error('Error al editar la imagen', error);
        }
      );
    } else {
      this.http.post(`${this.baseUrl}/image-repositories`, payload).subscribe(
        (response) => {
          this.toastService.success('Imagen añadida correctamente');
        },
        (error) => {
          this.toastService.error(error['error']['hydra:description']);
          console.error('Error al añadir la imagen', error);
        }
      );
    }
  }

  loadStatus(): void {
    this.loading = true;
    this.http.get<any>(`${this.baseUrl}/image-repositories/server/${this.repositoryId}/status`).subscribe(data => {
      if (!data.success) {
        this.toastService.error('Error al obtener el estado del servidor');
        this.loading = false;
        this.status = false;
        return;
      }

      this.status = true;

      const { disk, services, ram, cpu, processes } = data.output;

      this.diskUsage = { ...disk };
      this.diskUsageChartData = [
        { name: 'Usado', value: parseFloat(disk.used.replace('GB', '')) },
        { name: 'Disponible', value: parseFloat(disk.available.replace('GB', '')) }
      ];

      this.ramUsage = { ...ram };
      this.ramUsageChartData = [
        { name: 'Usado', value: parseFloat(ram.used.replace('GB', '')) },
        { name: 'Disponible', value: parseFloat(ram.available.replace('GB', '')) }
      ];

      this.cpuUsage = { percentage: cpu.used_percentage };
      this.servicesStatus = Object.entries(services).map(([name, status]) => ({ name, status }));
      this.processesStatus = Object.entries(processes).map(([name, status]) => ({ name, status }));
      this.loading = false;
    }, error => {
      this.loading = false;
    });
  }

  getServices(): { name: string, status: string }[] {
    if (!this.status) {
      return [];
    }
    return this.servicesStatus ? this.servicesStatus : [];
  }

  getProcesses(): { name: string, status: string }[] {
    if (!this.status) {
      return [];
    }
    return this.processesStatus ? this.processesStatus : [];
  }

  loadAlert(): Observable<any> {
    return this.http.post<any>(`${this.baseUrl}/image-repositories/server/${this.repositoryId}/get-collection`, {});
  }

  syncRepository() {
    this.http.post(`${this.baseUrl}/image-repositories/server/${this.repositoryId}/sync`, {})
      .subscribe(response => {
        this.toastService.success('Sincronización completada');
        this.load()
      }, error => {
        console.error('Error al sincronizar', error);
        this.toastService.error('Error al sincronizar');
      });
  }

  openImageInfoDialog() {
    this.loadAlert().subscribe(
      response => {
        this.alertMessage = response.output;

        this.dialog.open(ServerInfoDialogComponent, {
          width: '800px',
          data: {
            message: this.alertMessage
          }
        });
      },
      error => {
        console.error('Error al cargar la información del alert', error);
      }
    );
  }
}
