# Recuperación de Contraseña

Endpoints del flujo de recuperación de contraseña en DeportesCam.
El proceso parte del username del usuario, envía un código de verificación
al canal registrado y permite establecer una nueva contraseña.

---

## POST /deportescam/recuperacion/buscar-usuario

Busca al usuario en `pad_registropadel` por su `username` y retorna el
`idRegistroPadel` (en Base64) junto con los canales de contacto disponibles.

**Autenticación:** No requerida  
**Middleware:** `seguridadFSG`, `throttle:60,1`

### Body (JSON)

| Campo | Tipo | Requerido | Descripción | Ejemplo |
|-------|------|-----------|-------------|---------|
| `username` | string | Sí | Nombre de usuario registrado | `GAMP230618` |

```json
{
  "username": "GAMP230618"
}
```

### Respuestas

#### 200 — Usuario encontrado

```json
{
  "success": true,
  "message": "Usuario encontrado.",
  "data": {
    "idRegistroPadel": "MQ==",
    "tieneCorreo": true,
    "tieneCelular": false
  }
}
```

| Campo | Tipo | Descripción |
|-------|------|-------------|
| `success` | bool | `true` cuando el usuario existe y está activo |
| `message` | string | Mensaje descriptivo del resultado |
| `data.idRegistroPadel` | string | ID del registro codificado en **Base64** |
| `data.tieneCorreo` | bool | `true` si tiene correo electrónico registrado |
| `data.tieneCelular` | bool | `true` si tiene número de celular registrado |

> **Nota:** `idRegistroPadel` se retorna en Base64 por seguridad. Para obtener el ID numérico:
> `atob("MQ==")` → `"1"` (JavaScript) / `base64_decode("MQ==")` → `"1"` (PHP)

#### 422 — Usuario no encontrado

```json
{
  "success": false,
  "message": "El nombre de usuario no existe."
}
```

#### 422 — Cuenta bloqueada

```json
{
  "success": false,
  "message": "La cuenta está bloqueada. Contacte a soporte."
}
```

#### 422 — Cuenta inactiva

```json
{
  "success": false,
  "message": "La cuenta no está activa."
}
```

#### 422 — Campo requerido faltante

```json
{
  "success": false,
  "status": 422,
  "message": "Tienes errores de validación",
  "errors": {
    "username": ["El campo username es requerido."]
  }
}
```

#### 500 — Error interno

```json
{
  "success": false,
  "message": "Descripción del error interno."
}
```

---

## POST /deportescam/recuperacion/enviar-codigo

Genera un código de verificación de **6 caracteres alfanuméricos** (mayúsculas),
lo guarda en `pad_registropadel` (`registroPadelToken`) con TTL de 10 minutos
y lo envía por el canal indicado.

**Autenticación:** No requerida  
**Middleware:** `seguridadFSG`, `throttle:60,1`

### Body (JSON)

| Campo | Tipo | Requerido | Descripción | Ejemplo |
|-------|------|-----------|-------------|---------|
| `idRegistroPadel` | string | Sí | ID del registro en **Base64** (obtenido de `buscar-usuario`) | `MQ==` |
| `tipo` | string | Sí | Canal de envío: `email` o `whatsapp` | `email` |

```json
{
  "idRegistroPadel": "MQ==",
  "tipo": "email"
}
```

### Respuestas

#### 200 — Código enviado por correo

```json
{
  "success": true,
  "message": "Código enviado al correo electrónico."
}
```

#### 200 — Código generado (WhatsApp pendiente de plantilla)

```json
{
  "success": true,
  "message": "Código generado. La notificación por WhatsApp estará disponible próximamente."
}
```

#### 422 — Usuario sin correo registrado

```json
{
  "success": false,
  "message": "El usuario no tiene correo electrónico registrado."
}
```

#### 422 — Registro no existe

```json
{
  "success": false,
  "message": "El registro no existe."
}
```

#### 422 — Campos faltantes o tipo inválido

```json
{
  "success": false,
  "status": 422,
  "message": "Tienes errores de validación",
  "errors": {
    "tipo": ["El tipo debe ser email o whatsapp."]
  }
}
```

#### 500 — Error interno

```json
{
  "success": false,
  "message": "Descripción del error interno."
}
```

---

## POST /deportescam/recuperacion/reenviar-codigo

Invalida el código previo del usuario, genera uno nuevo y lo reenvía por
el canal indicado. Usar cuando el código anterior expiró o no fue recibido.
La lógica de envío es idéntica a `/enviar-codigo`.

**Autenticación:** No requerida  
**Middleware:** `seguridadFSG`, `throttle:60,1`

### Body (JSON)

| Campo | Tipo | Requerido | Descripción | Ejemplo |
|-------|------|-----------|-------------|---------|
| `idRegistroPadel` | string | Sí | ID del registro en **Base64** | `MQ==` |
| `tipo` | string | Sí | Canal de envío: `email` o `whatsapp` | `email` |

```json
{
  "idRegistroPadel": "MQ==",
  "tipo": "email"
}
```

### Respuestas

#### 200 — Código reenviado

```json
{
  "success": true,
  "message": "Código enviado al correo electrónico."
}
```

#### 422 / 500

Mismas respuestas de error que `/enviar-codigo`.

---

## POST /deportescam/recuperacion/validar-codigo

Verifica el código de 6 caracteres contra `registroPadelToken` en
`pad_registropadel`. Si es correcto lo elimina (uso único — si el usuario
regresa debe solicitar uno nuevo).

**Autenticación:** No requerida  
**Middleware:** `seguridadFSG`, `throttle:60,1`

### Body (JSON)

| Campo | Tipo | Requerido | Descripción | Ejemplo |
|-------|------|-----------|-------------|---------|
| `idRegistroPadel` | string | Sí | ID del registro en **Base64** | `MQ==` |
| `codigo` | string | Sí | Código de verificación de exactamente 6 caracteres | `A1B2C3` |

```json
{
  "idRegistroPadel": "MQ==",
  "codigo": "A1B2C3"
}
```

### Respuestas

#### 200 — Código correcto

```json
{
  "success": true,
  "message": "Código verificado correctamente."
}
```

#### 422 — Código incorrecto o expirado

```json
{
  "success": false,
  "message": "El código es incorrecto o ha expirado."
}
```

#### 422 — Campos faltantes o código con longitud incorrecta

```json
{
  "success": false,
  "status": 422,
  "message": "Tienes errores de validación",
  "errors": {
    "codigo": ["El código debe tener exactamente 6 caracteres."]
  }
}
```

#### 500 — Error interno

```json
{
  "success": false,
  "message": "Descripción del error interno."
}
```

---

## POST /deportescam/recuperacion/restablecer-password

Establece la nueva contraseña del usuario. Debe llamarse solo después de que
`validar-codigo` haya respondido con `success: true`. Al finalizar el usuario
**no queda autenticado** — debe iniciar sesión con las nuevas credenciales.

**Autenticación:** No requerida  
**Middleware:** `seguridadFSG`, `throttle:60,1`

### Body (JSON)

| Campo | Tipo | Requerido | Descripción | Ejemplo |
|-------|------|-----------|-------------|---------|
| `idRegistroPadel` | string | Sí | ID del registro en **Base64** | `MQ==` |
| `password` | string | Sí | Mín. 8 chars, mayúsculas, minúsculas, número y carácter especial | `MiPass1!` |
| `password_confirmation` | string | Sí | Confirmación de contraseña | `MiPass1!` |

```json
{
  "idRegistroPadel": "MQ==",
  "password": "MiPass1!",
  "password_confirmation": "MiPass1!"
}
```

### Respuestas

#### 200 — Contraseña restablecida

```json
{
  "success": true,
  "message": "Contraseña restablecida correctamente. Inicie sesión para continuar."
}
```

#### 422 — Contraseña no cumple el formato

```json
{
  "success": false,
  "status": 422,
  "message": "Tienes errores de validación",
  "errors": {
    "password": ["La contraseña debe tener mayúsculas, minúsculas, números y al menos un carácter especial."]
  }
}
```

#### 422 — Contraseñas no coinciden

```json
{
  "success": false,
  "status": 422,
  "message": "Tienes errores de validación",
  "errors": {
    "password": ["Las contraseñas no coinciden."]
  }
}
```

#### 422 — Registro no existe

```json
{
  "success": false,
  "message": "El registro no existe."
}
```

#### 500 — Error interno

```json
{
  "success": false,
  "message": "Descripción del error interno."
}
```
