<?php
/**
 * FcQuarantineTable — Quarantine audit trail for the File Checker module.
 *
 * Each row represents one file quarantine event. Files that are restored
 * or permanently deleted keep their row with an updated `status` field
 * for a full audit trail.
 *
 * @package UltraguardPro\modules\filechecker\db
 * @since   6.5.0
 */

namespace UltraguardPro\modules\filechecker\db;

use UltraguardPro\db\BaseTable;

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

class FcQuarantineTable extends BaseTable {

    protected $table_name  = 'ultraguard_fc_quarantine';
    protected $cache_group = 'ultraguard_fc_quarantine';

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

    public function get_defaults(): array {
        return [
            'id'              => 0,
            'original_path'   => '',
            'quarantine_path' => '',
            'reason'          => 'manual',
            'file_size'       => 0,
            'file_hash'       => '',
            'status'          => 'quarantined',
            'quarantined_by'  => 0,
            'quarantined_at'  => '',
            'restored_at'     => null,
            'deleted_at'      => null,
            'created_at'      => '',
            'updated_at'      => '',
        ];
    }

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

        $valid_statuses = [ 'quarantined', 'restored', 'deleted' ];
        if ( isset( $data['status'] ) && ! in_array( $data['status'], $valid_statuses, true ) ) {
            $data['status'] = 'quarantined';
        }

        return $data;
    }

    protected function sanitize_data( $data ): array {
        $out = [];
        foreach ( $data as $k => $v ) {
            $out[ $k ] = match ( $k ) {
                'original_path',
                'quarantine_path' => is_null( $v ) ? null : sanitize_textarea_field( (string) $v ),
                'file_size'       => absint( $v ),
                'quarantined_by'  => absint( $v ),
                'file_hash'       => sanitize_text_field( (string) $v ),
                'restored_at',
                'deleted_at',
                'quarantined_at'  => is_null( $v ) ? null : sanitize_text_field( (string) $v ),
                default           => is_string( $v ) ? sanitize_text_field( $v ) : $v,
            };
        }
        return $out;
    }

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

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

    /**
     * Fetch all currently-quarantined files (not restored or deleted).
     *
     * @param  int $limit
     * @return array
     */
    public function get_active( int $limit = 200 ): array {
        return $this->get_by(
            [ 'status' => 'quarantined' ],
            $limit,
            'quarantined_at',
            'DESC'
        );
    }

    /**
     * Mark a quarantine record as restored and stamp the timestamp.
     *
     * @param  int $id
     * @return bool
     */
    public function mark_restored( int $id ): bool {
        return $this->update( $id, [
            'status'      => 'restored',
            'restored_at' => current_time( 'mysql', true ),
        ] );
    }

    /**
     * Mark a quarantine record as permanently deleted and stamp the timestamp.
     *
     * @param  int $id
     * @return bool
     */
    public function mark_deleted( int $id ): bool {
        return $this->update( $id, [
            'status'     => 'deleted',
            'deleted_at' => current_time( 'mysql', true ),
        ] );
    }

    /**
     * Summary counts for the Quarantine page stat-cards.
     *
     * @return array{active:int, restored:int, deleted:int, total:int}
     */
    public function get_quarantine_summary(): array {
        return [
            'active'   => $this->count( [ 'status' => 'quarantined' ] ),
            'restored' => $this->count( [ 'status' => 'restored' ] ),
            'deleted'  => $this->count( [ 'status' => 'deleted' ] ),
            'total'    => $this->count(),
        ];
    }
}
