<?php

namespace UltraguardPro\modules\reputation_monitor\db;

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

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Reputation blacklist table intentionally performs live lookup/reporting queries.

use UltraguardPro\core\DatabaseSchema;
use UltraguardPro\db\BaseTable;

class BlacklistChecksTable extends BaseTable {

    protected $table_name  = 'ultraguard_blacklist_checks';
    protected $cache_group = 'ultraguard_blacklist_checks';

    public function get_defaults(): array {
        return [
            'id'              => 0,
            'source_id'       => '',
            'source_name'     => '',
            'check_type'      => 'domain',
            'target'          => '',
            'status'          => 'clean',
            'threat_type'     => '',
            'details'         => '',
            'last_checked_at' => '',
            'next_check_at'   => '',
            'created_at'      => '',
            'updated_at'      => '',
        ];
    }

    protected function validate_data( $data ) {
        return $this->validate_required( (array) $data, [ 'source_id', 'source_name', 'check_type', 'target', 'status' ] ) ? $data : false;
    }

    protected function sanitize_data( $data ): array {
        $out = [];
        foreach ( $data as $key => $value ) {
            if ( 'details' === $key ) {
                $out[ $key ] = sanitize_textarea_field( (string) $value );
            } else {
                $out[ $key ] = is_string( $value ) ? sanitize_text_field( $value ) : $value;
            }
        }

        return $out;
    }

    public function upsert_result( array $data ): bool {
        if ( ! $this->table_exists() ) {
            return false;
        }

        $row   = $this->get_by_source_target( (string) $data['source_id'], (string) $data['target'] );

        if ( ! empty( $row['id'] ) ) {
            return (bool) $this->update( (int) $row['id'], $data );
        }

        return false !== $this->insert( $data );
    }

    public function get_by_source_target( string $source_id, string $target ): ?array {
        if ( ! $this->table_exists() ) {
            return null;
        }

        $rows = $this->get_by( [ 'source_id' => $source_id, 'target' => $target ], 1 );
        return ! empty( $rows[0] ) ? $rows[0] : null;
    }

    public function get_summary(): array {
        if ( ! $this->table_exists() ) {
            return [];
        }

        return (array) $this->get_by( [], 100, 'source_name', 'ASC' );
    }

    public function count_by_status( string $status ): int {
        if ( ! $this->table_exists() ) {
            return 0;
        }

        return (int) $this->count( [ 'status' => $status ], 'id', false );
    }

    public function count_sources_monitoring(): int {
        return count( $this->get_summary() );
    }

    public function count_all_checks(): int {
        return count( $this->get_summary() );
    }

    private function table_exists(): bool {
        global $wpdb;

        $table_name = DatabaseSchema::get_table_name( $this->get_table_name_raw() );
        if ( empty( $table_name ) ) {
            return false;
        }

        return $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name; // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- query uses prepare(); table name is supplied as a value placeholder.
    }
}
