import { Injectable } from '@angular/core';
import {HttpClient, HttpParams} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { UnidadOrganizativa } from '../model/model';
import { ConfigService } from '@services/config.service';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  baseUrl: string;
  private apiUrl: string;
  private clientsUrl: string;

  constructor(private http: HttpClient, private configService: ConfigService) {
    this.baseUrl = this.configService.apiUrl;
    this.apiUrl = `${this.baseUrl}/organizational-units?page=1&itemsPerPage=1000`;
    this.clientsUrl = `${this.baseUrl}/clients`;
  }

  getOrganizationalUnits(search: string = ''): Observable<UnidadOrganizativa[]> {
    let url = `${this.apiUrl}&type=organizational-unit`;
    if (search) {
      url += `&name=${encodeURIComponent(search)}`;
    }

    return this.http.get<any>(url).pipe(
      map(response => {
        if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
          return response['hydra:member'];
        } else {
          throw new Error('Unexpected response format');
        }
      }),
      catchError(error => {
        console.error('Error fetching unidades organizativas', error);
        return throwError(error);
      })
    );
  }

  getChildren(id: string): Observable<any[]> {
    return this.http.get<any>(`${this.apiUrl}&parent.id=${id}`).pipe(
      map(response => {
        if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
          return response['hydra:member']
        } else {
          throw new Error('Unexpected response format');
        }
      }),
      catchError(error => {
        console.error('Error fetching children', error);
        return throwError(error);
      })
    );
  }

  getClients(id: string): Observable<any[]> {
    return this.http.get<any>(`${this.clientsUrl}&organizationalUnit.id=${id}`).pipe(
      map(response => {
        if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
          return response['hydra:member']
        } else {
          throw new Error('Unexpected response format');
        }
      }),
      catchError(error => {
        console.error('Error fetching clients', error);
        return throwError(error);
      })
    );
  }

  getHardwareProfiles():  Observable<any[]> {
    const url = `${this.baseUrl}/hardware-profiles`;
    return this.http.get<any>(url).pipe(
      map(response => {
        if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
          return response['hydra:member']
        } else {
          throw new Error('Unexpected response format');
        }
      }),
      catchError(error => {
        console.error('Error fetching clients', error);
        return throwError(error);
      })
    );
  }

  getOgLives(): Observable<any[]> {
    const url = `${this.baseUrl}/og-lives`;
    return this.http.get<any>(url).pipe(
      map(response => {
        if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
          return response['hydra:member']
        } else {
          throw new Error('Unexpected response format');
        }
      }),
      catchError(error => {
        console.error('Error fetching clients', error);
        return throwError(error);
      })
    );
  }

  getRepositories(): Observable<any[]> {
    const url = `${this.baseUrl}/image-repositories`;
    return this.http.get<any>(url).pipe(
      map(response => {
        if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
          return response['hydra:member']
        } else {
          throw new Error('Unexpected response format');
        }
      }),
      catchError(error => {
        console.error('Error fetching clients', error);
        return throwError(error);
      })
    );
  }

  deleteElement(uuid: string, type: string): Observable<void> {
    const url = type === 'client'
      ? `${this.baseUrl}/clients/${uuid}`
      : `${this.baseUrl}/organizational-units/${uuid}`;

    console.log('DELETE URL:', url); // Depuración
    return this.http.delete<void>(url).pipe(
      catchError(error => {
        console.error('Error deleting element', error);
        return throwError(error);
      })
    );
  }


  changeParent(uuid: string): Observable<void> {
    const url = `${this.baseUrl}/organizational-units/${uuid}/change-parent`;
    // @ts-ignore
    return this.http.post<void>(url).pipe(
      catchError(error => {
        console.error('Error deleting element', error);
        return throwError(error);
      })
    );
  }

  getFilteredResults(filter1: string, filter2: string, filterName: string, filterIP: string, filterMAC: string, page: number, pageSize: number): Observable<any> {
    let params = new HttpParams();

    if (filter2 && filter2 !== 'none') {
      params = params.set('type', filter2);
    }
    if (filterName) {
      params = params.set('name', filterName);
    }

    if (filterIP) {
      params = params.set('ip', filterIP);
    }

    if (filterMAC) {
      params = params.set('mac', filterMAC);
    }

    params = params.set('page', page.toString());
    params = params.set('itemsPerPage', pageSize.toString());

    const url = filter1 === 'client' ? this.clientsUrl : this.apiUrl;

    return this.http.get<any>(url, { params }).pipe(
      map(response => {
        if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
          return {
            results: response['hydra:member'],
            total: response['hydra:totalItems'] || response['hydra:member'].length
          };
        } else {
          throw new Error('Unexpected response format');
        }
      }),
      catchError(error => {
        console.error('Error fetching data', error);
        return throwError(error);
      })
    );
  }

  getFilters(): Observable<any> {
    return this.http.get<any>(`${this.baseUrl}/views?page=1&itemsPerPage=30`).pipe(
      map(response => {
        if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
          return response['hydra:member'];
        } else {
          throw new Error('Unexpected response format');
        }
      }),
      catchError(error => {
        console.error('Error fetching filters', error);
        return throwError(error);
      })
    );
  }

  getFilter(id: string): Observable<any> {
    return this.http.get<any>(`${this.baseUrl}/views/` + id).pipe(
      map(response => {


        if (response.name && response.filters) {
          return response;
        } else {
          throw new Error('Unexpected response format');
        }
      }),
      catchError(error => {
        console.error('Error fetching filters', error);
        return throwError(error);
      })
    );
  }

  getOrganizationalUnitById(id: string): Observable<any> {
    const url = `${this.baseUrl}/organizational-units/${id}`;
    return this.http.get<any>(url).pipe(
      catchError(error => {
        console.error('Error fetching organizational unit', error);
        return throwError(error);
      })
    );
  }

  getOrganizationalUnitPath(unit: UnidadOrganizativa, units: UnidadOrganizativa[]): string {
    const path: string[] = [];
    let currentUnit: UnidadOrganizativa | undefined = unit;

    while (currentUnit) {
      path.unshift(currentUnit.name);
      currentUnit = units.find(u => u['@id'] === currentUnit?.parent?.['@id']);
    }

    return path.join(' / ');
  }
}
