# Anuncios (AdMob)

El módulo de anuncios envuelve **Google AdMob** (`google_mobile_ads`) y soporta los
cuatro formatos de AdMob: **banner, interstitial, rewarded y rewarded-interstitial**.

- **Solo nativo.** AdMob no tiene SDK web, así que en web toda llamada de anuncio es
  un no-op silencioso y `KasyAdBanner` no renderiza nada. Esto es automático —
  siempre es seguro usar código de anuncios en widgets compartidos.
- **Funciona sin configurar nada.** Hasta que definas ids reales, los builds de debug
  muestran los **anuncios de prueba** oficiales de Google. Los builds de release
  nunca muestran anuncios de prueba.
- **Premium = sin anuncios.** Los usuarios con suscripción activa no ven los formatos
  automáticos (banner + interstitial). Los formatos recompensados siguen disponibles,
  porque el usuario elige verlos.

> ⚠ Solo puedes crear ad unit ids reales después de registrar el app en la consola de
> AdMob (y normalmente publicarlo). Publica una primera versión sin ids reales
> (anuncios de prueba) y agrégalos después.

## Activar / desactivar

Los anuncios vienen en `kasy new` (modo Rápido). Para agregarlos a un proyecto
existente:

```
kasy add ads
```

El comando pregunta tus **app ids** de AdMob (opcional — en blanco mantiene los ids
de prueba), configura lo nativo, la dependencia `google_mobile_ads` y la flag
`withAds`.

Define los ids después en cualquier momento con `kasy configure` (aparece una sección
"Anuncios (AdMob)").

## Configuración

Hay dos tipos de valor:

1. **App id** (uno por plataforma) — nativo, en tiempo de build. Vive en
   `android/app/src/main/res/values/strings.xml` (`admob_app_id`) y en
   `ios/Runner/Info.plist` (`GADApplicationIdentifier`). Configúralo con
   `kasy configure` / `kasy add ads`. El SDK lo exige — el app crashea al abrir sin
   un app id válido (el template ya trae el app id de prueba de Google).
2. **Ad unit ids** (uno por formato, por plataforma) — env del cliente, leídos en
   runtime del `.env`:

```
ADMOB_ANDROID_BANNER=
ADMOB_IOS_BANNER=
ADMOB_ANDROID_INTERSTITIAL=
ADMOB_IOS_INTERSTITIAL=
ADMOB_ANDROID_REWARDED=
ADMOB_IOS_REWARDED=
ADMOB_ANDROID_REWARDED_INTERSTITIAL=
ADMOB_IOS_REWARDED_INTERSTITIAL=
```

Déjalos en blanco para usar anuncios de prueba durante el desarrollo; completa los
ids reales antes de un build de release.

## Usar anuncios en tu app

Todo pasa por `googleAdsProvider`
(`lib/core/ads/ads_provider.dart`). El SDK ya se inicializa por ti en `main.dart`.

### Banner

Coloca el widget donde quieras — lee su ad unit, se oculta para usuarios premium y
no renderiza nada en web:

```dart
import 'package:kasy_kit/core/ads/widgets/kasy_ad_banner.dart';

const KasyAdBanner();                          // banner estándar
const KasyAdBanner(size: KasyAdBannerSize.mediumRectangle);
```

### Interstitial

```dart
final ads = ref.read(googleAdsProvider.notifier);

// Muestra respetando un cooldown para no bombardear al usuario (por defecto 50s):
await ads.showInterstitialIfElapsed();

// O fuerza uno:
await ads.showInterstitial();
```

### Rewarded / Rewarded-interstitial

El usuario ve un anuncio y gana una recompensa. La recompensa también se verifica en
el servidor (ver SSV abajo) — nunca concedas nada valioso solo con el callback del
cliente.

```dart
await ads.showRewarded(
  onReward: (reward) {
    // Solo UI optimista; la concesión real es trabajo del servidor (SSV).
    debugPrint('Earned ${reward.amount} ${reward.type}');
  },
);

await ads.showRewardedInterstitial(onReward: (reward) { /* … */ });
```

## Verificación en el servidor (SSV) — recompensas seguras

Para los formatos recompensados, AdMob llama a **tu backend** para confirmar que el
usuario realmente vio el anuncio, y entonces tu backend concede la recompensa. Es la
única parte de los anuncios que toca el servidor, y es lo que hace las recompensas a
prueba de fraude.

El app ya envía el id del usuario conectado (`setServerSideOptions`), así que tu
endpoint sabe a quién acreditar. Solo necesitas desplegar el endpoint y configurar su
URL en la consola de AdMob (en cada ad unit recompensado → SSV callback).

| Backend | Endpoint | Referencia |
|---|---|---|
| Firebase | Cloud Function `ads-verifyAdReward` | `functions/src/ads/ads_functions.ts` |
| Supabase | Edge Function `verify-ad-reward` | + SQL `grant_ad_reward()` (migration) |
| API (tu servidor) | implementas `GET /ads/verify-reward` | contrato en el README del API |

Los tres verifican la firma ECDSA contra las claves públicas de Google
(`https://gstatic.com/admob/reward/verifier-keys.json`) y conceden la recompensa de
forma idempotente (con clave `transaction_id`). La concesión en sí (monedas, vidas,
pase sin anuncios…) es un hook claramente marcado que tú personalizas.

No se necesita ningún secret — la verificación usa las claves públicas de Google.

## Quitar los anuncios

`kasy remove ads` (o no seleccionar la feature) elimina la dependencia, el código de
`lib/core/ads`, la config nativa y la flag `withAds`.
