import { API_BASE_URL } from './config'; // Types para el sistema de emergencias export interface Incident { id: string; type: 'theft' | 'assault' | 'accident' | 'medical' | 'other'; priority: 'low' | 'medium' | 'high' | 'critical'; status: 'pending' | 'assigned' | 'in_progress' | 'resolved' | 'closed'; title: string; description: string; location: { latitude: number; longitude: number; address?: string; }; reportedBy: { id: string; name: string; phone?: string; }; assignedOfficer?: { id: string; name: string; badge: string; }; createdAt: string; updatedAt: string; resolvedAt?: string; } export interface EmergencyAlert { id: string; type: 'panic' | 'medical' | 'fire' | 'security' | 'natural_disaster'; priority: 'high' | 'critical'; status: 'active' | 'resolved'; location: { latitude: number; longitude: number; address?: string; }; user: { id: string; name: string; phone?: string; }; createdAt: string; deactivatedAt?: string; } export interface Officer { id: string; name: string; badge: string; rank: string; status: 'available' | 'busy' | 'off_duty'; location?: { latitude: number; longitude: number; }; phone: string; assignedIncidents: number; } export interface SecurityStats { totalIncidents: number; activeIncidents: number; resolvedToday: number; averageResponseTime: number; activeAlerts: number; availableOfficers: number; incidentsByType: Record; incidentsByPriority: Record; } class EmergencyApiService { private getAuthHeaders() { const token = localStorage.getItem('karibeo-token') || localStorage.getItem('karibeo_token'); return { 'Content-Type': 'application/json', 'Authorization': token ? `Bearer ${token}` : '', }; } // === INCIDENTES === /** * Reportar un nuevo incidente */ async createIncident(incidentData: { type: string; priority: string; title: string; description: string; location: { latitude: number; longitude: number; address?: string; }; }): Promise { const response = await fetch(`${API_BASE_URL}/security/incidents`, { method: 'POST', headers: this.getAuthHeaders(), body: JSON.stringify(incidentData), }); if (!response.ok) { throw new Error(`Error creating incident: ${response.statusText}`); } return response.json(); } /** * Obtener todos los incidentes (solo officers/admin) */ async getAllIncidents(filters?: { status?: string; type?: string; priority?: string; page?: number; limit?: number; }): Promise<{ incidents: Incident[]; total: number; page: number; limit: number }> { const params = new URLSearchParams(); if (filters?.status) params.append('status', filters.status); if (filters?.type) params.append('type', filters.type); if (filters?.priority) params.append('priority', filters.priority); if (filters?.page) params.append('page', filters.page.toString()); if (filters?.limit) params.append('limit', filters.limit.toString()); const response = await fetch(`${API_BASE_URL}/security/incidents?${params}`, { method: 'GET', headers: this.getAuthHeaders(), }); if (!response.ok) { throw new Error(`Error fetching incidents: ${response.statusText}`); } return response.json(); } /** * Obtener incidentes asignados al oficial actual */ async getMyIncidents(): Promise { const response = await fetch(`${API_BASE_URL}/security/incidents/my`, { method: 'GET', headers: this.getAuthHeaders(), }); if (!response.ok) { throw new Error(`Error fetching my incidents: ${response.statusText}`); } return response.json(); } /** * Obtener incidente por ID */ async getIncidentById(id: string): Promise { const response = await fetch(`${API_BASE_URL}/security/incidents/${id}`, { method: 'GET', headers: this.getAuthHeaders(), }); if (!response.ok) { throw new Error(`Error fetching incident: ${response.statusText}`); } return response.json(); } /** * Actualizar incidente */ async updateIncident(id: string, updateData: Partial): Promise { const response = await fetch(`${API_BASE_URL}/security/incidents/${id}`, { method: 'PATCH', headers: this.getAuthHeaders(), body: JSON.stringify(updateData), }); if (!response.ok) { throw new Error(`Error updating incident: ${response.statusText}`); } return response.json(); } /** * Asignar incidente a oficial (solo admin) */ async assignIncident(incidentId: string, officerId: string): Promise { const response = await fetch(`${API_BASE_URL}/security/incidents/${incidentId}/assign/${officerId}`, { method: 'PATCH', headers: this.getAuthHeaders(), }); if (!response.ok) { throw new Error(`Error assigning incident: ${response.statusText}`); } return response.json(); } // === ALERTAS DE EMERGENCIA === /** * Crear alerta de emergencia (Botón de pánico) */ async createEmergencyAlert(alertData: { type: string; location: { latitude: number; longitude: number; address?: string; }; message?: string; }): Promise { const response = await fetch(`${API_BASE_URL}/security/emergency-alerts`, { method: 'POST', headers: this.getAuthHeaders(), body: JSON.stringify(alertData), }); if (!response.ok) { throw new Error(`Error creating emergency alert: ${response.statusText}`); } return response.json(); } /** * Obtener alertas de emergencia activas (solo officers/admin) */ async getActiveEmergencyAlerts(): Promise { const response = await fetch(`${API_BASE_URL}/security/emergency-alerts`, { method: 'GET', headers: this.getAuthHeaders(), }); if (!response.ok) { throw new Error(`Error fetching emergency alerts: ${response.statusText}`); } return response.json(); } /** * Desactivar alerta de emergencia */ async deactivateEmergencyAlert(id: string): Promise { const response = await fetch(`${API_BASE_URL}/security/emergency-alerts/${id}/deactivate`, { method: 'PATCH', headers: this.getAuthHeaders(), }); if (!response.ok) { throw new Error(`Error deactivating emergency alert: ${response.statusText}`); } return response.json(); } // === OFICIALES/POLITUR === /** * Obtener oficiales disponibles */ async getAvailableOfficers(): Promise { const response = await fetch(`${API_BASE_URL}/security/officers/available`, { method: 'GET', headers: this.getAuthHeaders(), }); if (!response.ok) { throw new Error(`Error fetching available officers: ${response.statusText}`); } return response.json(); } /** * Actualizar estado de servicio del oficial */ async updateOfficerStatus(id: string, status: 'available' | 'busy' | 'off_duty'): Promise { const response = await fetch(`${API_BASE_URL}/security/officers/${id}/status`, { method: 'PATCH', headers: this.getAuthHeaders(), body: JSON.stringify({ status }), }); if (!response.ok) { throw new Error(`Error updating officer status: ${response.statusText}`); } return response.json(); } // === ESTADÍSTICAS === /** * Obtener estadísticas de seguridad (solo admin) */ async getSecurityStats(): Promise { const response = await fetch(`${API_BASE_URL}/security/stats`, { method: 'GET', headers: this.getAuthHeaders(), }); if (!response.ok) { throw new Error(`Error fetching security stats: ${response.statusText}`); } return response.json(); } // === GEOLOCALIZACIÓN === /** * Obtener ubicación actual del usuario */ getCurrentLocation(): Promise<{ latitude: number; longitude: number }> { return new Promise((resolve, reject) => { if (!navigator.geolocation) { reject(new Error('La geolocalización no está soportada en este navegador')); return; } navigator.geolocation.getCurrentPosition( (position) => { resolve({ latitude: position.coords.latitude, longitude: position.coords.longitude, }); }, (error) => { reject(new Error(`Error obteniendo ubicación: ${error.message}`)); }, { enableHighAccuracy: true, timeout: 10000, maximumAge: 60000, } ); }); } /** * Activar botón de pánico con ubicación automática */ async activatePanicButton(type: 'panic' | 'medical' | 'security' = 'panic'): Promise { try { const location = await this.getCurrentLocation(); return await this.createEmergencyAlert({ type, location, message: `Alerta de pánico activada desde la aplicación`, }); } catch (error) { // Si no se puede obtener la ubicación, crear alerta sin ubicación específica return await this.createEmergencyAlert({ type, location: { latitude: 0, longitude: 0, address: 'Ubicación no disponible' }, message: `Alerta de pánico activada - ubicación no disponible`, }); } } } export const emergencyApi = new EmergencyApiService();