<?php
declare(strict_types=1);

namespace KbMarkdownImporter\Admin;

use KbMarkdownImporter\GitLab\GitLabClient;
use KbMarkdownImporter\Import\ImportLogger;
use KbMarkdownImporter\Plugin;
use KbMarkdownImporter\Settings;

final class SettingsPage
{
    public static function registerSettings(): void
    {
        register_setting('kb_markdown_importer_settings', 'kb_markdown_importer_settings', [
            'type' => 'array',
            'sanitize_callback' => [self::class, 'sanitize'],
            'default' => Settings::defaults(),
        ]);
    }

    public static function sanitize(array $input): array
    {
        $old = Plugin::settings();
        $settings = Settings::defaults();

        $settings['gitlab_base_url'] = esc_url_raw(GitLabClient::normalizeBaseUrl((string) ($input['gitlab_base_url'] ?? '')));
        $settings['gitlab_token'] = trim((string) ($input['gitlab_token'] ?? '')) ?: (string) $old['gitlab_token'];
        $settings['gitlab_group'] = sanitize_text_field((string) ($input['gitlab_group'] ?? 'knowledgebase'));
        $settings['branch_pattern'] = sanitize_text_field((string) ($input['branch_pattern'] ?? '^v.*'));
        $settings['docs_base_slug'] = sanitize_title((string) ($input['docs_base_slug'] ?? 'docs')) ?: 'docs';
        $settings['image_lightbox'] = ! empty($input['image_lightbox']) ? '1' : '0';
        $settings['public_docs'] = ! empty($input['public_docs']) ? '1' : '0';
        $settings['allow_svg'] = ! empty($input['allow_svg']) ? '1' : '0';
        $settings['cron_interval'] = in_array(($input['cron_interval'] ?? 'disabled'), ['disabled', 'hourly', 'daily', 'weekly'], true) ? (string) $input['cron_interval'] : 'disabled';
        $settings['design_theme'] = in_array(($input['design_theme'] ?? 'obyte'), ['obyte', 'inherit'], true) ? (string) $input['design_theme'] : 'obyte';
        $settings['design_primary_color'] = self::sanitizeHexColor((string) ($input['design_primary_color'] ?? '#00A7E6'), '#00A7E6');
        $settings['design_accent_color'] = self::sanitizeHexColor((string) ($input['design_accent_color'] ?? '#F59C00'), '#F59C00');
        $settings['design_radius'] = (string) max(0, min(32, (int) ($input['design_radius'] ?? 14)));
        $settings['custom_theme_css_url'] = esc_url_raw((string) ($input['custom_theme_css_url'] ?? ''));
        $settings['docs_home_intro_title'] = sanitize_text_field((string) ($input['docs_home_intro_title'] ?? $settings['docs_home_intro_title']));
        $settings['docs_home_intro_content'] = wp_kses_post((string) ($input['docs_home_intro_content'] ?? $settings['docs_home_intro_content']));
        $settings['product_updates_source'] = in_array(($input['product_updates_source'] ?? 'rss'), ['rss', 'rest'], true) ? (string) $input['product_updates_source'] : 'rss';
        $settings['product_updates_feed_url'] = esc_url_raw((string) ($input['product_updates_feed_url'] ?? ''));
        $settings['product_updates_feed_limit'] = (string) max(1, min(20, (int) ($input['product_updates_feed_limit'] ?? 5)));
        $settings['product_updates_feed_item_path'] = self::sanitizeXmlPath((string) ($input['product_updates_feed_item_path'] ?? 'channel/item'), 'channel/item');
        $settings['product_updates_feed_product_field'] = self::sanitizeXmlPath((string) ($input['product_updates_feed_product_field'] ?? 'title'), 'title');
        $settings['product_updates_feed_version_field'] = self::sanitizeXmlPath((string) ($input['product_updates_feed_version_field'] ?? 'category'), 'category');
        $settings['product_updates_feed_date_field'] = self::sanitizeXmlPath((string) ($input['product_updates_feed_date_field'] ?? 'pubDate'), 'pubDate');
        $settings['product_updates_feed_changelog_field'] = self::sanitizeXmlPath((string) ($input['product_updates_feed_changelog_field'] ?? 'description'), 'description');
        $settings['product_updates_rest_url'] = esc_url_raw((string) ($input['product_updates_rest_url'] ?? ''));
        $settings['product_updates_rest_list_path'] = self::sanitizePathList((string) ($input['product_updates_rest_list_path'] ?? 'content,data,items'), 'content,data,items');
        $settings['product_updates_rest_product_field'] = self::sanitizePathList((string) ($input['product_updates_rest_product_field'] ?? 'product.name,productName,name'), 'product.name,productName,name');
        $settings['product_updates_rest_version_field'] = self::sanitizePathList((string) ($input['product_updates_rest_version_field'] ?? 'version,versionName,name'), 'version,versionName,name');
        $settings['product_updates_rest_date_field'] = self::sanitizePathList((string) ($input['product_updates_rest_date_field'] ?? 'releaseDate,date,updatedAt,createdAt'), 'releaseDate,date,updatedAt,createdAt');
        $settings['product_updates_rest_changelog_field'] = self::sanitizePathList((string) ($input['product_updates_rest_changelog_field'] ?? 'changelog,changeLog,description,changes'), 'changelog,changeLog,description,changes');

        Plugin::syncCronSchedule($settings);
        if (($old['docs_base_slug'] ?? 'docs') !== $settings['docs_base_slug']) {
            flush_rewrite_rules(false);
        }

        return $settings;
    }

    public static function render(): void
    {
        if (! current_user_can('manage_kb_docs')) {
            wp_die(esc_html__('Insufficient permissions.', 'kb-markdown-importer'));
        }

        if (isset($_POST['kb_markdown_test_connection']) && check_admin_referer('kb_markdown_test_connection')) {
            self::handleConnectionTest();
        }

        $updatesTest = null;
        if (isset($_POST['kb_markdown_test_product_updates']) && check_admin_referer('kb_markdown_test_product_updates')) {
            $updatesTest = self::handleProductUpdatesTest();
        }

        $settings = Plugin::settings();
        ?>
        <div class="wrap">
            <h1><?php esc_html_e('Markdown Knowledgebase Settings', 'kb-markdown-importer'); ?></h1>
            <form method="post" action="options.php">
                <?php settings_fields('kb_markdown_importer_settings'); ?>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><label for="gitlab_base_url">GitLab Base URL</label></th>
                        <td>
                            <input class="regular-text" id="gitlab_base_url" name="kb_markdown_importer_settings[gitlab_base_url]" type="url" value="<?php echo esc_attr($settings['gitlab_base_url']); ?>" placeholder="https://git.example.de">
                            <p class="description"><?php esc_html_e('Use the GitLab root URL, for example https://git.example.de. Do not include /api/v4.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="gitlab_token">GitLab API Token</label></th>
                        <td><input class="regular-text" id="gitlab_token" name="kb_markdown_importer_settings[gitlab_token]" type="password" value="" placeholder="<?php echo $settings['gitlab_token'] ? esc_attr__('Token is stored; leave blank to keep it', 'kb-markdown-importer') : ''; ?>"></td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="gitlab_group">GitLab Group Path / ID</label></th>
                        <td><input class="regular-text" id="gitlab_group" name="kb_markdown_importer_settings[gitlab_group]" type="text" value="<?php echo esc_attr($settings['gitlab_group']); ?>"></td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="branch_pattern">Branch Pattern</label></th>
                        <td><input class="regular-text" id="branch_pattern" name="kb_markdown_importer_settings[branch_pattern]" type="text" value="<?php echo esc_attr($settings['branch_pattern']); ?>"></td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="docs_base_slug">Frontend Base Slug</label></th>
                        <td><input class="regular-text" id="docs_base_slug" name="kb_markdown_importer_settings[docs_base_slug]" type="text" value="<?php echo esc_attr($settings['docs_base_slug']); ?>"></td>
                    </tr>
                    <tr>
                        <th scope="row">Markdown Project Structure</th>
                        <td>
                            <p class="description"><?php esc_html_e('Each version branch must contain doku.md, stepbystep.md and an images/ folder. Optional files such as faq.md and doku.yml are supported.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">Options</th>
                        <td>
                            <label><input type="checkbox" name="kb_markdown_importer_settings[image_lightbox]" value="1" <?php checked($settings['image_lightbox'], '1'); ?>> Link images with lightbox class</label><br>
                            <label><input type="checkbox" name="kb_markdown_importer_settings[public_docs]" value="1" <?php checked($settings['public_docs'], '1'); ?>> Show documentation publicly</label><br>
                            <label><input type="checkbox" name="kb_markdown_importer_settings[allow_svg]" value="1" <?php checked($settings['allow_svg'], '1'); ?>> Allow SVG image import</label>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="cron_interval">Automatic Sync</label></th>
                        <td>
                            <select id="cron_interval" name="kb_markdown_importer_settings[cron_interval]">
                                <option value="disabled" <?php selected($settings['cron_interval'], 'disabled'); ?>>Disabled</option>
                                <option value="hourly" <?php selected($settings['cron_interval'], 'hourly'); ?>>Hourly</option>
                                <option value="daily" <?php selected($settings['cron_interval'], 'daily'); ?>>Daily</option>
                                <option value="weekly" <?php selected($settings['cron_interval'], 'weekly'); ?>>Weekly</option>
                            </select>
                        </td>
                    </tr>
                </table>
                <h2><?php esc_html_e('Dokumentations-Startseite', 'kb-markdown-importer'); ?></h2>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><label for="docs_home_intro_title"><?php esc_html_e('Anleitungs-Titel', 'kb-markdown-importer'); ?></label></th>
                        <td><input class="regular-text" id="docs_home_intro_title" name="kb_markdown_importer_settings[docs_home_intro_title]" type="text" value="<?php echo esc_attr($settings['docs_home_intro_title']); ?>"></td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="docs_home_intro_content"><?php esc_html_e('Anleitungstext', 'kb-markdown-importer'); ?></label></th>
                        <td>
                            <?php
                            wp_editor((string) $settings['docs_home_intro_content'], 'docs_home_intro_content', [
                                'textarea_name' => 'kb_markdown_importer_settings[docs_home_intro_content]',
                                'textarea_rows' => 7,
                                'media_buttons' => false,
                                'teeny' => true,
                            ]);
                            ?>
                            <p class="description"><?php esc_html_e('Dieser Text erscheint oben auf der Dokumentations-Startseite.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="product_updates_source"><?php esc_html_e('Update-Quelle', 'kb-markdown-importer'); ?></label></th>
                        <td>
                            <select id="product_updates_source" name="kb_markdown_importer_settings[product_updates_source]">
                                <option value="rss" <?php selected($settings['product_updates_source'], 'rss'); ?>><?php esc_html_e('RSS/XML', 'kb-markdown-importer'); ?></option>
                                <option value="rest" <?php selected($settings['product_updates_source'], 'rest'); ?>><?php esc_html_e('REST/JSON', 'kb-markdown-importer'); ?></option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="product_updates_feed_url"><?php esc_html_e('RSS/XML-Feed URL', 'kb-markdown-importer'); ?></label></th>
                        <td>
                            <input class="regular-text" id="product_updates_feed_url" name="kb_markdown_importer_settings[product_updates_feed_url]" type="url" value="<?php echo esc_attr($settings['product_updates_feed_url']); ?>" placeholder="https://example.com/updates.xml">
                            <p class="description"><?php esc_html_e('RSS- oder XML-Feed mit den neuesten Produktupdates. Wird nur genutzt, wenn RSS/XML als Quelle ausgewählt ist.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="product_updates_rest_url"><?php esc_html_e('REST/JSON URL', 'kb-markdown-importer'); ?></label></th>
                        <td>
                            <input class="regular-text" id="product_updates_rest_url" name="kb_markdown_importer_settings[product_updates_rest_url]" type="url" value="<?php echo esc_attr($settings['product_updates_rest_url']); ?>" placeholder="https://example.com/api/product-versions">
                            <p class="description"><?php esc_html_e('REST-Endpunkt mit JSON-Antwort. Wird nur genutzt, wenn REST/JSON als Quelle ausgewählt ist.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="product_updates_feed_limit"><?php esc_html_e('Anzahl Updates', 'kb-markdown-importer'); ?></label></th>
                        <td><input id="product_updates_feed_limit" name="kb_markdown_importer_settings[product_updates_feed_limit]" type="number" min="1" max="20" value="<?php echo esc_attr($settings['product_updates_feed_limit']); ?>"></td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="product_updates_feed_item_path"><?php esc_html_e('Eintrag-Pfad', 'kb-markdown-importer'); ?></label></th>
                        <td>
                            <input class="regular-text" id="product_updates_feed_item_path" name="kb_markdown_importer_settings[product_updates_feed_item_path]" type="text" value="<?php echo esc_attr($settings['product_updates_feed_item_path']); ?>" placeholder="channel/item">
                            <p class="description"><?php esc_html_e('Pfad zum wiederholten Feed-Eintrag, zum Beispiel channel/item.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="product_updates_rest_list_path"><?php esc_html_e('REST Listenpfad', 'kb-markdown-importer'); ?></label></th>
                        <td>
                            <input class="regular-text" id="product_updates_rest_list_path" name="kb_markdown_importer_settings[product_updates_rest_list_path]" type="text" value="<?php echo esc_attr($settings['product_updates_rest_list_path']); ?>" placeholder="content,data,items">
                            <p class="description"><?php esc_html_e('Pfad zur Liste in der JSON-Antwort. Mehrere Alternativen mit Komma trennen. Leer lassen, wenn die Antwort direkt ein Array ist.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php esc_html_e('XML-Felder', 'kb-markdown-importer'); ?></th>
                        <td>
                            <fieldset class="kb-feed-fields">
                                <p>
                                    <label for="product_updates_feed_product_field"><?php esc_html_e('Produktname', 'kb-markdown-importer'); ?></label><br>
                                    <input class="regular-text" id="product_updates_feed_product_field" name="kb_markdown_importer_settings[product_updates_feed_product_field]" type="text" value="<?php echo esc_attr($settings['product_updates_feed_product_field']); ?>" placeholder="title">
                                </p>
                                <p>
                                    <label for="product_updates_feed_version_field"><?php esc_html_e('Version', 'kb-markdown-importer'); ?></label><br>
                                    <input class="regular-text" id="product_updates_feed_version_field" name="kb_markdown_importer_settings[product_updates_feed_version_field]" type="text" value="<?php echo esc_attr($settings['product_updates_feed_version_field']); ?>" placeholder="category">
                                </p>
                                <p>
                                    <label for="product_updates_feed_date_field"><?php esc_html_e('Datum', 'kb-markdown-importer'); ?></label><br>
                                    <input class="regular-text" id="product_updates_feed_date_field" name="kb_markdown_importer_settings[product_updates_feed_date_field]" type="text" value="<?php echo esc_attr($settings['product_updates_feed_date_field']); ?>" placeholder="pubDate">
                                </p>
                                <p>
                                    <label for="product_updates_feed_changelog_field"><?php esc_html_e('Changelog', 'kb-markdown-importer'); ?></label><br>
                                    <input class="regular-text" id="product_updates_feed_changelog_field" name="kb_markdown_importer_settings[product_updates_feed_changelog_field]" type="text" value="<?php echo esc_attr($settings['product_updates_feed_changelog_field']); ?>" placeholder="description">
                                </p>
                            </fieldset>
                            <p class="description"><?php esc_html_e('Feldpfade relativ zum Eintrag, zum Beispiel product/name, version oder changelog. Namespaces wie dc:date werden unterstützt.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><?php esc_html_e('REST-Felder', 'kb-markdown-importer'); ?></th>
                        <td>
                            <fieldset class="kb-rest-fields">
                                <p>
                                    <label for="product_updates_rest_product_field"><?php esc_html_e('Produktname', 'kb-markdown-importer'); ?></label><br>
                                    <input class="regular-text" id="product_updates_rest_product_field" name="kb_markdown_importer_settings[product_updates_rest_product_field]" type="text" value="<?php echo esc_attr($settings['product_updates_rest_product_field']); ?>" placeholder="product.name,productName,name">
                                </p>
                                <p>
                                    <label for="product_updates_rest_version_field"><?php esc_html_e('Version', 'kb-markdown-importer'); ?></label><br>
                                    <input class="regular-text" id="product_updates_rest_version_field" name="kb_markdown_importer_settings[product_updates_rest_version_field]" type="text" value="<?php echo esc_attr($settings['product_updates_rest_version_field']); ?>" placeholder="version,versionName,name">
                                </p>
                                <p>
                                    <label for="product_updates_rest_date_field"><?php esc_html_e('Datum', 'kb-markdown-importer'); ?></label><br>
                                    <input class="regular-text" id="product_updates_rest_date_field" name="kb_markdown_importer_settings[product_updates_rest_date_field]" type="text" value="<?php echo esc_attr($settings['product_updates_rest_date_field']); ?>" placeholder="releaseDate,date,updatedAt,createdAt">
                                </p>
                                <p>
                                    <label for="product_updates_rest_changelog_field"><?php esc_html_e('Changelog', 'kb-markdown-importer'); ?></label><br>
                                    <input class="regular-text" id="product_updates_rest_changelog_field" name="kb_markdown_importer_settings[product_updates_rest_changelog_field]" type="text" value="<?php echo esc_attr($settings['product_updates_rest_changelog_field']); ?>" placeholder="changelog,changeLog,description,changes">
                                </p>
                            </fieldset>
                            <p class="description"><?php esc_html_e('JSON-Feldpfade relativ zu einem Eintrag. Verschachtelte Felder mit Punkt oder Slash angeben, Alternativen mit Komma trennen.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                </table>
                <h2><?php esc_html_e('Frontend Design', 'kb-markdown-importer'); ?></h2>
                <table class="form-table" role="presentation">
                    <tr>
                        <th scope="row"><label for="design_theme">Design Theme</label></th>
                        <td>
                            <select id="design_theme" name="kb_markdown_importer_settings[design_theme]">
                                <option value="obyte" <?php selected($settings['design_theme'], 'obyte'); ?>>o-byte</option>
                                <option value="inherit" <?php selected($settings['design_theme'], 'inherit'); ?>>Theme inherit / neutral</option>
                            </select>
                            <p class="description"><?php esc_html_e('The bundled o-byte theme is loaded by default. A custom theme.css is loaded after it and can override everything.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="design_primary_color">Primary Color</label></th>
                        <td><input id="design_primary_color" name="kb_markdown_importer_settings[design_primary_color]" type="color" value="<?php echo esc_attr($settings['design_primary_color']); ?>"></td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="design_accent_color">Accent Color</label></th>
                        <td><input id="design_accent_color" name="kb_markdown_importer_settings[design_accent_color]" type="color" value="<?php echo esc_attr($settings['design_accent_color']); ?>"></td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="design_radius">Border Radius</label></th>
                        <td>
                            <input id="design_radius" name="kb_markdown_importer_settings[design_radius]" type="number" min="0" max="32" value="<?php echo esc_attr($settings['design_radius']); ?>"> px
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="custom_theme_css_url">Custom theme.css</label></th>
                        <td>
                            <input class="regular-text" id="custom_theme_css_url" name="kb_markdown_importer_settings[custom_theme_css_url]" type="url" value="<?php echo esc_attr($settings['custom_theme_css_url']); ?>" placeholder="https://example.com/theme.css">
                            <button type="button" class="button" id="kb-markdown-upload-theme-css"><?php esc_html_e('Upload/select theme.css', 'kb-markdown-importer'); ?></button>
                            <p class="description"><?php esc_html_e('Upload a CSS file in the media library or paste a CSS URL. It is enqueued last, so it can override the bundled theme.', 'kb-markdown-importer'); ?></p>
                        </td>
                    </tr>
                </table>
                <?php submit_button(); ?>
            </form>
            <form method="post">
                <?php wp_nonce_field('kb_markdown_test_connection'); ?>
                <?php submit_button(__('Test GitLab Connection', 'kb-markdown-importer'), 'secondary', 'kb_markdown_test_connection'); ?>
            </form>
            <form method="post">
                <?php wp_nonce_field('kb_markdown_test_product_updates'); ?>
                <?php submit_button(__('Produktupdate-Quelle testen', 'kb-markdown-importer'), 'secondary', 'kb_markdown_test_product_updates'); ?>
                <p class="description"><?php esc_html_e('Der Test nutzt die gespeicherten Einstellungen der ausgewählten Update-Quelle. Bitte Änderungen vorher speichern.', 'kb-markdown-importer'); ?></p>
            </form>
            <?php if (is_array($updatesTest)) : ?>
                <div class="notice notice-<?php echo $updatesTest['ok'] ? 'success' : 'error'; ?>">
                    <p><strong><?php echo esc_html($updatesTest['title']); ?></strong></p>
                    <p><?php echo esc_html($updatesTest['message']); ?></p>
                </div>
                <?php if ('' !== $updatesTest['body']) : ?>
                    <h2><?php esc_html_e('Antwort der Produktupdate-Quelle', 'kb-markdown-importer'); ?></h2>
                    <textarea class="large-text code" rows="16" readonly><?php echo esc_textarea($updatesTest['body']); ?></textarea>
                <?php endif; ?>
            <?php endif; ?>
        </div>
        <?php
    }

    private static function handleConnectionTest(): void
    {
        $client = new GitLabClient(Plugin::settings());
        $result = $client->getGroup(Plugin::settings()['gitlab_group']);

        if (is_wp_error($result)) {
            $message = self::formatConnectionError($result);
            ImportLogger::error('GitLab connection failed: ' . $message);
            add_settings_error('kb_markdown_importer', 'connection_failed', esc_html($message), 'error');
            settings_errors('kb_markdown_importer');
            return;
        }

        ImportLogger::info('GitLab connection successful.');
        add_settings_error('kb_markdown_importer', 'connection_ok', esc_html__('GitLab connection successful.', 'kb-markdown-importer'), 'success');
        settings_errors('kb_markdown_importer');
    }

    private static function handleProductUpdatesTest(): array
    {
        $settings = Plugin::settings();
        $source = (string) ($settings['product_updates_source'] ?? 'rss');
        $url = esc_url_raw((string) ('rest' === $source ? ($settings['product_updates_rest_url'] ?? '') : ($settings['product_updates_feed_url'] ?? '')));

        if ('' === $url) {
            return [
                'ok' => false,
                'title' => __('Keine Produktupdate-Quelle konfiguriert.', 'kb-markdown-importer'),
                'message' => __('Bitte zuerst eine RSS/XML- oder REST/JSON-URL speichern.', 'kb-markdown-importer'),
                'body' => '',
            ];
        }

        $response = wp_remote_get($url, [
            'timeout' => 12,
            'redirection' => 3,
            'user-agent' => 'KB Markdown Importer/' . KB_MARKDOWN_IMPORTER_VERSION,
        ]);

        if (is_wp_error($response)) {
            return [
                'ok' => false,
                'title' => __('Produktupdate-Quelle nicht erreichbar.', 'kb-markdown-importer'),
                'message' => $response->get_error_message(),
                'body' => '',
            ];
        }

        $status = (int) wp_remote_retrieve_response_code($response);
        $contentType = (string) wp_remote_retrieve_header($response, 'content-type');
        $body = (string) wp_remote_retrieve_body($response);
        $excerpt = substr($body, 0, 12000);
        $validPayload = true;
        $payloadNote = '';

        if ('rest' === $source) {
            json_decode($body, true);
            $validPayload = JSON_ERROR_NONE === json_last_error();
            if (! $validPayload) {
                $payloadNote = ' ' . sprintf(
                    /* translators: %s: JSON parser error message. */
                    __('Die Antwort ist kein gültiges JSON: %s', 'kb-markdown-importer'),
                    json_last_error_msg()
                );
            }
        }

        $message = sprintf(
            /* translators: 1: source type, 2: HTTP status code, 3: content type. */
            __('Quelle: %1$s | HTTP-Status: %2$d | Content-Type: %3$s', 'kb-markdown-importer'),
            'rest' === $source ? 'REST/JSON' : 'RSS/XML',
            $status,
            $contentType ?: '-'
        );
        $message .= $payloadNote;

        if (strlen($body) > strlen($excerpt)) {
            $message .= ' ' . __('Die Antwort wurde auf 12000 Zeichen gekürzt.', 'kb-markdown-importer');
        }

        $ok = $status >= 200 && $status < 300 && $validPayload;

        return [
            'ok' => $ok,
            'title' => $ok ? __('Produktupdate-Quelle erreichbar.', 'kb-markdown-importer') : __('Produktupdate-Quelle nicht nutzbar.', 'kb-markdown-importer'),
            'message' => $message,
            'body' => $excerpt,
        ];
    }

    private static function formatConnectionError(\WP_Error $error): string
    {
        $message = $error->get_error_message();
        $data = $error->get_error_data();

        if (! is_array($data)) {
            return $message;
        }

        if (! empty($data['url'])) {
            $message .= ' Target: ' . $data['url'];
        }

        if (! empty($data['retry_after'])) {
            $message .= ' Retry-After: ' . $data['retry_after'];
        }

        if (! empty($data['response_excerpt'])) {
            $message .= ' Response: ' . $data['response_excerpt'];
        }

        return $message;
    }

    private static function sanitizeHexColor(string $value, string $fallback): string
    {
        $value = trim($value);

        return preg_match('/^#[0-9a-fA-F]{6}$/', $value) ? strtoupper($value) : $fallback;
    }

    private static function sanitizeXmlPath(string $value, string $fallback): string
    {
        $value = trim($value);
        $value = preg_replace('/[^A-Za-z0-9_:@.\/-]/', '', $value) ?: '';

        return '' !== $value ? $value : $fallback;
    }

    private static function sanitizePathList(string $value, string $fallback): string
    {
        $value = trim($value);
        $value = preg_replace('/[^A-Za-z0-9_:@.\/,-]/', '', $value) ?: '';

        return '' !== $value ? $value : $fallback;
    }
}
