<?php
declare(strict_types=1);

namespace App\Controllers\Api;

use App\Middleware\ApiToken;
use App\Middleware\TenantScope;
use Core\Controller;
use Core\DB;

/**
 * Push-token registration for the mobile app.
 *
 *   POST /api/v1/push/register
 *     { "device_id": "abc...", "expo_token": "ExponentPushToken[...]", "platform": "android|ios" }
 *
 *   POST /api/v1/push/unregister
 *     { "device_id": "abc..." }
 *
 * Uses device_id as the natural key (UNIQUE index) — re-registering the same
 * device just refreshes its expo_token.
 */
final class PushController extends Controller
{
    public function middleware(): array
    {
        return [ApiToken::class, TenantScope::class];
    }

    public function register(): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
            $this->json(['error' => 'POST required'], 405);
        }
        $body = $this->input();
        $deviceId  = trim((string) ($body['device_id']  ?? ''));
        $expoToken = trim((string) ($body['expo_token'] ?? ''));
        $platform  = (string) ($body['platform'] ?? '');

        if ($deviceId === '' || $expoToken === '') {
            $this->json(['error' => 'device_id and expo_token required'], 422);
        }

        $tenantId = (int) ($_SESSION['tenant_id'] ?? 0);
        $userId   = (int) ($_SESSION['user']['user_id'] ?? 0);

        $existing = DB::one('SELECT push_token_id FROM push_tokens WHERE device_id = :d', ['d' => $deviceId]);
        if ($existing) {
            DB::run(
                'UPDATE push_tokens
                    SET tenant_id = :t, user_id = :u, expo_token = :e, platform = :p,
                        revoked_at = NULL, updated_at = NOW()
                  WHERE push_token_id = :id',
                ['t' => $tenantId, 'u' => $userId, 'e' => $expoToken, 'p' => $platform, 'id' => $existing['push_token_id']]
            );
        } else {
            DB::insert('push_tokens', [
                'tenant_id'  => $tenantId,
                'user_id'    => $userId,
                'device_id'  => $deviceId,
                'expo_token' => $expoToken,
                'platform'   => $platform ?: 'unknown',
            ]);
        }
        $this->json(['success' => true]);
    }

    public function unregister(): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
            $this->json(['error' => 'POST required'], 405);
        }
        $body = $this->input();
        $deviceId = trim((string) ($body['device_id'] ?? ''));
        if ($deviceId === '') $this->json(['error' => 'device_id required'], 422);

        DB::run(
            'UPDATE push_tokens SET revoked_at = NOW() WHERE device_id = :d AND revoked_at IS NULL',
            ['d' => $deviceId]
        );
        $this->json(['success' => true]);
    }

    /** Test-send a push to the caller's own devices. Handy for verifying the loop. */
    public function testSelf(): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
            $this->json(['error' => 'POST required'], 405);
        }
        $tenantId = (int) ($_SESSION['tenant_id'] ?? 0);
        $userId   = (int) ($_SESSION['user']['user_id'] ?? 0);
        try {
            $r = \App\Lib\ExpoPush::sendToUser($tenantId, $userId, 'OrchView 2', 'Push test successful ✓');
            $this->json(['ok' => true, 'expo' => $r]);
        } catch (\Throwable $e) {
            $this->json(['error' => $e->getMessage()], 500);
        }
    }
}
