<?php
/**
 * IpBlacklistTable — 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 IpBlacklistTable extends BaseTable {

    protected $table_name  = 'ultraguard_ip_blacklist';
    protected $cache_group = 'ultraguard_ip_blacklist';

    public function get_defaults(): array {
        return [
            'id'          => 0,
            'ip_address'  => '',
            'ip_range'    => null,
            'reason'      => '',
            'source'      => 'manual',
            'severity'    => 'medium',
            'is_active'   => 1,
            'expires_at'  => null,
            'hits_count'  => 0,
            'last_hit_at' => null,
            'added_by'    => null,
            'created_at'  => '',
            'updated_at'  => '',
        ];
    }

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

    protected function sanitize_data( $data ): array {
        $out = [];
        foreach ( $data as $k => $v ) {
            $out[ $k ] = match ( $k ) {
                'hits_count' => absint( $v ),
                'is_active'  => (int) (bool) $v,
                'added_by'   => $v === null ? null : absint( $v ),
                default      => is_string( $v ) ? sanitize_text_field( $v ) : $v,
            };
        }
        return $out;
    }

    public function is_blocked( string $ip ): bool {
        $record = $this->get_by_field( 'ip_address', $ip );
        if ( ! $record || empty( $record['is_active'] ) ) { return false; }
        if ( ! empty( $record['expires_at'] ) && strtotime( $record['expires_at'] ) < time() ) {
            $this->update( (int) $record['id'], [ 'is_active' => 0 ] );
            return false;
        }
        $this->increment_field( 'hits_count', [ 'ip_address' => $ip ] );
        $this->update( (int) $record['id'], [ 'last_hit_at' => current_time( 'mysql', true ) ] );
        return true;
    }

    public function block_ip( string $ip, string $reason = '', string $source = 'manual',
                              string $severity = 'medium', ?string $expires_at = null ): int|false {
        if ( $this->exists( [ 'ip_address' => $ip ] ) ) {
            $existing = $this->get_by_field( 'ip_address', $ip );
            return $this->update( (int) $existing['id'], [ 'is_active' => 1, 'reason' => $reason ] ) ? (int) $existing['id'] : false;
        }
        return $this->insert( [
            'ip_address' => $ip,
            'reason'     => $reason,
            'source'     => $source,
            'severity'   => $severity,
            'expires_at' => $expires_at,
            'added_by'   => get_current_user_id() ?: null,
        ] );
    }

    public function unblock_ip( string $ip ): bool {
        return (bool) $this->update_where( [ 'is_active' => 0 ], [ 'ip_address' => $ip ] );
    }

    public function get_active_blocks( int $limit = 500 ): array {
        return $this->get_by( [ 'is_active' => 1 ], $limit );
    }

    protected function get_searchable_fields(): array {
        return [ 'ip_address', 'reason', 'source' ];
    }
}

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