<?php
/**
 * Recursive sanitization for decoded import payloads.
 *
 * json_decode() does not sanitize; this walks the decoded structure and
 * cleans every scalar before the data is persisted (transient, post,
 * meta) or echoed back in a preview response.
 *
 * @package SlideMind\Core
 * @since   1.0.0
 */

namespace SlideMind\Core;

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

class ImportSanitizer {

    /**
     * Keys whose values may legitimately contain limited HTML.
     */
    private const RICH_TEXT_KEYS = [
        'content',
        'context',
        'objectives',
        'description',
        'system_prompt',
        'opening_message',
        'closing_message',
    ];

    private const ALLOWED_STATUSES = ['publish', 'draft', 'pending', 'private'];

    /**
     * Recursively sanitize a decoded import array.
     *
     * Numeric/bool/null scalars pass through; strings are cleaned according
     * to their key: `status` is whitelisted, rich-text keys go through
     * wp_kses_post(), everything else through sanitize_textarea_field()
     * (preserves newlines, strips tags and control characters).
     *
     * @param array $data Decoded payload.
     * @return array
     */
    public static function sanitize(array $data): array {
        $out = [];
        foreach ($data as $key => $value) {
            $clean_key = is_string($key) ? sanitize_text_field($key) : $key;
            if (is_array($value)) {
                $out[$clean_key] = self::sanitize($value);
                continue;
            }
            if (!is_string($value)) {
                $out[$clean_key] = $value;
                continue;
            }
            if ($clean_key === 'status') {
                $out[$clean_key] = in_array($value, self::ALLOWED_STATUSES, true) ? $value : 'draft';
            } elseif (in_array($clean_key, self::RICH_TEXT_KEYS, true)) {
                $out[$clean_key] = wp_kses_post($value);
            } else {
                $out[$clean_key] = sanitize_textarea_field($value);
            }
        }
        return $out;
    }
}
