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

namespace UltraguardPro\modules\antivirus\db;

use UltraguardPro\db\BaseTable;

if ( ! defined( 'ABSPATH' ) ) { exit; }
// VulnerabilityScansTable
class VulnerabilityScansTable extends BaseTable {

    protected $table_name  = 'ultraguard_vulnerability_scans';
    protected $cache_group = 'ultraguard_vulnerability_scans';

    /**
     * @return array<string,mixed>
     */
    public function get_defaults(): array {
        return [
            'id'                 => 0,
            'scan_id'            => '',
            'component_type'     => 'plugin',
            'component_slug'     => '',
            'component_version'  => null,
            'vulnerability_type' => null,
            'severity'           => 'medium',
            'description'        => null,
            'cve_id'             => null,
            'status'             => 'open',
            'remediation'        => null,
            'created_at'         => '',
            'updated_at'         => '',
        ];
    }

    /**
     * @param  array<string,mixed>|false $data
     * @return array<string,mixed>|false
     */
    protected function validate_data( $data ) {
        if ( empty( $data['scan_id'] ) || empty( $data['component_slug'] ) ) {
            return false;
        }
        $valid_types = [ 'plugin', 'theme', 'core', 'file' ];
        if ( isset( $data['component_type'] ) && ! in_array( $data['component_type'], $valid_types, true ) ) {
            return false;
        }
        return $data;
    }

    /**
     * @param  array<string,mixed> $data
     * @return array<string,mixed>
     */
    protected function sanitize_data( $data ): array {
        $out = [];
        foreach ( $data as $k => $v ) {
            $out[ $k ] = match ( $k ) {
                'description', 'remediation' => wp_kses_post( (string) $v ),
                default                       => is_string( $v ) ? sanitize_text_field( $v ) : $v,
            };
        }
        return $out;
    }

    // ── Domain methods ─────────────────────────────────────────────────────────

    /**
     * Retrieve open vulnerabilities sorted by severity.
     *
     * @param  int $limit
     * @return array<int,array<string,mixed>>
     */
    public function get_open_vulnerabilities( int $limit = 100 ): array {
        return $this->get_by( [ 'status' => 'open' ], $limit, 'severity', 'DESC' );
    }

    /**
     * Retrieve open critical vulnerabilities.
     *
     * @param  int $limit
     * @return array<int,array<string,mixed>>
     */
    public function get_critical_findings( int $limit = 50 ): array {
        return $this->get_by( [ 'severity' => 'critical', 'status' => 'open' ], $limit );
    }

    /**
     * Mark a vulnerability as patched.
     *
     * @param  int $id  Record ID.
     * @return bool
     */
    public function mark_patched( int $id ): bool {
        return $this->update( $id, [ 'status' => 'patched' ] );
    }

    /**
     * Retrieve all vulnerabilities for a specific component.
     *
     * @param  string $slug  Component slug.
     * @param  string $type  Component type (optional filter).
     * @return array<int,array<string,mixed>>
     */
    public function get_by_component( string $slug, string $type = '' ): array {
        $conds = [ 'component_slug' => sanitize_text_field( $slug ) ];
        if ( $type ) {
            $conds['component_type'] = sanitize_key( $type );
        }
        return $this->get_by( $conds, 500 );
    }

    /**
     * Summary counts grouped by severity and status.
     *
     * @return array{open: int, critical: int, high: int, medium: int, patched: int, false_positive: int}
     */
    public function get_vulnerability_summary(): array {
        return [
            'open'           => $this->count( [ 'status' => 'open' ] ),
            'critical'       => $this->count( [ 'status' => 'open', 'severity' => 'critical' ] ),
            'high'           => $this->count( [ 'status' => 'open', 'severity' => 'high' ] ),
            'medium'         => $this->count( [ 'status' => 'open', 'severity' => 'medium' ] ),
            'patched'        => $this->count( [ 'status' => 'patched' ] ),
            'false_positive' => $this->count( [ 'status' => 'false_positive' ] ),
        ];
    }

    /**
     * @return string[]
     */
    protected function get_searchable_fields(): array {
        return [ 'scan_id', 'component_slug', 'vulnerability_type', 'cve_id', 'description' ];
    }
}
