<?php
/**
 * Registers the cached AI summary and FAQ post meta fields.
 *
 * @package Priizmo_Engine
 */

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

/**
 * Class Priizmo_Engine_Post_Meta
 *
 * Registers the `_priizmo_cached_summary` and `_priizmo_cached_faq_data` post meta
 * fields so they are available to the block editor (via the REST API) and
 * can be read/written safely elsewhere in the plugin.
 */
class Priizmo_Engine_Post_Meta {

	/**
	 * Meta key used to cache the generated AI summary.
	 *
	 * @var string
	 */
	const META_KEY = '_priizmo_cached_summary';

	/**
	 * Meta key used to cache the generated FAQ data (JSON-encoded array of
	 * {question, answer} objects).
	 *
	 * @var string
	 */
	const FAQ_META_KEY = '_priizmo_cached_faq_data';

	/**
	 * Constructor. Hooks meta registration.
	 */
	public function __construct() {
		add_action( 'init', array( $this, 'register_meta' ) );
	}

	/**
	 * Registers the cached summary and FAQ meta fields for all public post types.
	 */
	public function register_meta() {
		register_post_meta(
			'',
			self::META_KEY,
			array(
				'type'              => 'string',
				'single'            => true,
				'default'           => '',
				'show_in_rest'      => true,
				'sanitize_callback' => 'sanitize_textarea_field',
				'auth_callback'     => array( $this, 'can_edit_post' ),
			)
		);

		register_post_meta(
			'',
			self::FAQ_META_KEY,
			array(
				'type'              => 'string',
				'single'            => true,
				'default'           => '',
				'show_in_rest'      => true,
				'sanitize_callback' => array( __CLASS__, 'sanitize_faq_json' ),
				'auth_callback'     => array( $this, 'can_edit_post' ),
			)
		);
	}

	/**
	 * Auth callback shared by both registered meta fields.
	 *
	 * @param bool   $allowed  Whether the meta is currently allowed.
	 * @param string $meta_key Meta key being checked.
	 * @param int    $post_id  Post ID.
	 *
	 * @return bool
	 */
	public function can_edit_post( $allowed, $meta_key, $post_id ) {
		return current_user_can( 'edit_post', $post_id );
	}

	/**
	 * Validates and re-encodes FAQ JSON before it is persisted, ensuring only
	 * a clean array of {question, answer} string pairs is ever stored.
	 *
	 * @param string $value Raw JSON string.
	 *
	 * @return string Sanitized JSON string (a JSON-encoded array; "[]" if invalid).
	 */
	public static function sanitize_faq_json( $value ) {
		$decoded = json_decode( (string) $value, true );

		return wp_json_encode( self::normalize_faq_items( $decoded ) );
	}

	/**
	 * Validates a decoded FAQ payload and reduces it to a clean array of
	 * {question, answer} string pairs, discarding anything malformed.
	 *
	 * @param mixed $items Decoded JSON value (expected to be an array).
	 *
	 * @return array<int, array{question: string, answer: string}>
	 */
	public static function normalize_faq_items( $items ) {
		if ( ! is_array( $items ) ) {
			return array();
		}

		$normalized = array();

		foreach ( $items as $item ) {
			if ( ! is_array( $item ) || empty( $item['question'] ) || empty( $item['answer'] ) ) {
				continue;
			}

			$question = sanitize_text_field( (string) $item['question'] );
			$answer   = sanitize_textarea_field( (string) $item['answer'] );

			if ( '' === $question || '' === $answer ) {
				continue;
			}

			$normalized[] = array(
				'question' => $question,
				'answer'   => $answer,
			);
		}

		return $normalized;
	}

	/**
	 * Reads and decodes the cached FAQ data for a post.
	 *
	 * @param int $post_id Post ID.
	 *
	 * @return array Array of associative arrays with 'question' and 'answer' keys.
	 */
	public static function get_faq_items( $post_id ) {
		$raw = get_post_meta( $post_id, self::FAQ_META_KEY, true );

		if ( empty( $raw ) ) {
			return array();
		}

		$decoded = json_decode( $raw, true );

		return is_array( $decoded ) ? $decoded : array();
	}
}
