<?php

if (!defined('ABSPATH')) {
    die('You are not allowed to call this page directly.');
}

/**
 * Helper class for DRM debug functionality
 *
 * Provides methods to display and analyze DRM-related information in the WordPress site health section
 */
class MeprDrmDebugHelper
{
    /**
     * Adds DRM debug information to the WordPress site health page
     *
     * @param array $tests Array of existing site health tests.
     *
     * @return array Modified array of site health tests including DRM debug information
     */
    public static function site_health_debug_status($tests)
    {
        if (!isset($_GET['mepr_drm_debug']) || !MeprUtils::is_logged_in_and_an_admin()) {
            return $tests;
        }

        $tests['direct']['mepr_drm_debug'] = [
            'label' => __('MemberPress - DRM Info', 'memberpress'),
            'test'  => ['MeprDrmDebugHelper', 'run_drm_debug'],
        ];

        return $tests;
    }

    /**
     * Main method to generate the DRM debug report
     *
     * Combines all debug sections and adds download functionality
     *
     * @return array Site health test result array containing the debug information
     */
    public static function run_drm_debug()
    {
        $content = '<div id="mepr-drm-debug-content" class="mepr-drm-debug">';

        // Build content from separate sections.
        $content .= self::get_drm_status_section();
        $content .= self::get_drm_options_section();
        $content .= self::get_drm_events_section();
        $content .= self::get_debug_styles();
        $content .= '</div>';

        // Get HTML and JS for the download button.
        $generate_report_parts = self::generate_html_js_button();
        if (!empty($generate_report_parts['html']) && !empty($generate_report_parts['js'])) {
            $content = $generate_report_parts['html'] . $content . $generate_report_parts['js'];
        }

        return [
            'label'       => __('DRM Debug Information', 'memberpress'),
            'status'      => 'critical',
            'badge'       => [
                'label' => 'DRM',
                'color' => 'orange',
            ],
            'description' => $content,
            'actions'     => '',
            'test'        => 'run_drm_debug',
        ];
    }

    /**
     * Generates the HTML button and JavaScript for downloading the debug report
     *
     * @return array {
     * Array containing button HTML and JavaScript
     *
     * @type string $html HTML for the download button
     * @type string $js   JavaScript for download functionality
     * }
     */
    private static function generate_html_js_button()
    {
        $button_html  = '<div style="text-align: right; margin-bottom: 5px;">';
        $button_html .= sprintf(
            '<button class="button button-small copy-debug" onclick="meprDownloadDebug(this)" data-target="mepr-drm-debug-content">%s</button>',
            esc_html__('Download', 'memberpress')
        );
        $button_html .= '</div>';

        $button_js = '
        <script>
        function meprDownloadDebug(button) {
            const debugId = button.getAttribute("data-target");
            const debugContent = document.getElementById(debugId);

            if (! debugContent) {
                console.error("Debug content not found");
                return;
            }

            try {
                // Clone the content so we can modify it without affecting the page.
                const contentClone = debugContent.cloneNode(true);

                // Remove all copy buttons.
                const copyButtons = contentClone.querySelectorAll(".copy-sql, .copy-debug");
                copyButtons.forEach(btn => btn.remove());

                // Sanitize content - remove any script tags.
                const scripts = contentClone.getElementsByTagName("script");
                while (scripts.length > 0) {
                    scripts[0].parentNode.removeChild(scripts[0]);
                }

                // Create the HTML document.
                const html = `
                    <!DOCTYPE html>
                    <html>
                    <head>
                        <meta charset="utf-8">
                        <meta name="robots" content="noindex, nofollow">
                        <meta name="viewport" content="width=device-width, initial-scale=1">
                        <title>DRM Debug Information</title>
                        <style>
                            :root {
                                --border-color: #c3c4c7;
                                --background-light: #f6f7f7;
                                --text-primary: #1d2327;
                                --text-secondary: #50575e;
                                --accent-color: #2271b1;
                                --spacing-sm: 8px;
                                --spacing-md: 16px;
                                --spacing-lg: 24px;
                                --spacing-xl: 32px;
                            }

                            body {
                                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
                                line-height: 1.5;
                                padding: var(--spacing-xl);
                                max-width: 1200px;
                                margin: 0 auto;
                                background: #f0f0f1;
                                color: var(--text-primary);
                            }
                            .mepr-drm-debug {
                                background: #fff;
                                border: 1px solid var(--border-color);
                                box-shadow: 0 1px 1px rgba(0,0,0,.04);
                                padding: var(--spacing-xl);
                                border-radius: 4px;
                            }
                            table {
                                width: 100%;
                                border-collapse: separate;
                                border-spacing: 0;
                                margin: var(--spacing-lg) 0 var(--spacing-xl);
                                background: #fff;
                                border: 1px solid var(--border-color);
                                box-shadow: 0 1px 1px rgba(0,0,0,.04);
                                border-radius: 4px;
                                overflow: hidden;
                            }
                            th, td {
                                padding: var(--spacing-md);
                                text-align: left;
                                border-bottom: 1px solid var(--border-color);
                                border-right: 1px solid var(--border-color);
                                vertical-align: top;
                            }
                            th:last-child, td:last-child { border-right: none; }
                            tr:last-child td, tr:last-child th { border-bottom: none; }
                            th {
                                background: var(--background-light);
                                font-weight: 600;
                                color: var(--text-primary);
                            }
                            table.two-col th { width: 30%; }
                            table.three-col th { width: auto; }
                            .striped tbody tr:nth-child(odd) { background-color: #fff; }
                            .striped tbody tr:nth-child(even) { background-color: var(--background-light); }
                            h1 {
                                color: var(--text-primary);
                                font-size: 24px;
                                margin: 0 0 var(--spacing-xl);
                                padding-bottom: var(--spacing-md);
                                border-bottom: 2px solid var(--accent-color);
                                font-weight: 600;
                            }
                            h2 {
                                color: var(--text-primary);
                                font-size: 20px;
                                margin: var(--spacing-xl) 0 var(--spacing-md);
                                padding-bottom: var(--spacing-sm);
                                border-bottom: 1px solid var(--border-color);
                                font-weight: 600;
                            }
                            h3 {
                                color: var(--text-primary);
                                font-size: 16px;
                                margin: var(--spacing-lg) 0 var(--spacing-md);
                                font-weight: 600;
                            }
                            .mepr-serialized-data {
                                margin: var(--spacing-sm) 0;
                                padding: var(--spacing-md);
                                background: var(--background-light);
                                border: 1px solid var(--border-color);
                                border-radius: 3px;
                            }
                            .mepr-data-row {
                                margin: var(--spacing-sm) 0;
                                line-height: 1.5;
                                display: flex;
                                align-items: flex-start;
                            }
                            .mepr-key {
                                font-weight: 600;
                                margin-right: var(--spacing-md);
                                color: var(--accent-color);
                                min-width: 120px;
                            }
                            .mepr-meta {
                                color: var(--text-secondary);
                                font-size: 12px;
                                margin-top: var(--spacing-xl);
                                padding-top: var(--spacing-md);
                                border-top: 1px solid var(--border-color);
                            }
                            @media print {
                                body {
                                    background: #fff;
                                    padding: var(--spacing-md);
                                }
                                .mepr-drm-debug {
                                    border: none;
                                    box-shadow: none;
                                    padding: 0;
                                }
                                table {
                                    box-shadow: none;
                                    border: 1px solid #000;
                                }
                                th, td {
                                    border-color: #000;
                                }
                                .mepr-serialized-data {
                                    border: 1px solid #000;
                                }
                            }
                        </style>
                    </head>
                    <body>
                        <h1>DRM Debug Information</h1>
                        ${contentClone.innerHTML}
                        <div class="mepr-meta">
                            Generated: ${new Date().toLocaleString()}
                            <br>
                            User ID: ' . (int) get_current_user_id() . '
                        </div>
                    </body>
                    </html>`;

                // Create blob and download with error handling
                try {
                    const blob = new Blob([html], { type: "text/html" });
                    const url = window.URL.createObjectURL(blob);
                    const a = document.createElement("a");
                    a.href = url;
                    a.download = "memberpress-drm-debug-" + new Date().toISOString().split("T")[0] + ".html";
                    document.body.appendChild(a);
                    a.click();
                    window.URL.revokeObjectURL(url);
                    document.body.removeChild(a);

                    // Show feedback.
                    const originalText = button.textContent;
                    button.textContent = "' . esc_js(__('Downloaded!', 'memberpress')) . '";
                    setTimeout(function() {
                        button.textContent = originalText;
                    }, 2000);
                } catch (error) {
                    console.error("Download failed:", error);
                    button.textContent = "' . esc_js(__('Download Failed', 'memberpress')) . '";
                    setTimeout(function() {
                        button.textContent = originalText;
                    }, 2000);
                }
            } catch (error) {
                console.error("Content processing failed:", error);
            }
        }
        </script>';

        return [
            'html' => $button_html,
            'js'   => $button_js,
        ];
    }

    /**
     * Generates the DRM status section of the debug report
     *
     * Shows current DRM status, license information, and active event details
     *
     * @return string HTML content for the DRM status section
     */
    private static function get_drm_status_section()
    {
        $drm_status  = MeprDrmHelper::get_status();
        $license_key = MeprDrmHelper::get_key();

        if (empty($drm_status)) {
            $drm_status = '-';
        }

        if (empty($license_key)) {
            $license_key = '-';
        }

        $drm_event_data = self::get_current_drm_event_data();
        $content        = '<h2>' . esc_html__('Current DRM Status', 'memberpress') . '</h2>';
        $content       .= '<table id="drm-status-table" class="widefat striped">';
        $content       .= sprintf(
            '<tr><th>%s</th><td>%s</td></tr>',
            esc_html__('DRM Event Type', 'memberpress'),
            esc_html($drm_event_data['type'] ?? '-')
        );
        $content       .= sprintf(
            '<tr><th>%s</th><td>%s</td></tr>',
            esc_html__('DRM Days Elapsed', 'memberpress'),
            esc_html($drm_event_data['days_elapsed'] ?? '-')
        );
        $content       .= sprintf(
            '<tr><th>%s</th><td>%s</td></tr>',
            esc_html__('DRM Status', 'memberpress'),
            esc_html($drm_status)
        );
        $content       .= sprintf(
            '<tr><th>%s</th><td>%s</td></tr>',
            esc_html__('License Key', 'memberpress'),
            esc_html($license_key)
        );
        $content       .= sprintf(
            '<tr><th>%s</th><td>%s</td></tr>',
            esc_html__('License Valid', 'memberpress'),
            MeprDrmHelper::is_valid() ? esc_html__('Yes', 'memberpress') : esc_html__('No', 'memberpress')
        );
        $content       .= '</table>';

        if (!empty($drm_event_data['type']) && !empty($drm_event_data['event']) && $drm_event_data['event'] instanceof MeprEvent) {
            $content .= '<h3>' . esc_html__('Current DRM Event Information', 'memberpress') . '</h3>';
            $content .= '<table class="widefat striped">';
            $content .= sprintf(
                '<tr><th>%s</th><th>%s</th><th>%s</th></tr>',
                esc_html__('Event', 'memberpress'),
                esc_html__('Created At', 'memberpress'),
                esc_html__('Args', 'memberpress')
            );
            $content .= self::format_event_row($drm_event_data['event']);
            $content .= '</table>';
        }
        return $content;
    }

    /**
     * Gets the DRM options from the WordPress options table
     *
     * Displays all options with 'mepr_drm_' prefix
     *
     * @return string HTML content showing all DRM-related options
     */
    private static function get_drm_options_section()
    {
        global $wpdb;

        $content  = sprintf('<h2>%s</h2>', esc_html__('DRM Options Log', 'memberpress'));
        $content .= '<table class="widefat striped">';
        $content .= sprintf(
            '<tr><th>%s</th><th>%s</th></tr>',
            esc_html__('Name', 'memberpress'),
            esc_html__('Value', 'memberpress')
        );

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery
        $drm_options = $wpdb->get_results(
            'SELECT option_name, option_value ' .
            "FROM {$wpdb->options} " .
            'WHERE option_name LIKE "mepr_drm_%" ' .
            'ORDER BY option_id ASC'
        );

        foreach ($drm_options as $option) {
            $value    = self::format_option_value($option->option_name, $option->option_value);
            $content .= sprintf(
                '<tr><th>%s</th><td>%s</td></tr>',
                esc_html($option->option_name),
                wp_kses_post($value)
            );
        }
        $content .= '</table>';

        return $content;
    }

    /**
     * Gets the chronological history of DRM events
     *
     * @return string HTML content showing all DRM events in chronological order
     */
    private static function get_drm_events_section()
    {
        $content  = sprintf('<h2>%s</h2>', esc_html__('DRM Events Chronological', 'memberpress'));
        $content .= '<table class="widefat striped">';
        $content .= sprintf(
            '<tr><th>%s</th><th>%s</th><th>%s</th></tr>',
            esc_html__('Event', 'memberpress'),
            esc_html__('Created At', 'memberpress'),
            esc_html__('Args', 'memberpress')
        );

        $drm_events = MeprEvent::get_all_by_evt_id_type(MeprEvent::$drm_str, 'id ASC');

        foreach ($drm_events as $event) {
            if ($event) {
                $content .= self::format_event_row($event);
            }
        }
        $content .= '</table>';

        return $content;
    }

    /**
     * Formats an option value for display based on its type and name
     *
     * @param string $option_name  The name of the option.
     * @param string $option_value The raw value of the option.
     *
     * @return string Formatted HTML for displaying the option value
     */
    private static function format_option_value($option_name, $option_value)
    {
        if (is_serialized($option_value)) {
            $unserialized = maybe_unserialize($option_value);
            if (is_array($unserialized)) {
                $formatted = '<div class="mepr-serialized-data">';
                foreach ($unserialized as $key => $value) {
                    if (is_numeric($value) && strlen($value) === 10) {
                        $value = sprintf(
                            '%s (%s)',
                            $value,
                            gmdate('Y-m-d H:i:s', (int) $value)
                        );
                    }
                    $formatted .= sprintf(
                        '<div class="mepr-data-row"><span class="mepr-key">%s:</span> <span class="mepr-value">%s</span></div>',
                        esc_html($key),
                        esc_html($value)
                    );
                }
                $formatted .= '</div>';

                return $formatted;
            }
        }

        if (is_numeric($option_value) && strlen($option_value) === 10) {
            return sprintf(
                '%s (%s)',
                $option_value,
                gmdate('Y-m-d H:i:s', (int) $option_value)
            );
        }

        return $option_value;
    }

    /**
     * Formats a DRM event row for display in tables
     *
     * @param object $event The event object to format.
     *
     * @return string HTML for the event table row
     */
    private static function format_event_row($event)
    {
        $args_data      = json_decode($event->args, true);
        $formatted_args = '';

        if (is_array($args_data)) {
            foreach ($args_data as $key => $value) {
                if (is_numeric($value) && strlen($value) === 10) {
                    $value = sprintf(
                        '%s (%s)',
                        $value,
                        gmdate('Y-m-d H:i:s', (int) $value)
                    );
                }
                $formatted_args .= sprintf(
                    '%s: %s<br>',
                    esc_html($key),
                    esc_html($value)
                );
            }
        }

        return sprintf(
            '<tr><td>%s</td><td>%s</td><td>%s</td></tr>',
            esc_html($event->event),
            esc_html($event->created_at),
            $formatted_args
        );
    }

    /**
     * Gets the CSS styles for the debug display
     *
     * @return string CSS styles for formatting the debug information
     */
    private static function get_debug_styles()
    {
        return '<style>
            .mepr-drm-debug table { margin-bottom: 20px; }
            .mepr-drm-debug h3 { margin: 20px 0 10px; }
            .mepr-drm-debug th { width: 250px; }
        </style>';
    }

    /**
     * Gets the current DRM event data including type, event object, and days elapsed
     *
     * @return array {
     * Array containing current DRM event information
     *
     * @type string      $type         The type of DRM event
     * @type MeprEvent   $event        The event object
     * @type int         $days_elapsed Number of days since the event
     * }
     */
    private static function get_current_drm_event_data()
    {
        // Check DRM license status flags.
        $drm_no_license      = get_option('mepr_drm_no_license', false);
        $drm_invalid_license = get_option('mepr_drm_invalid_license', false);

        $drm_event_type = '';
        if ($drm_no_license) {
            $drm_event_type = MeprDrmHelper::NO_LICENSE_EVENT;
        } elseif ($drm_invalid_license) {
            $drm_event_type = MeprDrmHelper::INVALID_LICENSE_EVENT;
        }

        $data = [];
        if (!empty($drm_event_type)) {
            $event = MeprEvent::latest($drm_event_type);
            if ($event) {
                $data['type']         = $drm_event_type;
                $data['event']        = $event;
                $data['days_elapsed'] = MeprDrmHelper::days_elapsed($event->created_at);
            }
        }

        return $data;
    }
}
