<?php
declare(strict_types=1);

namespace App\Shared\Services;

use App\Core\App;

final class PushNotificationService
{
    public static function send(string $entityType, int $entityId, string $title, string $body, array $data = []): bool
    {
        $db = App::getInstance()->db();
        if (!$db) {
            return false;
        }

        $pushToken = self::resolvePushToken($entityType, $entityId);
        if (!$pushToken) {
            return false;
        }

        $db->insert('notification_queue', [
            'type' => 'push',
            'recipient_type' => $entityType,
            'recipient_id' => $entityId,
            'subject' => $title,
            'message' => $body,
            'data_json' => !empty($data) ? json_encode($data, JSON_UNESCAPED_UNICODE) : null,
            'priority' => 1,
            'status' => 'pending',
            'attempts' => 0,
            'max_attempts' => 3,
            'created_at' => date('Y-m-d H:i:s'),
        ]);

        return true;
    }

    public static function sendBulk(string $entityType, array $entityIds, string $title, string $body, array $data = []): int
    {
        $sent = 0;
        foreach ($entityIds as $entityId) {
            if (self::send($entityType, (int) $entityId, $title, $body, $data)) {
                $sent++;
            }
        }
        return $sent;
    }

    public static function registerToken(string $entityType, int $entityId, string $bearerToken, string $pushToken, string $platform): void
    {
        $db = App::getInstance()->db();
        if (!$db) {
            return;
        }

        $table = self::tokenTable($entityType);
        if (!$table) {
            return;
        }

        $db->update($table, [
            'push_token' => $pushToken,
            'device_platform' => $platform,
        ], '`token` = ?', [$bearerToken]);
    }

    public static function clearToken(string $entityType, string $bearerToken): void
    {
        $db = App::getInstance()->db();
        if (!$db) {
            return;
        }

        $table = self::tokenTable($entityType);
        if (!$table) {
            return;
        }

        $db->update($table, [
            'push_token' => null,
            'device_platform' => null,
        ], '`token` = ?', [$bearerToken]);
    }

    private static function resolvePushToken(string $entityType, int $entityId): ?string
    {
        $db = App::getInstance()->db();
        $table = self::tokenTable($entityType);
        if (!$table) {
            return null;
        }

        $idColumn = match ($entityType) {
            'player' => 'player_id',
            'coach' => 'coach_id',
            'parent' => 'parent_id',
            default => null,
        };

        if (!$idColumn) {
            return null;
        }

        $row = $db->selectOne(
            "SELECT push_token FROM {$table} WHERE {$idColumn} = ? AND is_revoked = 0 AND push_token IS NOT NULL ORDER BY last_used_at DESC LIMIT 1",
            [$entityId]
        );

        return $row['push_token'] ?? null;
    }

    private static function tokenTable(string $entityType): ?string
    {
        return match ($entityType) {
            'player' => 'player_tokens',
            'coach' => 'coach_tokens',
            'parent' => 'parent_tokens',
            default => null,
        };
    }
}
