<?php

namespace CaptureRelay;

final class DeviceBlocklist
{
    public static function find(string $identityHash): ?object
    {
        if (!preg_match('/^[a-f0-9]{64}$/', $identityHash)) {
            return null;
        }
        global $wpdb;
        return $wpdb->get_row($wpdb->prepare(
            'SELECT * FROM %i WHERE identity_hash = %s LIMIT 1',
            Config::table('blocks'),
            $identityHash
        )) ?: null;
    }

    public static function recordBlockedAttempt(string $identityHash): void
    {
        global $wpdb;
        $wpdb->query($wpdb->prepare(
            'UPDATE %i SET hit_count = hit_count + 1, last_seen_at = %s WHERE identity_hash = %s',
            Config::table('blocks'),
            current_time('mysql', true),
            $identityHash
        ));
    }

    public static function blockRequest(object $request, string $reason = ''): bool
    {
        return self::block(
            (string) $request->identity_hash,
            (string) $request->device_name,
            (string) $request->platform,
            $reason,
            (string) $request->request_id
        );
    }

    public static function blockDevice(object $device, string $reason = ''): bool
    {
        return self::block(
            (string) $device->identity_hash,
            (string) $device->display_name,
            (string) $device->platform,
            $reason
        );
    }

    public static function unblock(string $identityHash): bool
    {
        global $wpdb;
        return $wpdb->delete(Config::table('blocks'), ['identity_hash' => $identityHash], ['%s']) !== false;
    }

    private static function block(
        string $identityHash,
        string $displayName,
        string $platform,
        string $reason,
        ?string $requestId = null
    ): bool {
        if (!preg_match('/^[a-f0-9]{64}$/', $identityHash)) {
            return false;
        }
        global $wpdb;
        $now = current_time('mysql', true);
        $result = $wpdb->query($wpdb->prepare(
            'INSERT INTO %i (identity_hash, identity_type, display_name, platform, reason, source_request_id, blocked_at, blocked_by) VALUES (%s, %s, %s, %s, %s, %s, %s, %d) '
            . 'ON DUPLICATE KEY UPDATE display_name = VALUES(display_name), platform = VALUES(platform), reason = VALUES(reason), source_request_id = VALUES(source_request_id), blocked_at = VALUES(blocked_at), blocked_by = VALUES(blocked_by)',
            Config::table('blocks'),
            $identityHash,
            'legacy_uuid',
            substr(sanitize_text_field($displayName), 0, 160),
            substr(sanitize_key($platform), 0, 32),
            substr(sanitize_text_field($reason), 0, 255),
            $requestId,
            $now,
            get_current_user_id()
        ));
        return $result !== false;
    }
}
