<?php

namespace UltraguardPro\modules\woo_security;

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

use UltraguardPro\Plugin;
use UltraguardPro\core\BaseController;

class SkimmerDetectionEngine extends BaseController {

    public function __construct( Plugin $plugin ) {
        parent::__construct( $plugin );
    }

    public function scan_for_skimmers(): array {
        $scripts  = $this->get_checkout_page_scripts();
        $findings = [];
        $files    = 0;

        foreach ( $scripts as $script ) {
            $path = $script['path'] ?? '';
            if ( ! $path || ! file_exists( $path ) ) {
                continue;
            }

            ++$files;
            foreach ( $this->scan_js_file( $path ) as $finding ) {
                $findings[] = array_merge( $finding, [
                    'file_path'       => $path,
                    'file_url'        => $script['url'] ?? '',
                    'first_detected'  => current_time( 'mysql', true ),
                ] );
            }
        }

        $table = $this->plugin->modules->get_db_tables()->get_table( 'skimmer_scan_results' );
        if ( $table && method_exists( $table, 'insert' ) ) {
            foreach ( $findings as $finding ) {
                $table->insert( [
                    'file_path'      => $finding['file_path'],
                    'finding_type'   => $finding['finding_type'],
                    'severity'       => $finding['severity'],
                    'details'        => $finding['details'],
                    'first_detected' => $finding['first_detected'],
                ] );
            }
        }

        return [
            'files_scanned' => $files,
            'threats_found' => count( $findings ),
            'findings'      => $findings,
            'scanned_at'    => current_time( 'mysql', true ),
        ];
    }

    public function scan_js_file( string $file_path ): array {
        $contents = (string) @file_get_contents( $file_path );
        if ( '' === $contents ) {
            return [];
        }

        $patterns = [
            'base64_exfiltration' => [ '/atob\s*\(|btoa\s*\(|base64/i', 'high', 'Base64 or encoding pattern found in checkout script.' ],
            'external_fetch'      => [ '/(fetch|XMLHttpRequest|axios|jQuery\.ajax).*https?:\/\/(?![^"\']*' . preg_quote( wp_parse_url( home_url(), PHP_URL_HOST ), '/' ) . ')/is', 'critical', 'External network exfiltration pattern detected.' ],
            'magecart_domain'     => [ '/(magecart|api\-collect|card\-verify|checkout\-secure|google\-tag\-manager\-secure)\./i', 'critical', 'Known skimmer command-and-control pattern detected.' ],
            'submit_listener'     => [ '/addEventListener\s*\(\s*[\'"]submit[\'"].*(fetch|XMLHttpRequest|action\s*=)/is', 'high', 'Suspicious checkout submit listener found.' ],
            'card_field_exfil'    => [ '/querySelector(All)?\s*\(.*(card|cc|cvv|cvc|expiry).*?(fetch|XMLHttpRequest|submit)/is', 'critical', 'Potential payment field exfiltration pattern detected.' ],
            'obfuscation'         => [ '/String\.fromCharCode|split\(\s*[\'"]\|[\'"]\s*\)\.join|\\x[0-9a-f]{2}/i', 'medium', 'Obfuscated JavaScript pattern detected.' ],
        ];

        $findings = [];
        foreach ( $patterns as $type => $config ) {
            if ( preg_match( $config[0], $contents ) ) {
                $findings[] = [
                    'finding_type' => $type,
                    'severity'     => $config[1],
                    'details'      => $config[2],
                ];
            }
        }

        return $findings;
    }

    public function get_checkout_page_scripts(): array {
        $scripts = [];
        $root    = wp_normalize_path( WP_CONTENT_DIR );

        $dirs = array_filter( [
            wp_normalize_path( get_stylesheet_directory() ),
            wp_normalize_path( WP_PLUGIN_DIR ),
        ] );

        foreach ( $dirs as $dir ) {
            if ( ! is_dir( $dir ) ) {
                continue;
            }

            $iterator = new \RecursiveIteratorIterator(
                new \RecursiveDirectoryIterator( $dir, \FilesystemIterator::SKIP_DOTS )
            );

            foreach ( $iterator as $file ) {
                if ( ! $file->isFile() || 'js' !== strtolower( $file->getExtension() ) ) {
                    continue;
                }

                $path = wp_normalize_path( $file->getPathname() );
                if ( str_contains( $path, '/node_modules/' ) || str_contains( $path, '/vendor/' ) ) {
                    continue;
                }

                if ( 0 !== strpos( $path, $root ) ) {
                    continue;
                }

                $relative  = ltrim( substr( $path, strlen( $root ) ), '/' );
                $scripts[] = [
                    'path' => $path,
                    'url'  => content_url( $relative ),
                ];
            }
        }

        return array_slice( $scripts, 0, 500 );
    }

    public function is_external_domain( string $url ): bool {
        $host      = wp_parse_url( $url, PHP_URL_HOST );
        $site_host = wp_parse_url( home_url(), PHP_URL_HOST );

        return ! empty( $host ) && $host !== $site_host;
    }
}
