<?php
declare(strict_types=1);

namespace App\Lib;

use Core\DB;

/**
 * Expo Push sender. Reads active push_tokens for a user (or takes a raw token)
 * and POSTs to Expo's push service. No SDK dependency — plain cURL.
 */
final class ExpoPush
{
    private const ENDPOINT = 'https://exp.host/--/api/v2/push/send';

    /** Send to one raw expo token. Returns the decoded API response array. */
    public static function sendRaw(string $expoToken, string $title, string $body, array $data = []): array
    {
        $payload = [[
            'to'    => $expoToken,
            'title' => $title,
            'body'  => $body,
            'data'  => $data,
            'sound' => 'default',
        ]];
        return self::post($payload);
    }

    /** Send to every active device belonging to a user. */
    public static function sendToUser(int $tenantId, int $userId, string $title, string $body, array $data = []): array
    {
        $tokens = DB::all(
            'SELECT expo_token FROM push_tokens
              WHERE tenant_id = :t AND user_id = :u AND revoked_at IS NULL',
            ['t' => $tenantId, 'u' => $userId]
        );
        if (!$tokens) return ['data' => [], 'note' => 'no tokens'];

        $payload = [];
        foreach ($tokens as $t) {
            $payload[] = [
                'to'    => $t['expo_token'],
                'title' => $title,
                'body'  => $body,
                'data'  => $data,
                'sound' => 'default',
            ];
        }
        return self::post($payload);
    }

    private static function post(array $payload): array
    {
        $ch = curl_init(self::ENDPOINT);
        curl_setopt_array($ch, [
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode($payload),
            CURLOPT_HTTPHEADER     => [
                'Accept: application/json',
                'Accept-Encoding: gzip, deflate',
                'Content-Type: application/json',
            ],
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 10,
        ]);
        $body = curl_exec($ch);
        $err  = curl_error($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($err) throw new \RuntimeException('Expo push cURL error: ' . $err);
        return ['http_code' => $code, 'body' => json_decode($body, true) ?: $body];
    }
}
