# Sistema de Agendamento com API de Slots

## Implementação Concluída ✅

### Fluxo de Agendamento

1. **Usuário seleciona médico** → Mostra calendário
2. **Usuário seleciona data** → Chama API de slots disponíveis
3. **API calcula horários** → Considera:
   - Disponibilidade do médico (agenda configurada)
   - Exceções (bloqueios e horários extras)
   - Antecedência mínima para agendamento
   - Consultas já agendadas
4. **Usuário seleciona horário** e preenche motivo
5. **Sistema cria agendamento** → Salva no banco

---

## APIs Implementadas

### 1. Calcular Slots Disponíveis

**Endpoint**: `POST /functions/v1/get-available-slots`

**Request**:

```json
{
  "doctor_id": "uuid-do-medico",
  "date": "2025-10-30"
}
```

**Response**:

```json
{
  "slots": [
    {
      "time": "09:00",
      "available": true
    },
    {
      "time": "09:30",
      "available": false
    },
    {
      "time": "10:00",
      "available": true
    }
  ]
}
```

**Código Implementado**:

```typescript
// src/services/appointments/appointmentService.ts
async getAvailableSlots(data: GetAvailableSlotsInput): Promise<GetAvailableSlotsResponse> {
  const response = await apiClient.post<GetAvailableSlotsResponse>(
    "/functions/v1/get-available-slots",
    data
  );
  return response.data;
}
```

---

### 2. Criar Agendamento

**Endpoint**: `POST /rest/v1/appointments`

**Request**:

```json
{
  "doctor_id": "uuid-do-medico",
  "patient_id": "uuid-do-paciente",
  "scheduled_at": "2025-10-30T09:00:00Z",
  "duration_minutes": 30,
  "appointment_type": "presencial",
  "chief_complaint": "Consulta de rotina",
  "created_by": "uuid-do-usuario"
}
```

**Response**:

```json
{
  "id": "uuid-do-agendamento",
  "order_number": "APT-2025-0001",
  "status": "requested",
  ...
}
```

**Código Implementado**:

```typescript
// src/services/appointments/appointmentService.ts
async create(data: CreateAppointmentInput): Promise<Appointment> {
  const payload = {
    ...data,
    duration_minutes: data.duration_minutes || 30,
    appointment_type: data.appointment_type || "presencial",
    status: "requested",
  };

  const response = await apiClient.post<Appointment[]>(
    "/rest/v1/appointments",
    payload,
    {
      headers: {
        Prefer: "return=representation",
      },
    }
  );

  return response.data[0];
}
```

---

## Componente AgendamentoConsulta

### Principais Melhorias

#### Antes ❌

- Calculava slots manualmente no frontend
- Precisava carregar disponibilidade + exceções separadamente
- Lógica complexa de validação no cliente
- Não considerava antecedência mínima
- Não verificava consultas já agendadas

#### Depois ✅

- Usa Edge Function para calcular slots
- API retorna apenas horários realmente disponíveis
- Validações centralizadas no backend
- Considera todas as regras de negócio
- Performance melhorada (menos requisições)

### Código Simplificado

```typescript
// src/components/AgendamentoConsulta.tsx

const calculateAvailableSlots = useCallback(async () => {
  if (!selectedDate || !selectedMedico) {
    setAvailableSlots([]);
    return;
  }

  try {
    const dateStr = format(selectedDate, "yyyy-MM-dd");

    // Chama a Edge Function
    const response = await appointmentService.getAvailableSlots({
      doctor_id: selectedMedico.id,
      date: dateStr,
    });

    if (response && response.slots) {
      // Filtra apenas slots disponíveis
      const available = response.slots
        .filter((slot) => slot.available)
        .map((slot) => slot.time);
      setAvailableSlots(available);
    } else {
      setAvailableSlots([]);
    }
  } catch (error) {
    console.error("Erro ao buscar slots:", error);
    setAvailableSlots([]);
  }
}, [selectedDate, selectedMedico]);

const confirmAppointment = async () => {
  if (!selectedMedico || !selectedDate || !selectedTime || !user) return;

  try {
    const scheduledAt =
      format(selectedDate, "yyyy-MM-dd") + "T" + selectedTime + ":00Z";

    // Cria o agendamento
    const appointment = await appointmentService.create({
      patient_id: user.id,
      doctor_id: selectedMedico.id,
      scheduled_at: scheduledAt,
      duration_minutes: 30,
      appointment_type:
        appointmentType === "online" ? "telemedicina" : "presencial",
      chief_complaint: motivo,
    });

    console.log("Consulta criada:", appointment);
    setBookingSuccess(true);
  } catch (error) {
    setBookingError(error.message);
  }
};
```

---

## Tipos TypeScript

```typescript
// src/services/appointments/types.ts

export interface GetAvailableSlotsInput {
  doctor_id: string;
  date: string; // YYYY-MM-DD
}

export interface TimeSlot {
  time: string; // HH:MM (ex: "09:00")
  available: boolean;
}

export interface GetAvailableSlotsResponse {
  slots: TimeSlot[];
}

export interface CreateAppointmentInput {
  patient_id: string;
  doctor_id: string;
  scheduled_at: string; // ISO 8601
  duration_minutes?: number;
  appointment_type?: "presencial" | "telemedicina";
  chief_complaint?: string;
  patient_notes?: string;
  insurance_provider?: string;
}
```

---

## Benefícios da Implementação

✅ **Performance**: Menos requisições ao backend  
✅ **Confiabilidade**: Validações centralizadas  
✅ **Manutenibilidade**: Lógica de negócio no servidor  
✅ **Escalabilidade**: Edge Functions são otimizadas  
✅ **UX**: Interface mais responsiva e clara  
✅ **Segurança**: Validações no backend não podem ser burladas

---

## Próximos Passos (Opcional)

- [ ] Adicionar loading states mais detalhados
- [ ] Implementar cache de slots (evitar chamadas repetidas)
- [ ] Adicionar retry automático em caso de falha
- [ ] Mostrar motivo quando slot não está disponível
- [ ] Implementar notificações (SMS/Email) após agendamento

---

## Testando

### 1. Selecione um médico

### 2. Selecione uma data futura

### 3. Verifique os slots disponíveis

### 4. Selecione um horário

### 5. Preencha o motivo

### 6. Confirme o agendamento

**Logs no Console**:

```
[AppointmentService] Buscando slots para: {doctor_id, date}
[AppointmentService] Slots recebidos: 12 slots
[AppointmentService] Criando agendamento...
[AppointmentService] Consulta criada: {id, order_number, ...}
```

---

## Data de Implementação

**30 de Outubro de 2025**

Implementado por: GitHub Copilot  
Revisado por: Equipe RiseUp Squad 18
