import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable, of } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; import { AgentFamilyMember } from '../interfaces/agent'; import { environment } from 'src/environments/environment.development'; const USE_SERVER = true; const API_BASE = '/api/v1/agent-family-members'; // Interface to match the API response structure interface AgentFamilyMemberApiResponse { id: number; agentId: number; nom: string; statut?: string; dateNaissance?: string; sexe?: string; } @Injectable({ providedIn: 'root' }) export class AgentFamilyMemberService { private apiUrl = environment.apiBaseUrl + API_BASE; constructor(private http: HttpClient) {} // Helper method to get ngrok bypass headers private getNgrokHeaders(): Record { const isNgrok = environment.apiBaseUrl.includes('ngrok-free.app') || environment.apiBaseUrl.includes('ngrok.io') || environment.apiBaseUrl.includes('ngrok'); return isNgrok ? { 'ngrok-skip-browser-warning': 'true' } : {}; } // Transform API response to AgentFamilyMember private transformMember(apiMember: AgentFamilyMemberApiResponse): AgentFamilyMember { return { id: String(apiMember.id), agentId: String(apiMember.agentId), nom: apiMember.nom, statut: apiMember.statut, dateNaissance: apiMember.dateNaissance, sexe: apiMember.sexe as 'M' | 'F' | undefined, }; } // Helper method to convert date string to LocalDateTime format (YYYY-MM-DDTHH:mm:ss) private formatDateForApi(dateStr: string | undefined): string | undefined { if (!dateStr) return undefined; // If already in ISO format with time, return as is if (dateStr.includes('T') || dateStr.includes(' ')) { return dateStr; } // If only date (YYYY-MM-DD), add time component if (dateStr.match(/^\d{4}-\d{2}-\d{2}$/)) { return `${dateStr}T00:00:00`; } return dateStr; } // Transform AgentFamilyMember to API payload private transformToApiPayload(member: Partial): any { const payload: any = {}; if (member.agentId !== undefined) payload.agentId = Number(member.agentId); if (member.nom !== undefined) payload.nom = member.nom; if (member.statut !== undefined) payload.statut = member.statut; if (member.dateNaissance !== undefined) payload.dateNaissance = this.formatDateForApi(member.dateNaissance); if (member.sexe !== undefined) payload.sexe = member.sexe; return payload; } // GET /api/v1/agent-family-members/{id} - Get by ID getById(id: string): Observable { if (USE_SERVER) { return this.http .get(`${this.apiUrl}/${id}`, { headers: this.getNgrokHeaders() }) .pipe( map((apiMember) => this.transformMember(apiMember)), catchError((err) => { console.error(`Error fetching agent family member ${id}:`, err); return of(undefined); }) ); } return of(undefined); } // GET /api/v1/agent-family-members - List all list(): Observable { if (USE_SERVER) { return this.http .get(this.apiUrl, { headers: this.getNgrokHeaders() }) .pipe( map((list) => list.map((apiMember) => this.transformMember(apiMember))), catchError((err) => { console.error('Error fetching agent family members:', err); return of([]); }) ); } return of([]); } // POST /api/v1/agent-family-members - Create create(payload: Omit): Observable { if (USE_SERVER) { const apiPayload = this.transformToApiPayload(payload); return this.http .post(this.apiUrl, apiPayload, { headers: this.getNgrokHeaders() }) .pipe( map((apiMember) => this.transformMember(apiMember)), catchError((err) => { console.error('Error creating agent family member:', err); throw err; }) ); } throw new Error('Server mode is required'); } // PUT /api/v1/agent-family-members/{id} - Update update(id: string, payload: Partial): Observable { if (USE_SERVER) { const apiPayload = this.transformToApiPayload(payload); return this.http .put(`${this.apiUrl}/${id}`, apiPayload, { headers: this.getNgrokHeaders() }) .pipe( map((apiMember) => this.transformMember(apiMember)), catchError((err) => { console.error(`Error updating agent family member ${id}:`, err); return of(undefined); }) ); } return of(undefined); } // DELETE /api/v1/agent-family-members/{id} - Delete delete(id: string): Observable { if (USE_SERVER) { return this.http .delete(`${this.apiUrl}/${id}`, { headers: this.getNgrokHeaders() }) .pipe( map(() => true), catchError((err) => { console.error(`Error deleting agent family member ${id}:`, err); return of(false); }) ); } return of(false); } // GET /api/v1/agent-family-members/statut/{statut} - List by statut getByStatut(statut: string): Observable { if (USE_SERVER) { return this.http .get(`${this.apiUrl}/statut/${statut}`, { headers: this.getNgrokHeaders() }) .pipe( map((list) => list.map((apiMember) => this.transformMember(apiMember))), catchError((err) => { console.error(`Error fetching agent family members by statut ${statut}:`, err); return of([]); }) ); } return of([]); } // GET /api/v1/agent-family-members/sexe/{sexe} - List by sexe getBySexe(sexe: 'M' | 'F'): Observable { if (USE_SERVER) { return this.http .get(`${this.apiUrl}/sexe/${sexe}`, { headers: this.getNgrokHeaders() }) .pipe( map((list) => list.map((apiMember) => this.transformMember(apiMember))), catchError((err) => { console.error(`Error fetching agent family members by sexe ${sexe}:`, err); return of([]); }) ); } return of([]); } // GET /api/v1/agent-family-members/search - Search by keyword search(query: string): Observable { if (USE_SERVER) { return this.http .get(`${this.apiUrl}/search`, { params: { q: query.trim() }, headers: this.getNgrokHeaders(), }) .pipe( map((list) => list.map((apiMember) => this.transformMember(apiMember))), catchError((err) => { console.error(`Error searching agent family members with query ${query}:`, err); return of([]); }) ); } return of([]); } // GET /api/v1/agent-family-members/nom/{nom} - List by nom getByNom(nom: string): Observable { if (USE_SERVER) { return this.http .get(`${this.apiUrl}/nom/${nom}`, { headers: this.getNgrokHeaders() }) .pipe( map((list) => list.map((apiMember) => this.transformMember(apiMember))), catchError((err) => { console.error(`Error fetching agent family members by nom ${nom}:`, err); return of([]); }) ); } return of([]); } // Get family members by agentId (filter from list) getByAgentId(agentId: string): Observable { if (USE_SERVER) { return this.list().pipe( map((list) => list.filter((member) => member.agentId === agentId)), catchError((err) => { console.error(`Error fetching agent family members by agentId ${agentId}:`, err); return of([]); }) ); } return of([]); } }