<?php
/**
 * ScanSessionsTable — One row per completed or running scan session.
 *
 * @package UltraguardPro\modules\filechecker\db
 * @since   6.5.0
 */

namespace UltraguardPro\modules\filechecker\db;

use UltraguardPro\db\BaseTable;

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

class ScanSessionsTable extends BaseTable {

    protected $table_name  = 'ultraguard_scan_sessions';
    protected $cache_group = 'ultraguard_scan_sessions';

    // ── BaseTable contract ─────────────────────────────────────────────────────

    public function get_defaults(): array {
        return [
            'id'             => 0,
            'scan_type'      => 'full',
            'status'         => 'running',
            'files_scanned'  => 0,
            'changes_found'  => 0,
            'added_files'    => 0,
            'modified_files' => 0,
            'suspicious'     => 0,
            'initiated_by'   => 0,
            'started_at'     => '',
            'completed_at'   => null,
            'error_message'  => null,
            'created_at'     => '',
            'updated_at'     => '',
        ];
    }

    protected function validate_data( $data ) {
        $valid_types   = [ 'full', 'quick', 'manual', 'post_upgrade' ];
        $valid_statuses= [ 'running', 'completed', 'failed', 'cancelled' ];

        if ( isset( $data['scan_type'] ) && ! in_array( $data['scan_type'], $valid_types, true ) ) {
            $data['scan_type'] = 'full';
        }
        if ( isset( $data['status'] ) && ! in_array( $data['status'], $valid_statuses, true ) ) {
            $data['status'] = 'running';
        }

        return $data;
    }

    protected function sanitize_data( $data ): array {
        $out = [];
        foreach ( $data as $k => $v ) {
            $out[ $k ] = match ( $k ) {
                'files_scanned',
                'changes_found',
                'added_files',
                'modified_files',
                'suspicious',
                'initiated_by' => absint( $v ),
                'completed_at',
                'started_at'   => is_null( $v ) ? null : sanitize_text_field( (string) $v ),
                'error_message'=> is_null( $v ) ? null : wp_kses_post( (string) $v ),
                default        => is_string( $v ) ? sanitize_text_field( $v ) : $v,
            };
        }
        return $out;
    }

    protected function get_searchable_fields(): array {
        return [ 'scan_type', 'status' ];
    }

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

    /**
     * Fetch the most recent N completed scan sessions.
     *
     * @param  int $limit
     * @return array
     */
    public function get_recent_completed( int $limit = 30 ): array {
        return $this->get_by(
            [ 'status' => 'completed' ],
            $limit,
            'started_at',
            'DESC'
        );
    }

    /**
     * Return summary stats across all completed sessions.
     *
     * @return array{total_scans:int, total_files_scanned:int, total_changes_found:int, last_scan_at:string}
     */
    public function get_scan_statistics(): array {
        return [
            'total_scans'         => $this->count( [ 'status' => 'completed' ] ),
            'total_files_scanned' => (int) $this->sum( 'files_scanned', [ 'status' => 'completed' ] ),
            'total_changes_found' => (int) $this->sum( 'changes_found', [ 'status' => 'completed' ] ),
            'last_scan_at'        => (string) $this->max( 'completed_at', [ 'status' => 'completed' ] ),
        ];
    }

    /**
     * Delete scan sessions older than N days.
     *
     * @param  int $days
     * @return int  Rows deleted.
     */
    public function prune_old_sessions( int $days = 90 ): int {
        return $this->delete_older_than( $days, 'started_at' );
    }
}
