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

namespace UltraguardPro\modules\notifications\db;

use UltraguardPro\db\BaseTable;
use UltraguardPro\core\DataCodec;

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

/**
 * NotificationRulesTable — User-defined notification trigger rules.
 *
 * @package UltraguardPro\modules\notifications\db
 * @since   6.5.0
 */
class NotificationRulesTable extends BaseTable {

    protected $table_name  = 'ultraguard_notification_rules';
    protected $cache_group = 'ultraguard_notification_rules';

    /** Severity levels in ascending order for threshold comparisons. */
    public const SEVERITY_ORDER = [
        'info'     => 0,
        'low'      => 1,
        'medium'   => 2,
        'high'     => 3,
        'critical' => 4,
    ];

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

    public function get_defaults(): array {
        return [
            'id'                 => 0,
            'name'               => '',
            'event_type'         => '',
            'severity_threshold' => 'medium',
            'channel'            => 'email',
            'recipient'          => '',
            'subject_template'   => '',
            'message_template'   => '',
            'webhook_secret'     => null,
            'is_active'          => 1,
            'cooldown_minutes'   => 60,
            'last_triggered_at'  => null,
            'trigger_count'      => 0,
            'created_by'         => null,
            'created_at'         => '',
            'updated_at'         => '',
        ];
    }

    protected function validate_data( $data ) {
        if ( empty( $data['name'] ) || empty( $data['event_type'] ) || empty( $data['recipient'] ) ) {
            return false;
        }

        $valid_channels   = [ 'email', 'admin_notice', 'webhook', 'slack', 'sms' ];
        $valid_severities = array_keys( self::SEVERITY_ORDER );

        if ( isset( $data['channel'] ) && ! in_array( $data['channel'], $valid_channels, true ) ) {
            return false;
        }
        if ( isset( $data['severity_threshold'] ) && ! in_array( $data['severity_threshold'], $valid_severities, true ) ) {
            $data['severity_threshold'] = 'medium';
        }

        return $data;
    }

    protected function sanitize_data( $data ): array {
        $out = [];
        foreach ( $data as $k => $v ) {
            $out[ $k ] = match ( $k ) {
                'message_template' => wp_kses_post( (string) $v ),
                'cooldown_minutes' => max( 0, absint( $v ) ),
                'trigger_count'    => absint( $v ),
                'is_active'        => (int) (bool) $v,
                'created_by'       => is_null( $v ) ? null : absint( $v ),
                'webhook_secret'   => is_null( $v ) ? null : sanitize_text_field( (string) $v ),
                default            => is_string( $v ) ? sanitize_text_field( $v ) : $v,
            };
        }
        return $out;
    }

    // ── DataCodec integration ───────────────────────────────────────────────────

    /**
     * Template columns contain {placeholder} tokens, emoji (e.g. 🚨), and
     * angle-bracket sequences (e.g. [UltraGuard Pro]) that wp_strip_all_tags()
     * inside DatabaseCrud would strip or mangle.  DataCodec Base64-wraps both
     * columns on write and decodes transparently on read.
     *
     * @return string[]
     */
    protected function get_codec_fields(): array {
        return [ 'subject_template', 'message_template' ];
    }

    protected function get_searchable_fields(): array {
        return [ 'name', 'event_type', 'recipient', 'channel' ];
    }

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

    /**
     * Return all active rules matching an event_type and severity.
     * Respects cooldown: rules that fired within their cooldown window are skipped.
     *
     * @param  string $event_type
     * @param  string $severity
     * @return array
     */
    public function get_matching_rules( string $event_type, string $severity ): array {
        $severity_level = self::SEVERITY_ORDER[ $severity ] ?? 0;

        // Fetch rules matching this exact event_type OR wildcard '*'
        $all_active = array_merge(
            $this->get_by( [ 'is_active' => 1, 'event_type' => $event_type ], 100, 'id', 'ASC', 0, false ),
            $this->get_by( [ 'is_active' => 1, 'event_type' => '*'          ], 100, 'id', 'ASC', 0, false )
        );

        // Deduplicate by ID
        $seen = [];
        $unique = [];
        foreach ( $all_active as $rule ) {
            $id = (int) $rule['id'];
            if ( ! isset( $seen[ $id ] ) ) {
                $seen[ $id ] = true;
                $unique[]    = $rule;
            }
        }

        $now = time();
        return array_values( array_filter( $unique, function( array $rule ) use ( $severity_level, $now ) {
            // Severity threshold check
            $threshold = self::SEVERITY_ORDER[ $rule['severity_threshold'] ] ?? 0;
            if ( $severity_level < $threshold ) { return false; }

            // Cooldown check
            if ( ! empty( $rule['last_triggered_at'] ) && (int) $rule['cooldown_minutes'] > 0 ) {
                $last     = (int) strtotime( $rule['last_triggered_at'] . ' UTC' );
                $cooldown = (int) $rule['cooldown_minutes'] * 60;
                if ( ( $now - $last ) < $cooldown ) { return false; }
            }

            return true;
        } ) );
    }

    /**
     * Stamp last_triggered_at and increment trigger_count for a rule.
     *
     * @param  int $rule_id
     * @return bool
     */
    public function mark_triggered( int $rule_id ): bool {
        $this->update( $rule_id, [ 'last_triggered_at' => current_time( 'mysql', true ) ] );
        return $this->increment_field( 'trigger_count', [ 'id' => $rule_id ] );
    }

    /**
     * Seed sensible default rules (skipped if table already has rows).
     *
     * @param string $admin_email
     */
    public function seed_defaults( string $admin_email ): void {
        if ( $this->count() > 0 ) { return; }

        $defaults = [
            [
                'name'               => __( 'Critical Security Alert — Any Event', 'ultraguard-security-suite' ),
                'event_type'         => '*',
                'severity_threshold' => 'critical',
                'channel'            => 'email',
                'recipient'          => $admin_email,
                'subject_template'   => '[{site_name}] 🚨 Critical Security Alert: {event_type}',
                'message_template'   => "A critical security event has been detected on {site_name}.\n\nEvent: {event_type}\nSeverity: {severity}\nTime: {time}\nIP: {ip}\n\nPlease review your security dashboard immediately:\n{admin_url}",
                'cooldown_minutes'   => 30,
                'created_by'         => 0,
            ],
            [
                'name'               => __( 'Brute Force / Lockout Alert', 'ultraguard-security-suite' ),
                'event_type'         => 'rate_limit_exceeded',
                'severity_threshold' => 'medium',
                'channel'            => 'email',
                'recipient'          => $admin_email,
                'subject_template'   => '[{site_name}] Brute Force Attack Detected — IP {ip}',
                'message_template'   => "Multiple failed login attempts have been detected on {site_name}.\n\nIP Address: {ip}\nUsername attempted: {username}\nLockout duration: {lockout_duration} minutes\nTime: {time}\n\nThe IP has been locked out automatically.\n\nManage lockouts: {site_url}/wp-admin/admin.php?page=ultraguard-security-suite-dashboard&ug_page=lockouts",
                'cooldown_minutes'   => 60,
                'created_by'         => 0,
            ],
            [
                'name'               => __( 'File Modification Detected', 'ultraguard-security-suite' ),
                'event_type'         => 'file_modified',
                'severity_threshold' => 'high',
                'channel'            => 'email',
                'recipient'          => $admin_email,
                'subject_template'   => '[{site_name}] ⚠️ File Integrity: {count} file(s) modified',
                'message_template'   => "File integrity changes detected on {site_name}.\n\nFiles modified: {count}\nScan type: {scan_type}\nDetected at: {time}\n\nIf you did not make these changes, your site may be compromised.\nReview changes: {site_url}/wp-admin/admin.php?page=ultraguard-security-suite-dashboard&ug_page=filechecker-changes",
                'cooldown_minutes'   => 120,
                'created_by'         => 0,
            ],
            [
                'name'               => __( 'Malware Detected', 'ultraguard-security-suite' ),
                'event_type'         => 'malware_detected',
                'severity_threshold' => 'critical',
                'channel'            => 'email',
                'recipient'          => $admin_email,
                'subject_template'   => '[{site_name}] 🦠 URGENT: Malware Detected — {count} infected file(s)',
                'message_template'   => "URGENT: Malware has been detected on {site_name}.\n\nInfected files: {count}\nScan ID: {scan_id}\nDetected at: {time}\n\nImmediate action required!\nView scan results: {site_url}/wp-admin/admin.php?page=ultraguard-security-suite-dashboard&ug_page=antivirus",
                'cooldown_minutes'   => 15,
                'created_by'         => 0,
            ],
            [
                'name'               => __( 'Firewall Block Alert (High Volume)', 'ultraguard-security-suite' ),
                'event_type'         => 'request_blocked',
                'severity_threshold' => 'high',
                'channel'            => 'email',
                'recipient'          => $admin_email,
                'subject_template'   => '[{site_name}] Firewall blocked request from {ip}',
                'message_template'   => "The UltraGuard firewall has blocked a high-severity request on {site_name}.\n\nIP: {ip}\nReason: {reason}\nTime: {time}\n\nReview firewall logs: {site_url}/wp-admin/admin.php?page=ultraguard-security-suite-dashboard&ug_page=firewall-logs",
                'cooldown_minutes'   => 30,
                'created_by'         => 0,
            ],

            // ── Server Intelligence events ─────────────────────────────────
            [
                'name'               => __( 'Suspicious File Detected', 'ultraguard-security-suite' ),
                'event_type'         => 'suspicious_file',
                'severity_threshold' => 'high',
                'channel'            => 'email',
                'recipient'          => $admin_email,
                'subject_template'   => '[{site_name}] ⚠️ Suspicious file detected: {file_path}',
                'message_template'   => "UltraGuard has detected a suspicious file on {site_name}.\n\nFile: {file_path}\nChange type: {change_type}\nDetected at: {time}\n\nThis file may contain malicious code. Please review it immediately:\n{admin_url}",
                'cooldown_minutes'   => 60,
                'created_by'         => 0,
            ],
            [
                'name'               => __( 'WordPress Core File Modified', 'ultraguard-security-suite' ),
                'event_type'         => 'core_file_modified',
                'severity_threshold' => 'critical',
                'channel'            => 'email',
                'recipient'          => $admin_email,
                'subject_template'   => '[{site_name}] 🚨 CRITICAL: Core file modified — {file_path}',
                'message_template'   => "CRITICAL SECURITY ALERT: A WordPress core file has been modified on {site_name}.\n\nFile: {file_path}\nExpected hash: {previous_hash}...\nCurrent hash:  {current_hash}...\nDetected at: {time}\n\n⚠️ This strongly suggests your site has been compromised.\nReview immediately: {admin_url}",
                'cooldown_minutes'   => 15,
                'created_by'         => 0,
            ],
            [
                'name'               => __( 'Threat Intelligence Updated (Bulk)', 'ultraguard-security-suite' ),
                'event_type'         => 'blacklist_updated',
                'severity_threshold' => 'info',
                'channel'            => 'admin_notice',
                'recipient'          => $admin_email,
                'subject_template'   => '[{site_name}] Threat intelligence updated',
                'message_template'   => "{message}\n\nView the intelligence dashboard: {admin_url}",
                'cooldown_minutes'   => 1440,
                'created_by'         => 0,
            ],
        ];

        foreach ( $defaults as $rule ) {
            $this->insert( $rule );
        }
    }
}

