<?php
declare(strict_types=1);

namespace Help4BuilderSuite\Modules\Feedback;

use Help4BuilderSuite\Contracts\ModuleContract;
use Help4BuilderSuite\Support\FeatureFlags;
use Help4BuilderSuite\Support\RemoteUrlGuard;
use Help4BuilderSuite\Support\Settings;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;

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

final class Module implements ModuleContract
{
    private const LOCAL_LOG_OPTION = 'h4bs_igor_feedback_log';
    private const POST_TYPE = 'h4_igor_feedback';
    private const REST_NAMESPACE = 'h4bs/v1';

    public function key(): string
    {
        return 'feedback';
    }

    public function boot(): void
    {
        add_action('init', [$this, 'registerPostType']);
        add_action('admin_menu', [$this, 'registerAdminPage']);
        add_action('admin_post_h4bs_igor_feedback_submit', [$this, 'handleAdminPost']);
        add_action('rest_api_init', [$this, 'registerRestRoutes']);
    }

    public function registerPostType(): void
    {
        if (! $this->isHelp4OwnedHost()) {
            return;
        }

        register_post_type(
            self::POST_TYPE,
            [
                'labels' => [
                    'name'          => __('I.G.O.R. Feedback', 'help4-builder-suite'),
                    'singular_name' => __('I.G.O.R. Feedback Report', 'help4-builder-suite'),
                    'menu_name'     => __('I.G.O.R. Inbox', 'help4-builder-suite'),
                ],
                'public'              => false,
                'show_ui'             => true,
                'show_in_menu'        => 'h4bs-settings',
                'show_in_rest'        => false,
                'capability_type'     => 'post',
                'capabilities'        => [
                    'create_posts' => 'do_not_allow',
                ],
                'map_meta_cap'        => true,
                'supports'            => ['title', 'editor', 'custom-fields'],
                'menu_icon'           => 'dashicons-feedback',
            ]
        );
    }

    public function registerAdminPage(): void
    {
        add_submenu_page(
            'h4bs-settings',
            __('I.G.O.R. Feedback', 'help4-builder-suite'),
            __('I.G.O.R. Feedback', 'help4-builder-suite'),
            'manage_options',
            'h4bs-igor-feedback',
            [$this, 'renderAdminPage']
        );
    }

    public function registerRestRoutes(): void
    {
        register_rest_route(
            self::REST_NAMESPACE,
            '/igor-feedback/details',
            [
                'methods'             => 'GET',
                'callback'            => [$this, 'detailsRoute'],
                'permission_callback' => static fn (): bool => current_user_can('manage_options'),
            ]
        );

        register_rest_route(
            self::REST_NAMESPACE,
            '/igor-feedback/submit',
            [
                'methods'             => 'POST',
                'callback'            => [$this, 'submitRoute'],
                'permission_callback' => static fn (): bool => current_user_can('manage_options'),
            ]
        );

        register_rest_route(
            self::REST_NAMESPACE,
            '/igor-feedback/collect',
            [
                'methods'             => 'POST',
                'callback'            => [$this, 'collectRoute'],
                'permission_callback' => [$this, 'canCollectRemoteFeedback'],
            ]
        );
    }

    public function detailsRoute(): WP_REST_Response
    {
        return new WP_REST_Response(
            [
                'ok'          => true,
                'agent'       => 'I.G.O.R.',
                'meaning'     => 'Integrated Graphical Organized Response',
                'diagnostics' => $this->collectDiagnostics(),
            ]
        );
    }

    public function submitRoute(WP_REST_Request $request): WP_REST_Response|WP_Error
    {
        $report = $this->reportFromArray($request->get_json_params());
        if (is_wp_error($report)) {
            return $report;
        }

        $payload = $this->buildPayload($report);
        $result = $this->submitPayload($payload);
        $this->recordLocalSubmission($payload, $result);

        $status = ! empty($result['ok']) ? 200 : 502;
        return new WP_REST_Response($result, $status);
    }

    public function canCollectRemoteFeedback(): bool
    {
        return $this->isHelp4OwnedHost();
    }

    public function collectRoute(WP_REST_Request $request): WP_REST_Response|WP_Error
    {
        if (! $this->rateLimitAllowsCollection()) {
            return new WP_Error(
                'h4bs_igor_rate_limited',
                __('Please wait a moment before sending another feedback report.', 'help4-builder-suite'),
                ['status' => 429]
            );
        }

        $payload = $this->sanitizeIncomingPayload($request->get_json_params());
        $report = is_array($payload['report'] ?? null) ? $payload['report'] : [];
        if (empty($payload['consent']) || empty($report['subject']) || empty($report['message'])) {
            return new WP_Error(
                'h4bs_igor_invalid_payload',
                __('Feedback payload is missing consent, subject, or message.', 'help4-builder-suite'),
                ['status' => 400]
            );
        }

        $reportId = $this->makeReportId($payload);
        $postId = $this->storeCollectedReport($reportId, $payload);

        return new WP_REST_Response(
            [
                'ok'        => true,
                'report_id' => $reportId,
                'stored'    => $postId > 0,
            ],
            201
        );
    }

    public function handleAdminPost(): void
    {
        if (! current_user_can('manage_options')) {
            wp_die(esc_html__('You do not have permission to send Help4 feedback.', 'help4-builder-suite'), 403);
        }

        check_admin_referer('h4bs_igor_feedback_submit');

        $raw = isset($_POST) && is_array($_POST) ? wp_unslash($_POST) : [];
        $report = $this->reportFromArray($raw);
        if (is_wp_error($report)) {
            $this->redirectWithStatus('error', $report->get_error_message());
        }

        $payload = $this->buildPayload($report);
        $result = $this->submitPayload($payload);
        $this->recordLocalSubmission($payload, $result);

        if (! empty($result['ok'])) {
            if (! empty($result['report_id'])) {
                /* translators: %s: I.G.O.R. feedback report reference ID. */
                $message = sprintf(__('I.G.O.R. report sent. Reference: %s', 'help4-builder-suite'), (string) $result['report_id']);
            } else {
                $message = __('I.G.O.R. report saved locally.', 'help4-builder-suite');
            }
            $this->redirectWithStatus('sent', $message);
        }

        $this->redirectWithStatus('error', (string) ($result['message'] ?? __('I.G.O.R. could not send the report.', 'help4-builder-suite')));
    }

    public function renderAdminPage(): void
    {
        if (! current_user_can('manage_options')) {
            return;
        }

        $settings = Settings::all();
        $diagnostics = $this->collectDiagnostics();
        $noticeNonce = isset($_GET['_wpnonce']) ? sanitize_text_field((string) wp_unslash($_GET['_wpnonce'])) : '';
        $validNotice = $noticeNonce !== '' && wp_verify_nonce($noticeNonce, 'h4bs_igor_feedback_notice');
        $status = $validNotice && isset($_GET['h4bs_igor_status']) ? sanitize_key((string) wp_unslash($_GET['h4bs_igor_status'])) : '';
        $message = $validNotice && isset($_GET['h4bs_igor_message']) ? sanitize_text_field((string) wp_unslash($_GET['h4bs_igor_message'])) : '';
        $endpoint = RemoteUrlGuard::normalize((string) ($settings['igor_feedback_endpoint'] ?? ''));
        $enabled = Settings::bool('igor_feedback_enabled', true);
        ?>
        <div class="wrap h4bs-admin-wrap">
            <h1><?php esc_html_e('I.G.O.R. Feedback', 'help4-builder-suite'); ?></h1>
            <p class="h4bs-admin-lead">
                <?php esc_html_e('Integrated Graphical Organized Response helps site teams send useful Builder Suite bug reports, compatibility notes, UI issues, and feature requests with the environment details developers usually need first.', 'help4-builder-suite'); ?>
            </p>

            <?php if ($status !== '' && $message !== '') : ?>
                <div class="notice <?php echo $status === 'sent' ? 'notice-success' : 'notice-error'; ?> inline">
                    <p><?php echo esc_html($message); ?></p>
                </div>
            <?php endif; ?>

            <?php if (! $enabled) : ?>
                <div class="notice notice-warning inline">
                    <p><?php esc_html_e('I.G.O.R. feedback intake is disabled in Help4 Settings. Enable it before sending reports from this screen.', 'help4-builder-suite'); ?></p>
                </div>
            <?php endif; ?>

            <div class="h4bs-admin-card-grid">
                <article class="h4bs-admin-card">
                    <h2><?php esc_html_e('What gets sent', 'help4-builder-suite'); ?></h2>
                    <p><?php esc_html_e('Your typed message, optional contact details, site URL, WordPress/PHP versions, active theme, active plugin names/versions, enabled Builder Suite modules, and non-secret Help4 settings.', 'help4-builder-suite'); ?></p>
                </article>
                <article class="h4bs-admin-card">
                    <h2><?php esc_html_e('What is not sent', 'help4-builder-suite'); ?></h2>
                    <p><?php esc_html_e('No cookies, saved payment keys, API secrets, application passwords, raw error logs, database content, customer records, or background tracking events are included.', 'help4-builder-suite'); ?></p>
                </article>
                <article class="h4bs-admin-card">
                    <h2><?php esc_html_e('Where it goes', 'help4-builder-suite'); ?></h2>
                    <p><code><?php echo esc_html($endpoint !== '' ? $endpoint : __('Local only', 'help4-builder-suite')); ?></code></p>
                </article>
            </div>

            <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
                <?php wp_nonce_field('h4bs_igor_feedback_submit'); ?>
                <input type="hidden" name="action" value="h4bs_igor_feedback_submit">
                <h2><?php esc_html_e('Send a report', 'help4-builder-suite'); ?></h2>
                <table class="form-table" role="presentation">
                    <tbody>
                        <tr>
                            <th scope="row"><label for="h4bs_igor_type"><?php esc_html_e('Report Type', 'help4-builder-suite'); ?></label></th>
                            <td>
                                <select id="h4bs_igor_type" name="report_type">
                                    <?php foreach ($this->reportTypes() as $value => $label) : ?>
                                        <option value="<?php echo esc_attr($value); ?>"><?php echo esc_html($label); ?></option>
                                    <?php endforeach; ?>
                                </select>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="h4bs_igor_severity"><?php esc_html_e('Severity', 'help4-builder-suite'); ?></label></th>
                            <td>
                                <select id="h4bs_igor_severity" name="severity">
                                    <?php foreach ($this->severityLevels() as $value => $label) : ?>
                                        <option value="<?php echo esc_attr($value); ?>"><?php echo esc_html($label); ?></option>
                                    <?php endforeach; ?>
                                </select>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="h4bs_igor_subject"><?php esc_html_e('Subject', 'help4-builder-suite'); ?></label></th>
                            <td><input id="h4bs_igor_subject" class="regular-text" type="text" name="subject" required maxlength="160"></td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="h4bs_igor_page_url"><?php esc_html_e('Affected Page URL', 'help4-builder-suite'); ?></label></th>
                            <td><input id="h4bs_igor_page_url" class="regular-text" type="url" name="page_url" placeholder="<?php echo esc_attr(home_url('/')); ?>"></td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="h4bs_igor_message"><?php esc_html_e('What happened?', 'help4-builder-suite'); ?></label></th>
                            <td>
                                <textarea id="h4bs_igor_message" class="large-text" name="message" rows="8" required></textarea>
                                <p class="description"><?php esc_html_e('Include what you expected, what happened instead, and the steps that make it happen again.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="h4bs_igor_contact_name"><?php esc_html_e('Contact Name', 'help4-builder-suite'); ?></label></th>
                            <td><input id="h4bs_igor_contact_name" class="regular-text" type="text" name="contact_name" maxlength="120"></td>
                        </tr>
                        <tr>
                            <th scope="row"><label for="h4bs_igor_contact_email"><?php esc_html_e('Reply Email', 'help4-builder-suite'); ?></label></th>
                            <td>
                                <input id="h4bs_igor_contact_email" class="regular-text" type="email" name="contact_email" value="<?php echo esc_attr((string) wp_get_current_user()->user_email); ?>">
                                <p class="description"><?php esc_html_e('Check spam and other folders for replies from help4wordpress.com, help4network.com, or help4.us.', 'help4-builder-suite'); ?></p>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><?php esc_html_e('Diagnostics', 'help4-builder-suite'); ?></th>
                            <td>
                                <label>
                                    <input type="checkbox" name="include_diagnostics" value="1" checked>
                                    <?php esc_html_e('Include non-secret plugin and environment details with this report.', 'help4-builder-suite'); ?>
                                </label>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row"><?php esc_html_e('Consent', 'help4-builder-suite'); ?></th>
                            <td>
                                <label>
                                    <input type="checkbox" name="consent" value="1" required>
                                    <?php esc_html_e('I understand this sends my report and selected diagnostics to the configured Help4 feedback endpoint.', 'help4-builder-suite'); ?>
                                </label>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <?php submit_button(__('Send to I.G.O.R.', 'help4-builder-suite'), 'primary', 'submit', true, $enabled ? [] : ['disabled' => 'disabled']); ?>
            </form>

            <h2><?php esc_html_e('Diagnostic preview', 'help4-builder-suite'); ?></h2>
            <div class="h4bs-admin-table-scroll">
                <table class="widefat striped">
                    <tbody>
                        <?php foreach ($this->diagnosticPreviewRows($diagnostics) as $label => $value) : ?>
                            <tr>
                                <th scope="row"><?php echo esc_html($label); ?></th>
                                <td><?php echo esc_html($value); ?></td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>

            <?php $this->renderLocalSubmissionLog(); ?>

            <?php if ($this->isHelp4OwnedHost() && post_type_exists(self::POST_TYPE)) : ?>
                <p>
                    <a class="button" href="<?php echo esc_url(admin_url('edit.php?post_type=' . self::POST_TYPE)); ?>">
                        <?php esc_html_e('Open I.G.O.R. Inbox', 'help4-builder-suite'); ?>
                    </a>
                </p>
            <?php endif; ?>
        </div>
        <?php
    }

    /**
     * @param mixed $raw
     * @return array<string, mixed>|WP_Error
     */
    private function reportFromArray($raw): array|WP_Error
    {
        $raw = is_array($raw) ? $raw : [];
        $types = array_keys($this->reportTypes());
        $severities = array_keys($this->severityLevels());

        $type = sanitize_key((string) ($raw['report_type'] ?? 'bug'));
        if (! in_array($type, $types, true)) {
            $type = 'bug';
        }

        $severity = sanitize_key((string) ($raw['severity'] ?? 'normal'));
        if (! in_array($severity, $severities, true)) {
            $severity = 'normal';
        }

        $subject = sanitize_text_field((string) ($raw['subject'] ?? ''));
        $message = sanitize_textarea_field((string) ($raw['message'] ?? ''));
        $consent = ! empty($raw['consent']) && rest_sanitize_boolean($raw['consent']);
        if (! $consent) {
            return new WP_Error('h4bs_igor_missing_consent', __('Please confirm consent before sending the I.G.O.R. report.', 'help4-builder-suite'));
        }
        if ($subject === '' || $message === '') {
            return new WP_Error('h4bs_igor_missing_report', __('Please add a subject and message before sending the I.G.O.R. report.', 'help4-builder-suite'));
        }

        $email = sanitize_email((string) ($raw['contact_email'] ?? ''));
        if ($email !== '' && ! is_email($email)) {
            $email = '';
        }

        return [
            'report_type'         => $type,
            'severity'            => $severity,
            'subject'             => substr($subject, 0, 160),
            'page_url'            => esc_url_raw((string) ($raw['page_url'] ?? '')),
            'message'             => substr($message, 0, 8000),
            'contact_name'        => substr(sanitize_text_field((string) ($raw['contact_name'] ?? '')), 0, 120),
            'contact_email'       => $email,
            'include_diagnostics' => ! empty($raw['include_diagnostics']) && rest_sanitize_boolean($raw['include_diagnostics']),
            'consent'             => true,
        ];
    }

    /**
     * @param array<string, mixed> $report
     * @return array<string, mixed>
     */
    private function buildPayload(array $report): array
    {
        return [
            'agent'        => 'I.G.O.R.',
            'meaning'      => 'Integrated Graphical Organized Response',
            'source'       => 'help4-builder-suite',
            'schema'       => 'h4bs-igor-feedback-v1',
            'submitted_at' => gmdate('c'),
            'consent'      => true,
            'report'       => $report,
            'diagnostics'  => ! empty($report['include_diagnostics']) ? $this->collectDiagnostics() : [],
        ];
    }

    /**
     * @param array<string, mixed> $payload
     * @return array<string, mixed>
     */
    private function submitPayload(array $payload): array
    {
        if (! Settings::bool('igor_feedback_enabled', true)) {
            return [
                'ok'      => false,
                'message' => __('I.G.O.R. feedback intake is disabled in Help4 Settings.', 'help4-builder-suite'),
            ];
        }

        $endpoint = RemoteUrlGuard::normalize((string) Settings::get('igor_feedback_endpoint', ''));
        if ($endpoint === '') {
            return [
                'ok'         => true,
                'local_only' => true,
                'message'    => __('I.G.O.R. report saved locally because no remote endpoint is configured.', 'help4-builder-suite'),
            ];
        }

        if (! RemoteUrlGuard::isAllowed($endpoint)) {
            return [
                'ok'      => false,
                'message' => __('The configured I.G.O.R. endpoint is not an allowed public HTTP(S) URL.', 'help4-builder-suite'),
            ];
        }

        $body = wp_json_encode($payload, JSON_UNESCAPED_SLASHES);
        if (! is_string($body)) {
            return [
                'ok'      => false,
                'message' => __('I.G.O.R. could not encode the report payload.', 'help4-builder-suite'),
            ];
        }

        $response = wp_remote_post(
            $endpoint,
            [
                'timeout'     => 20,
                'redirection' => 2,
                'headers'     => [
                    'Accept'       => 'application/json',
                    'Content-Type' => 'application/json; charset=utf-8',
                    'User-Agent'   => 'Help4 Builder Suite/' . H4BS_VERSION . ' I.G.O.R.',
                ],
                'body'        => $body,
            ]
        );

        if (is_wp_error($response)) {
            return [
                'ok'      => false,
                'message' => $response->get_error_message(),
            ];
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        $responseBody = (string) wp_remote_retrieve_body($response);
        $json = json_decode($responseBody, true);
        $json = is_array($json) ? $json : [];

        if ($code < 200 || $code >= 300) {
            return [
                'ok'          => false,
                'status_code' => $code,
                'message'     => sanitize_text_field((string) ($json['message'] ?? wp_remote_retrieve_response_message($response))),
            ];
        }

        return [
            'ok'          => true,
            'status_code' => $code,
            'report_id'   => sanitize_text_field((string) ($json['report_id'] ?? '')),
            'message'     => __('I.G.O.R. report delivered.', 'help4-builder-suite'),
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private function collectDiagnostics(): array
    {
        global $wpdb;

        $theme = wp_get_theme();
        $parent = $theme->parent();
        $flags = (new FeatureFlags())->all();

        return [
            'site' => [
                'home_url'          => home_url('/'),
                'site_url'          => site_url('/'),
                'admin_url'         => admin_url(),
                'rest_url'          => rest_url(),
                'locale'            => get_locale(),
                'timezone'          => wp_timezone_string(),
                'multisite'         => is_multisite(),
                'environment_type'  => function_exists('wp_get_environment_type') ? wp_get_environment_type() : '',
                'permalink_structure' => (string) get_option('permalink_structure', ''),
            ],
            'wordpress' => [
                'version'        => get_bloginfo('version'),
                'debug'          => defined('WP_DEBUG') && WP_DEBUG,
                'debug_log'      => defined('WP_DEBUG_LOG') && WP_DEBUG_LOG,
                'memory_limit'   => defined('WP_MEMORY_LIMIT') ? WP_MEMORY_LIMIT : '',
                'max_memory'     => defined('WP_MAX_MEMORY_LIMIT') ? WP_MAX_MEMORY_LIMIT : '',
                'database_version' => is_object($wpdb) ? (string) $wpdb->db_version() : '',
            ],
            'server' => [
                'php_version'       => PHP_VERSION,
                'php_sapi'          => PHP_SAPI,
                'server_software'   => isset($_SERVER['SERVER_SOFTWARE']) ? sanitize_text_field((string) wp_unslash($_SERVER['SERVER_SOFTWARE'])) : '',
                'https'             => is_ssl(),
                'external_http_blocked' => defined('WP_HTTP_BLOCK_EXTERNAL') && WP_HTTP_BLOCK_EXTERNAL,
            ],
            'builder_suite' => [
                'version'                 => H4BS_VERSION,
                'plugin_file'             => plugin_basename(H4BS_FILE),
                'enabled_modules'         => array_keys(array_filter($flags)),
                'update_manifest_url'     => esc_url_raw((string) Settings::get('update_manifest_url', '')),
                'required_plugin_zip_url' => esc_url_raw((string) Settings::get('required_plugin_zip_url', '')),
                'required_theme_slug'     => sanitize_key((string) Settings::get('required_theme_slug', '')),
                'support_url'             => esc_url_raw((string) Settings::get('support_url', '')),
            ],
            'theme' => [
                'name'           => $theme->get('Name'),
                'version'        => $theme->get('Version'),
                'stylesheet'     => get_stylesheet(),
                'template'       => get_template(),
                'parent_name'    => $parent ? $parent->get('Name') : '',
                'parent_version' => $parent ? $parent->get('Version') : '',
            ],
            'plugins' => [
                'active'   => $this->activePluginList(),
                'mu'       => $this->mustUsePluginList(),
            ],
        ];
    }

    /**
     * @return array<int, array{name:string, version:string, file:string}>
     */
    private function activePluginList(): array
    {
        if (! function_exists('get_plugins')) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        $plugins = get_plugins();
        $active = array_fill_keys((array) get_option('active_plugins', []), true);
        $networkActive = is_multisite() ? (array) get_site_option('active_sitewide_plugins', []) : [];
        foreach (array_keys($networkActive) as $basename) {
            $active[(string) $basename] = true;
        }

        $rows = [];
        foreach ($plugins as $basename => $data) {
            if (empty($active[$basename])) {
                continue;
            }
            $rows[] = [
                'name'    => sanitize_text_field((string) ($data['Name'] ?? $basename)),
                'version' => sanitize_text_field((string) ($data['Version'] ?? '')),
                'file'    => sanitize_text_field((string) $basename),
            ];
        }

        return $rows;
    }

    /**
     * @return array<int, array{name:string, version:string, file:string}>
     */
    private function mustUsePluginList(): array
    {
        if (! function_exists('get_mu_plugins')) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        $rows = [];
        foreach (get_mu_plugins() as $basename => $data) {
            $rows[] = [
                'name'    => sanitize_text_field((string) ($data['Name'] ?? $basename)),
                'version' => sanitize_text_field((string) ($data['Version'] ?? '')),
                'file'    => sanitize_text_field((string) $basename),
            ];
        }

        return $rows;
    }

    /**
     * @return array<string, string>
     */
    private function diagnosticPreviewRows(array $diagnostics): array
    {
        $activePlugins = is_array($diagnostics['plugins']['active'] ?? null) ? $diagnostics['plugins']['active'] : [];
        $enabledModules = is_array($diagnostics['builder_suite']['enabled_modules'] ?? null) ? $diagnostics['builder_suite']['enabled_modules'] : [];

        return [
            __('Site', 'help4-builder-suite') => (string) ($diagnostics['site']['home_url'] ?? ''),
            __('WordPress', 'help4-builder-suite') => (string) ($diagnostics['wordpress']['version'] ?? ''),
            __('PHP', 'help4-builder-suite') => (string) ($diagnostics['server']['php_version'] ?? ''),
            __('Builder Suite', 'help4-builder-suite') => (string) ($diagnostics['builder_suite']['version'] ?? ''),
            __('Theme', 'help4-builder-suite') => trim((string) ($diagnostics['theme']['name'] ?? '') . ' ' . (string) ($diagnostics['theme']['version'] ?? '')),
            __('Enabled Modules', 'help4-builder-suite') => implode(', ', array_map('sanitize_key', $enabledModules)),
            __('Active Plugins', 'help4-builder-suite') => (string) count($activePlugins),
        ];
    }

    private function renderLocalSubmissionLog(): void
    {
        $log = get_option(self::LOCAL_LOG_OPTION, []);
        if (! is_array($log) || ! $log) {
            return;
        }
        ?>
        <h2><?php esc_html_e('Recent local submissions', 'help4-builder-suite'); ?></h2>
        <div class="h4bs-admin-table-scroll">
            <table class="widefat striped">
                <thead>
                    <tr>
                        <th><?php esc_html_e('Time', 'help4-builder-suite'); ?></th>
                        <th><?php esc_html_e('Subject', 'help4-builder-suite'); ?></th>
                        <th><?php esc_html_e('Status', 'help4-builder-suite'); ?></th>
                        <th><?php esc_html_e('Reference', 'help4-builder-suite'); ?></th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach (array_slice($log, 0, 10) as $entry) : ?>
                        <?php $entry = is_array($entry) ? $entry : []; ?>
                        <tr>
                            <td><?php echo esc_html((string) ($entry['time'] ?? '')); ?></td>
                            <td><?php echo esc_html((string) ($entry['subject'] ?? '')); ?></td>
                            <td><?php echo esc_html((string) ($entry['status'] ?? '')); ?></td>
                            <td><?php echo esc_html((string) ($entry['report_id'] ?? '')); ?></td>
                        </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        </div>
        <?php
    }

    /**
     * @param array<string, mixed> $payload
     * @param array<string, mixed> $result
     */
    private function recordLocalSubmission(array $payload, array $result): void
    {
        $log = get_option(self::LOCAL_LOG_OPTION, []);
        $log = is_array($log) ? $log : [];
        $report = is_array($payload['report'] ?? null) ? $payload['report'] : [];
        array_unshift(
            $log,
            [
                'time'      => gmdate('Y-m-d H:i:s') . ' UTC',
                'subject'   => sanitize_text_field((string) ($report['subject'] ?? '')),
                'status'    => ! empty($result['ok']) ? 'sent' : 'failed',
                'report_id' => sanitize_text_field((string) ($result['report_id'] ?? '')),
                'message'   => sanitize_text_field((string) ($result['message'] ?? '')),
            ]
        );

        update_option(self::LOCAL_LOG_OPTION, array_slice($log, 0, 20), false);
    }

    /**
     * @param mixed $payload
     * @return array<string, mixed>
     */
    private function sanitizeIncomingPayload($payload): array
    {
        $payload = is_array($payload) ? $payload : [];
        $clean = $this->sanitizePayloadValue($payload, 0);
        return is_array($clean) ? $clean : [];
    }

    /**
     * @param mixed $value
     * @return mixed
     */
    private function sanitizePayloadValue($value, int $depth)
    {
        if ($depth > 8) {
            return null;
        }
        if (is_array($value)) {
            $clean = [];
            foreach ($value as $key => $child) {
                $cleanKey = is_int($key) ? $key : substr(sanitize_key((string) $key), 0, 80);
                if ($cleanKey === '') {
                    continue;
                }
                $clean[$cleanKey] = $this->sanitizePayloadValue($child, $depth + 1);
            }
            return $clean;
        }
        if (is_bool($value) || is_int($value) || is_float($value) || $value === null) {
            return $value;
        }

        return substr(sanitize_textarea_field((string) $value), 0, 12000);
    }

    private function storeCollectedReport(string $reportId, array $payload): int
    {
        $report = is_array($payload['report'] ?? null) ? $payload['report'] : [];
        $subject = sanitize_text_field((string) ($report['subject'] ?? __('I.G.O.R. feedback report', 'help4-builder-suite')));
        $site = is_array($payload['diagnostics']['site'] ?? null)
            ? esc_url_raw((string) ($payload['diagnostics']['site']['home_url'] ?? ''))
            : '';
        $content = wp_json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
        $content = is_string($content) ? $content : '';

        $postId = wp_insert_post(
            [
                'post_type'    => self::POST_TYPE,
                'post_status'  => 'private',
                'post_title'   => $reportId . ' - ' . $subject,
                'post_content' => $content,
            ],
            true
        );

        if (is_wp_error($postId) || (int) $postId <= 0) {
            return 0;
        }

        update_post_meta((int) $postId, '_h4bs_igor_report_id', $reportId);
        update_post_meta((int) $postId, '_h4bs_igor_site', $site);
        update_post_meta((int) $postId, '_h4bs_igor_type', sanitize_key((string) ($report['report_type'] ?? '')));
        update_post_meta((int) $postId, '_h4bs_igor_severity', sanitize_key((string) ($report['severity'] ?? '')));
        update_post_meta((int) $postId, '_h4bs_igor_contact_email', sanitize_email((string) ($report['contact_email'] ?? '')));
        update_post_meta((int) $postId, '_h4bs_igor_ip_hash', $this->requestIpHash());

        return (int) $postId;
    }

    private function makeReportId(array $payload): string
    {
        $hash = substr(hash('sha256', wp_json_encode($payload) . '|' . microtime(true)), 0, 10);
        return 'H4-IGOR-' . gmdate('Ymd-His') . '-' . strtoupper($hash);
    }

    private function rateLimitAllowsCollection(): bool
    {
        $key = 'h4bs_igor_collect_' . $this->requestIpHash();
        if (get_transient($key)) {
            return false;
        }

        set_transient($key, '1', 45);
        return true;
    }

    private function requestIpHash(): string
    {
        $ip = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field((string) wp_unslash($_SERVER['REMOTE_ADDR'])) : 'unknown';
        return hash('sha256', $ip);
    }

    private function redirectWithStatus(string $status, string $message): void
    {
        wp_safe_redirect(
            add_query_arg(
                [
                    'page'              => 'h4bs-igor-feedback',
                    'h4bs_igor_status'  => sanitize_key($status),
                    'h4bs_igor_message' => $message,
                    '_wpnonce'          => wp_create_nonce('h4bs_igor_feedback_notice'),
                ],
                admin_url('admin.php')
            )
        );
        exit;
    }

    /**
     * @return array<string, string>
     */
    private function reportTypes(): array
    {
        return [
            'bug'           => __('Bug or broken feature', 'help4-builder-suite'),
            'ui'            => __('UI or design issue', 'help4-builder-suite'),
            'compatibility' => __('Theme/plugin compatibility', 'help4-builder-suite'),
            'performance'   => __('Performance or loading issue', 'help4-builder-suite'),
            'security'      => __('Security concern', 'help4-builder-suite'),
            'docs'          => __('Documentation gap', 'help4-builder-suite'),
            'feature'       => __('Feature request', 'help4-builder-suite'),
        ];
    }

    /**
     * @return array<string, string>
     */
    private function severityLevels(): array
    {
        return [
            'normal'   => __('Normal', 'help4-builder-suite'),
            'high'     => __('High - important workflow blocked', 'help4-builder-suite'),
            'critical' => __('Critical - site/admin broken', 'help4-builder-suite'),
            'idea'     => __('Idea / enhancement', 'help4-builder-suite'),
        ];
    }

    private function isHelp4OwnedHost(): bool
    {
        $host = strtolower((string) wp_parse_url(home_url('/'), PHP_URL_HOST));
        return in_array(
            $host,
            [
                'help4wordpress.com',
                'www.help4wordpress.com',
                'md.help4wordpress.com',
                'plugin.help4wordpress.com',
                'plugins.help4wordpress.com',
            ],
            true
        );
    }
}
