<?php

namespace App\Notifications\Channels;

use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

/**
 * Envío vía Expo Push (app móvil). Requiere token registrado en mobile_expo_push_tokens.
 *
 * @see https://docs.expo.dev/push-notifications/sending-notifications/
 */
class ExpoPushChannel
{
    public function send(object $notifiable, Notification $notification): void
    {
        if (! method_exists($notification, 'toExpo')) {
            return;
        }

        $tokens = $notifiable->relationLoaded('mobileExpoPushTokens')
            ? $notifiable->mobileExpoPushTokens
            : $notifiable->mobileExpoPushTokens()->get();

        if ($tokens->isEmpty()) {
            return;
        }

        /** @var array{title?: string, body?: string, badge?: int, data?: array<string, mixed>} $payload */
        $payload = $notification->toExpo($notifiable);

        $messages = [];
        foreach ($tokens as $row) {
            $to = $row->expo_token;
            if (! is_string($to) || $to === '') {
                continue;
            }
            $msg = array_filter([
                'to' => $to,
                'title' => $payload['title'] ?? '',
                'body' => $payload['body'] ?? '',
                'sound' => 'default',
                'priority' => 'high',
                'channelId' => 'takeover_hints',
                'data' => array_map(
                    static fn ($v) => is_string($v) ? $v : json_encode($v),
                    $payload['data'] ?? []
                ),
            ]);
            if (array_key_exists('badge', $payload)) {
                $msg['badge'] = max(0, (int) $payload['badge']);
            }
            $messages[] = $msg;
        }

        if ($messages === []) {
            return;
        }

        try {
            // Expo acepta un único objeto o un array JSON de mensajes; el cuerpo debe ser JSON real.
            $response = Http::timeout(25)
                ->acceptJson()
                ->asJson()
                ->post('https://exp.host/--/api/v2/push/send', $messages);

            if (! $response->successful()) {
                Log::warning('Expo push: respuesta no exitosa', [
                    'status' => $response->status(),
                    'body' => $response->body(),
                ]);
            }
        } catch (\Throwable $e) {
            Log::warning('Expo push: error al enviar', ['error' => $e->getMessage()]);
        }
    }
}
