<?php
/**
 * FirewallLogsTable — standalone class file.
 *
 * @package UltraguardPro\modules\firewall\db
 */

namespace UltraguardPro\modules\firewall\db;

use UltraguardPro\db\BaseTable;
use UltraguardPro\core\DatabaseCrud;

if ( ! defined( 'ABSPATH' ) ) { exit; }

// ─────────────────────────────────────────────────────────────────────────────
class FirewallLogsTable extends BaseTable {

    protected $table_name  = 'ultraguard_firewall_logs';
    protected $cache_group = 'ultraguard_firewall_logs';

    public function get_defaults(): array {
        return [
            'id'             => 0,
            'ip_address'     => '',
            'request_method' => 'GET',
            'request_uri'    => '',
            'user_agent'     => null,
            'rule_id'        => null,
            'action'         => 'allowed',
            'threat_level'   => 'none',
            'country_code'   => null,
            'user_id'        => null,
            'response_code'  => null,
            'created_at'     => '',
        ];
    }

    protected function validate_data( $data ) {
        if ( empty( $data['ip_address'] ) ) { return false; }
        return $data;
    }

    protected function sanitize_data( $data ): array {
        $out = [];
        foreach ( $data as $k => $v ) {
            $out[ $k ] = match ( $k ) {
                'request_uri', 'user_agent' => sanitize_textarea_field( (string) $v ),
                'rule_id', 'user_id'        => $v === null ? null : absint( $v ),
                'response_code'             => $v === null ? null : absint( $v ),
                default                     => is_string( $v ) ? sanitize_text_field( $v ) : $v,
            };
        }
        return $out;
    }

    public function log_request( string $ip, string $method, string $uri, string $action = 'allowed',
                                  string $threat = 'none', ?int $rule_id = null ): int|false {
        return $this->insert( [
            'ip_address'     => $ip,
            'request_method' => strtoupper( $method ),
            'request_uri'    => $uri,
            'user_agent'     => sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ?? '' ) ),
            'action'         => $action,
            'threat_level'   => $threat,
            'rule_id'        => $rule_id,
            'user_id'        => get_current_user_id() ?: null,
        ] );
    }

    public function get_blocked_count_by_ip( string $ip, int $since_hours = 24 ): int {
        $cutoff = gmdate( 'Y-m-d H:i:s', strtotime( "-{$since_hours} hours" ) );

        return DatabaseCrud::count_since(
            $this->table_name,
            [ 'ip_address' => $ip, 'action' => 'blocked' ],
            'created_at',
            $cutoff
        );
    }

    public function get_top_attacked_uris( int $limit = 10, int $since_hours = 24 ): array {
        $results = $this->get_top_records( 'request_uri', 'id', 'COUNT', $limit, [
            'action'       => 'blocked',
            'created_at >=' => gmdate( 'Y-m-d H:i:s', strtotime( "-{$since_hours} hours" ) ),
        ] );

        return is_array( $results['raw'] ?? null ) ? $results['raw'] : [];
    }

    protected function get_searchable_fields(): array {
        return [ 'ip_address', 'request_uri', 'action', 'threat_level' ];
    }
}

// ─────────────────────────────────────────────────────────────────────────────
