<?php

namespace CleantalkSP\SpbctWP\FileEditorDisabler;

class FileEditorDisabler
{
    /**
     * Syncs the disallow file editor based on the settings.
     * @param array $settings
     */
    public static function syncDisallowFileEditBySettings($settings)
    {
        if ( ! isset($settings['misc_disable_file_editor']) ) {
            return null;
        }

        $critical_count = self::getCriticalCount();

        if (
            ( $settings['misc_disable_file_editor'] == 2 && $critical_count > 0 ) ||
            $settings['misc_disable_file_editor'] == 1
        ) {
            return self::turnOnDisallowFileEdit();
        }
    }

    /**
     * Turns on disallow file editor
     * @return bool
     */
    private static function turnOnDisallowFileEdit()
    {
        add_filter('map_meta_cap', function ($caps, $_cap, $_user_id, $_args) {
            foreach ( $caps as &$cap_value ) {
                if (
                    $cap_value === 'edit_plugins' ||
                    $cap_value === 'edit_themes' ||
                    $cap_value === 'edit_files'
                ) {
                    $cap_value = 'do_not_allow';
                }
            } unset($cap_value);
            return $caps;
        }, 10, 4);

        // Customize wp_die message for plugin/theme editor
        add_filter('wp_die_handler', function ($handler) {
            // Only apply on plugin-editor.php or theme-editor.php pages
            if (!isset($_SERVER['REQUEST_URI'])) {
                return $handler;
            }
            $request_uri = $_SERVER['REQUEST_URI'];
            $is_plugin_editor = strpos($request_uri, 'plugin-editor.php') !== false;
            $is_theme_editor = strpos($request_uri, 'theme-editor.php') !== false;

            if (!$is_plugin_editor && !$is_theme_editor) {
                return $handler;
            }

            return function ($message, $title = '', $args = array()) use ($handler, $is_plugin_editor, $is_theme_editor) {
                // Default custom message
                $default_message = __('This function was disabled by the Security by CleanTalk plugin.');

                // Check if this is the plugin/theme editor error message
                $plugin_editor_message = __('Sorry, you are not allowed to edit plugins for this site.');
                $theme_editor_message = __('Sorry, you are not allowed to edit templates for this site.');

                if (($is_plugin_editor && ($message === $plugin_editor_message ||
                    (is_string($message) && strpos($message, 'not allowed to edit plugins') !== false))) ||
                    ($is_theme_editor && ($message === $theme_editor_message ||
                    (is_string($message) && strpos($message, 'not allowed to edit templates') !== false)))) {
                    // Check for custom message in URL parameter, otherwise use default
                    if (isset($_GET['error_msg']) && !empty($_GET['error_msg'])) {
                        $message = sanitize_text_field($_GET['error_msg']);
                    } elseif (isset($_GET['msg']) && !empty($_GET['msg'])) {
                        $message = sanitize_text_field($_GET['msg']);
                    } else {
                        $message = $default_message;
                    }
                }

                // Call the original handler
                return call_user_func($handler, $message, $title, $args);
            };
        });

        return true;
    }

    /**
     * Gets the critical count
     * @return int
     */
    private static function getCriticalCount()
    {
        global $wpdb;
        $query = 'SELECT COUNT(*)
            FROM ' . SPBC_TBL_SCAN_FILES . ' 
            WHERE (STATUS = "INFECTED" AND severity = "CRITICAL") 
            OR STATUS = "DENIED_BY_CLOUD"
            OR STATUS = "DENIED_BY_CT"';
        return (int)$wpdb->get_var($query);
    }
}
