/** * Serviço de Agendamentos */ import { apiClient } from "../api/client"; import type { Appointment, CreateAppointmentInput, UpdateAppointmentInput, AppointmentFilters, GetAvailableSlotsInput, GetAvailableSlotsResponse, } from "./types"; class AppointmentService { private readonly basePath = "/appointments"; /** * Busca horários disponíveis de um médico * POST /functions/v1/get-available-slots */ async getAvailableSlots( data: GetAvailableSlotsInput ): Promise { try { console.log("[AppointmentService] Chamando get-available-slots:", data); // Usa callFunction para chamar a Edge Function const response = await apiClient.callFunction( "get-available-slots", data ); console.log( "[AppointmentService] Resposta get-available-slots:", response.data ); return response.data; } catch (error: any) { console.error("[AppointmentService] ❌ Erro ao buscar slots:"); console.error("[AppointmentService] Status:", error?.response?.status); console.error( "[AppointmentService] Response Data:", JSON.stringify(error?.response?.data, null, 2) ); console.error("[AppointmentService] Message:", error?.message); console.error( "[AppointmentService] Input enviado:", JSON.stringify(data, null, 2) ); throw new Error( error?.response?.data?.message || error?.message || "Erro ao buscar horários disponíveis" ); } } /** * Lista agendamentos com filtros opcionais */ async list(filters?: AppointmentFilters): Promise { const params: Record = {}; if (filters?.doctor_id) { params["doctor_id"] = `eq.${filters.doctor_id}`; } if (filters?.patient_id) { params["patient_id"] = `eq.${filters.patient_id}`; } if (filters?.status) { params["status"] = `eq.${filters.status}`; } if (filters?.scheduled_at) { params["scheduled_at"] = filters.scheduled_at; } if (filters?.limit) { params["limit"] = filters.limit.toString(); } if (filters?.offset) { params["offset"] = filters.offset.toString(); } if (filters?.order) { params["order"] = filters.order; } const response = await apiClient.get(this.basePath, { params, }); return response.data; } /** * Busca agendamento por ID */ async getById(id: string): Promise { const response = await apiClient.get( `${this.basePath}?id=eq.${id}` ); if (response.data && response.data.length > 0) { return response.data[0]; } throw new Error("Agendamento não encontrado"); } /** * Cria novo agendamento * POST /rest/v1/appointments * Nota: order_number é gerado automaticamente (APT-YYYY-NNNN) */ async create(data: CreateAppointmentInput): Promise { try { console.log("[AppointmentService] Criando agendamento:", data); // Adiciona created_by se não estiver presente const payload = { ...data, duration_minutes: data.duration_minutes || 30, appointment_type: data.appointment_type || "presencial", status: "requested", }; console.log("[AppointmentService] Payload final:", payload); const response = await apiClient.post( this.basePath, payload, { headers: { Prefer: "return=representation", }, } ); console.log("[AppointmentService] Resposta da API:", response.data); if (response.data && response.data.length > 0) { return response.data[0]; } throw new Error("Erro ao criar agendamento"); } catch (error: any) { console.error("[AppointmentService] Erro ao criar agendamento:", { error, message: error?.message, response: error?.response, data: error?.response?.data, status: error?.response?.status, }); throw error; } } /** * Atualiza agendamento existente */ async update(id: string, data: UpdateAppointmentInput): Promise { const response = await apiClient.patch( `${this.basePath}?id=eq.${id}`, data ); if (response.data && response.data.length > 0) { return response.data[0]; } throw new Error("Agendamento não encontrado"); } /** * Deleta agendamento */ async delete(id: string): Promise { await apiClient.delete(`${this.basePath}?id=eq.${id}`); } } export const appointmentService = new AppointmentService();