<?php

declare(strict_types=1);

namespace WPUltimateSecurity\UltimateSecurity\Modules\Protection;

use WPUltimateSecurity\UltimateSecurity\Modules\Base\AbstractModule;
use WPUltimateSecurity\UltimateSecurity\Support\Helpers\Utils;

/**
 * Content Protection Module
 *
 * Prevents content copying through various methods:
 * - Right-click blocking
 * - Text selection disabling
 * - Copy/cut event blocking
 * - Image protection (dragging, overlay, hotlink)
 * - Keyboard shortcut blocking (dev tools, view source, save, print)
 *
 * @package WPUltimateSecurity\UltimateSecurity\Modules\Protection
 * @since 2.1.0
 */
class ContentProtection extends AbstractModule
{
    /**
     * Module identifier.
     */
    public const MODULE_ID = 'protection.content_protection';

    /**
     * Module version.
     */
    protected const VERSION = '2.1.0';

    /**
     * Content protection settings.
     *
     * @var array<string, mixed>
     */
    protected static array $options = [];

    /**
     * Get unique module identifier.
     */
    public static function getId(): string
    {
        return self::MODULE_ID;
    }

    /**
     * Get human-readable module name.
     */
    public static function getName(): string
    {
        return __('Content Protection', 'ultimate-security');
    }

    /**
     * Get module domain.
     */
    public static function getDomain(): string
    {
        return 'protection';
    }

    /**
     * Boot the module.
     */
    public static function boot(): void
    {
        $all_options = Utils::ultimate_security_get_option();
        self::$options = $all_options['security']['content_protection'] ?? [];

        if (empty(self::$options['enable']) || self::$options['enable'] !== '1') {
            return;
        }

        add_action('wp_head', [self::class, 'inject_protection_scripts'], 999);
        add_action('wp_head', [self::class, 'inject_protection_styles'], 999);

        if (!empty(self::$options['hotlink_protection']) && self::$options['hotlink_protection'] === '1') {
            add_action('admin_init', [self::class, 'setup_hotlink_protection']);
        }
    }

    /**
     * Cleanup on deactivation.
     */
    public static function deactivate(): void
    {
        self::remove_hotlink_protection();
    }

    /**
     * Check if protection should apply to current page.
     */
    protected static function should_protect(): bool
    {
        if (empty(self::$options) || empty(self::$options['enable']) || self::$options['enable'] !== '1') {
            return false;
        }

        if (is_admin()) {
            return false;
        }

        if (is_user_logged_in()) {
            $current_user = wp_get_current_user();

            if (in_array('administrator', $current_user->roles, true)) {
                return false;
            }

            $excluded_roles = self::$options['excluded_roles'] ?? [];
            if (!empty($excluded_roles)) {
                foreach ($excluded_roles as $role) {
                    if (is_array($role) && isset($role['code'])) {
                        $role_code = $role['code'];
                    } elseif (is_string($role)) {
                        $role_code = $role;
                    } else {
                        $role_code = '';
                    }

                    if ($role_code && in_array($role_code, $current_user->roles, true)) {
                        return false;
                    }
                }
            }
        }

        if (!empty(self::$options['protection_scope']) && self::$options['protection_scope'] === 'whole_site') {
            return true;
        }

        $page_ids = self::$options['page_ids'] ?? [];
        if (!empty($page_ids) && is_singular()) {
            $current_id = get_the_ID();
            foreach ($page_ids as $page) {
                if (is_array($page) && isset($page['code'])) {
                    $page_id = (int) $page['code'];
                } elseif (is_numeric($page)) {
                    $page_id = (int) $page;
                } else {
                    $page_id = 0;
                }

                if ($page_id && $page_id === $current_id) {
                    return true;
                }
            }
        }

        if (!empty(self::$options['protect_woocommerce']) && self::$options['protect_woocommerce'] === '1') {
            if (function_exists('is_product') && is_product()) {
                $product_cats = self::$options['product_categories'] ?? [];
                if (empty($product_cats)) {
                    return true;
                }

                global $post;
                if ($post && function_exists('wc_get_product_cat_ids')) {
                    $product_cat_ids = wc_get_product_cat_ids($post->ID);
                    foreach ($product_cats as $cat) {
                        if (is_array($cat) && isset($cat['code'])) {
                            $cat_id = (int) $cat['code'];
                        } elseif (is_numeric($cat)) {
                            $cat_id = (int) $cat;
                        } else {
                            $cat_id = 0;
                        }

                        if ($cat_id && in_array($cat_id, $product_cat_ids, true)) {
                            return true;
                        }
                    }
                }
            }
        }

        $custom_urls = self::$options['custom_urls'] ?? [];
        if (!empty($custom_urls)) {
            $current_uri = isset($_SERVER['REQUEST_URI'])
                ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI']))
                : '';

            foreach ($custom_urls as $url) {
                $pattern = is_array($url) ? ($url['value'] ?? '') : $url;
                if (empty($pattern)) {
                    continue;
                }

                if (strpos($pattern, '*') !== false) {
                    $escaped = preg_quote($pattern, '/');
                    $regex = '/^' . str_replace('\*', '.*', $escaped) . '$/';
                    if (preg_match($regex, $current_uri)) {
                        return true;
                    }
                } elseif (strpos($current_uri, $pattern) === 0) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Inject protection JavaScript.
     */
    public static function inject_protection_scripts(): void
    {
        if (!self::should_protect()) {
            return;
        }

        $notification_type = self::$options['notification_type'] ?? 'alert';
        $msg_right_click = wp_json_encode(!empty(self::$options['message_right_click'])
            ? self::$options['message_right_click']
            : __('Right-click is disabled on this site.', 'ultimate-security'));
        $msg_copy = wp_json_encode(!empty(self::$options['message_copy'])
            ? self::$options['message_copy']
            : __('Content copying is not allowed.', 'ultimate-security'));
        $msg_keyboard = wp_json_encode(!empty(self::$options['message_keyboard'])
            ? self::$options['message_keyboard']
            : __('This keyboard shortcut is disabled.', 'ultimate-security'));

        $script = '<script type="text/javascript">';
        $script .= '(function(){';

        if ($notification_type === 'alert') {
            $script .= 'function usNotify(msg){alert(msg);}';
        } elseif ($notification_type === 'toast') {
            $script .= 'function usNotify(msg){';
            $script .= 'var t=document.createElement("div");';
            $script .= 't.style.cssText="position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:#333;color:#fff;padding:12px 24px;border-radius:4px;z-index:999999;font-size:14px;";';
            $script .= 't.textContent=msg;document.body.appendChild(t);';
            $script .= 'setTimeout(function(){t.remove();},3000);';
            $script .= '}';
        } else {
            $script .= 'function usNotify(msg){}';
        }

        if (!empty(self::$options['disable_right_click']) && self::$options['disable_right_click'] === '1') {
            $script .= 'document.addEventListener("contextmenu",function(e){e.preventDefault();usNotify(' . $msg_right_click . ');return false;});';
        }

        if (!empty(self::$options['disable_image_right_click']) && self::$options['disable_image_right_click'] === '1') {
            $script .= 'document.querySelectorAll("img").forEach(function(img){img.addEventListener("contextmenu",function(e){e.preventDefault();usNotify(' . $msg_right_click . ');return false;});});';
        }

        if (!empty(self::$options['disable_copy']) && self::$options['disable_copy'] === '1') {
            $script .= 'document.addEventListener("copy",function(e){e.preventDefault();usNotify(' . $msg_copy . ');return false;});';
            $script .= 'document.addEventListener("keydown",function(e){if((e.ctrlKey||e.metaKey)&&e.key==="c"){e.preventDefault();usNotify(' . $msg_copy . ');}});';
        }

        if (!empty(self::$options['disable_cut']) && self::$options['disable_cut'] === '1') {
            $script .= 'document.addEventListener("cut",function(e){e.preventDefault();usNotify(' . $msg_copy . ');return false;});';
            $script .= 'document.addEventListener("keydown",function(e){if((e.ctrlKey||e.metaKey)&&e.key==="x"){e.preventDefault();usNotify(' . $msg_copy . ');}});';
        }

        if (!empty(self::$options['disable_image_dragging']) && self::$options['disable_image_dragging'] === '1') {
            $script .= 'document.querySelectorAll("img").forEach(function(img){img.setAttribute("draggable","false");img.addEventListener("dragstart",function(e){e.preventDefault();return false;});});';
        }

        if (!empty(self::$options['disable_dev_tools']) && self::$options['disable_dev_tools'] === '1') {
            $script .= 'document.addEventListener("keydown",function(e){';
            $script .= 'if(e.key==="F12"||(e.ctrlKey&&e.shiftKey&&(e.key==="I"||e.key==="i"||e.key==="J"||e.key==="j"||e.key==="C"||e.key==="c"))){';
            $script .= 'e.preventDefault();usNotify(' . $msg_keyboard . ');return false;}});';
        }

        if (!empty(self::$options['disable_view_source']) && self::$options['disable_view_source'] === '1') {
            $script .= 'document.addEventListener("keydown",function(e){if((e.ctrlKey||e.metaKey)&&(e.key==="u"||e.key==="U")){e.preventDefault();usNotify(' . $msg_keyboard . ');return false;}});';
        }

        if (!empty(self::$options['disable_save']) && self::$options['disable_save'] === '1') {
            $script .= 'document.addEventListener("keydown",function(e){if((e.ctrlKey||e.metaKey)&&(e.key==="s"||e.key==="S")){e.preventDefault();usNotify(' . $msg_keyboard . ');return false;}});';
        }

        if (!empty(self::$options['disable_print']) && self::$options['disable_print'] === '1') {
            $script .= 'document.addEventListener("keydown",function(e){if((e.ctrlKey||e.metaKey)&&(e.key==="p"||e.key==="P")){e.preventDefault();usNotify(' . $msg_keyboard . ');return false;}});';
        }

        if (!empty(self::$options['disable_mobile_longpress']) && self::$options['disable_mobile_longpress'] === '1') {
            $script .= 'var touchTimer;';
            $script .= 'document.addEventListener("touchstart",function(e){touchTimer=setTimeout(function(){e.preventDefault();},500);},{passive:false});';
            $script .= 'document.addEventListener("touchend",function(){clearTimeout(touchTimer);});';
            $script .= 'document.addEventListener("touchmove",function(){clearTimeout(touchTimer);});';
        }

        if (!empty(self::$options['image_overlay']) && self::$options['image_overlay'] === '1') {
            $script .= 'document.querySelectorAll("img").forEach(function(img){';
            $script .= 'var wrapper=document.createElement("div");';
            $script .= 'wrapper.style.cssText="position:relative;display:inline-block;";';
            $script .= 'img.parentNode.insertBefore(wrapper,img);wrapper.appendChild(img);';
            $script .= 'var overlay=document.createElement("div");';
            $script .= 'overlay.style.cssText="position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;";';
            $script .= 'wrapper.appendChild(overlay);';
            $script .= '});';
        }

        $script .= '})();';
        $script .= '</script>';

        echo $script; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

    /**
     * Inject protection CSS styles.
     */
    public static function inject_protection_styles(): void
    {
        if (!self::should_protect()) {
            return;
        }

        $css = '<style type="text/css">';

        if (!empty(self::$options['disable_text_selection']) && self::$options['disable_text_selection'] === '1') {
            $css .= 'body{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}';
        }

        if (!empty(self::$options['disable_touch_callout']) && self::$options['disable_touch_callout'] === '1') {
            $css .= 'body{-webkit-touch-callout:none;}';
            $css .= 'img{-webkit-touch-callout:none;}';
        }

        if (!empty(self::$options['disable_print']) && self::$options['disable_print'] === '1') {
            $css .= '@media print{body{display:none !important;}}';
        }

        if (!empty(self::$options['disable_image_dragging']) && self::$options['disable_image_dragging'] === '1') {
            $css .= 'img{-webkit-user-drag:none;-khtml-user-drag:none;-moz-user-drag:none;-o-user-drag:none;user-drag:none;pointer-events:auto;}';
        }

        $css .= '</style>';

        echo $css; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

    /**
     * Setup hotlink protection via .htaccess.
     */
    public static function setup_hotlink_protection(): void
    {
        if (get_option('ultimate_security_hotlink_protection_setup')) {
            return;
        }

        $htaccess_file = ABSPATH . '.htaccess';
        if (!file_exists($htaccess_file) || !is_writable($htaccess_file)) {
            return;
        }

        $site_url = parse_url(home_url(), PHP_URL_HOST);
        $site_url = preg_quote((string) $site_url, '/');

        $hotlink_rules = "\n# BEGIN Ultimate Security Hotlink Protection\n";
        $hotlink_rules .= "<IfModule mod_rewrite.c>\n";
        $hotlink_rules .= "RewriteEngine On\n";
        $hotlink_rules .= "RewriteCond %{HTTP_REFERER} !^$\n";
        $hotlink_rules .= "RewriteCond %{HTTP_REFERER} !^https?://(www\\.)?" . $site_url . " [NC]\n";
        $hotlink_rules .= "RewriteRule \\.(jpg|jpeg|png|gif|webp|svg)$ - [F,NC,L]\n";
        $hotlink_rules .= "</IfModule>\n";
        $hotlink_rules .= "# END Ultimate Security Hotlink Protection\n";

        $htaccess_content = file_get_contents($htaccess_file);
        if ($htaccess_content === false) {
            return;
        }

        if (strpos($htaccess_content, 'Ultimate Security Hotlink Protection') !== false) {
            update_option('ultimate_security_hotlink_protection_setup', true);
            return;
        }

        $new_content = $hotlink_rules . $htaccess_content;
        file_put_contents($htaccess_file, $new_content);

        update_option('ultimate_security_hotlink_protection_setup', true);
    }

    /**
     * Remove hotlink protection from .htaccess.
     */
    public static function remove_hotlink_protection(): void
    {
        $htaccess_file = ABSPATH . '.htaccess';
        if (!file_exists($htaccess_file) || !is_writable($htaccess_file)) {
            return;
        }

        $htaccess_content = file_get_contents($htaccess_file);
        if ($htaccess_content === false) {
            return;
        }

        $pattern = '/\n?# BEGIN Ultimate Security Hotlink Protection.*?# END Ultimate Security Hotlink Protection\n?/s';
        $new_content = preg_replace($pattern, '', $htaccess_content);

        if ($new_content !== null && $new_content !== $htaccess_content) {
            file_put_contents($htaccess_file, $new_content);
        }

        delete_option('ultimate_security_hotlink_protection_setup');
    }
}
