<?php
/**
 * Options Page Builder — REST API integration.
 *
 * Access model:
 * - List pages / field metadata: page capability (never below edit_posts for weak caps).
 * - Raw stored values: manage_options (or filtered raw capability).
 * - Secrets: never returned as plaintext; only { configured: true|false }.
 *
 * @package OptionsPageBuilder
 */

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

add_action( 'rest_api_init', 'wpps_opb_register_rest_routes' );

function wpps_opb_register_rest_routes(): void {
	register_rest_route(
		'wp-powersuite/v1',
		'/opb/pages',
		[
			'methods'             => 'GET',
			'callback'            => 'wpps_opb_rest_list_pages',
			'permission_callback' => static function (): bool {
				return is_user_logged_in() && current_user_can( 'edit_posts' );
			},
		]
	);

	register_rest_route(
		'wp-powersuite/v1',
		'/opb/(?P<page>[a-z0-9_-]+)',
		[
			'methods'             => 'GET',
			'callback'            => 'wpps_opb_rest_get_page_values',
			'permission_callback' => 'wpps_opb_rest_can_read_raw_values_request',
			'args'                => [
				'page' => [
					'required'          => true,
					'sanitize_callback' => 'sanitize_key',
				],
			],
		]
	);

	register_rest_route(
		'wp-powersuite/v1',
		'/opb/(?P<page>[a-z0-9_-]+)/(?P<field>[a-z0-9_-]+)',
		[
			'methods'             => 'GET',
			'callback'            => 'wpps_opb_rest_get_field_value',
			'permission_callback' => 'wpps_opb_rest_can_read_field_request',
			'args'                => [
				'page' => [
					'required'          => true,
					'sanitize_callback' => 'sanitize_key',
				],
				'field' => [
					'required'          => true,
					'sanitize_callback' => 'sanitize_key',
				],
				'format' => [
					'required'          => false,
					'default'           => 'display',
					'sanitize_callback' => 'sanitize_key',
				],
			],
		]
	);
}

function wpps_opb_rest_can_read_raw_values_request( \WP_REST_Request $request ): bool {
	$page_slug = sanitize_key( (string) $request->get_param( 'page' ) );
	if ( $page_slug === '' || ! wpps_opb_page_exists( $page_slug ) ) {
		return false;
	}

	return wpps_opb_user_can_read_raw_values( $page_slug );
}

function wpps_opb_rest_can_read_field_request( \WP_REST_Request $request ): bool {
	$page_slug = sanitize_key( (string) $request->get_param( 'page' ) );
	$format    = sanitize_key( (string) ( $request->get_param( 'format' ) ?? 'display' ) );

	if ( $page_slug === '' || ! wpps_opb_page_exists( $page_slug ) || ! wpps_opb_user_can_manage_page( $page_slug ) ) {
		return false;
	}

	// Raw format requires the raw-values capability.
	if ( $format === 'raw' ) {
		return wpps_opb_user_can_read_raw_values( $page_slug );
	}

	return true;
}

function wpps_opb_rest_list_pages( \WP_REST_Request $request ): \WP_REST_Response {
	unset( $request );

	$pages = get_option( 'wp_powersuite_opb_pages', [] );
	$pages = is_array( $pages ) ? $pages : [];
	$out   = [];

	foreach ( $pages as $page ) {
		if ( ! is_array( $page ) || empty( $page['slug'] ) ) {
			continue;
		}

		$slug = sanitize_key( (string) $page['slug'] );
		if ( $slug === '' || ! wpps_opb_user_can_manage_page( $slug ) ) {
			continue;
		}

		$fields = [];
		foreach ( $page['fields'] ?? [] as $field ) {
			if ( ! is_array( $field ) || in_array( $field['type'] ?? '', [ 'group', 'message' ], true ) ) {
				continue;
			}
			$field_id = sanitize_key( (string) ( $field['field_id'] ?? $field['id'] ?? '' ) );
			if ( $field_id === '' ) {
				continue;
			}
			$fields[] = [
				'id'        => $field_id,
				'label'     => (string) ( $field['label'] ?? $field_id ),
				'type'      => sanitize_key( (string) ( $field['type'] ?? 'text' ) ),
				'is_secret' => function_exists( 'wpps_opb_field_is_secret' ) && wpps_opb_field_is_secret( $field ),
			];
		}

		$out[] = [
			'slug'       => $slug,
			'title'      => (string) ( $page['page_title'] ?? $page['menu_title'] ?? $slug ),
			'capability' => sanitize_key( (string) ( $page['capability'] ?? 'manage_options' ) ),
			'fields'     => $fields,
		];
	}

	return new \WP_REST_Response( [ 'pages' => $out ] );
}

function wpps_opb_rest_get_page_values( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error {
	$page_slug = sanitize_key( (string) $request->get_param( 'page' ) );
	if ( $page_slug === '' || ! wpps_opb_page_exists( $page_slug ) ) {
		return new \WP_Error( 'wpps_opb_invalid_page', __( 'Invalid page slug.', 'wp-powersuite' ), [ 'status' => 404 ] );
	}

	if ( ! wpps_opb_user_can_read_raw_values( $page_slug ) ) {
		return new \WP_Error( 'wpps_opb_forbidden', __( 'You are not allowed to retrieve raw option values.', 'wp-powersuite' ), [ 'status' => 403 ] );
	}

	$values = wpps_opb_mask_secret_values( $page_slug, wpps_opb_get_all( $page_slug ) );

	return new \WP_REST_Response(
		[
			'page'   => $page_slug,
			'values' => $values,
		]
	);
}

function wpps_opb_rest_get_field_value( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error {
	$page_slug = sanitize_key( (string) $request->get_param( 'page' ) );
	$field_id  = sanitize_key( (string) $request->get_param( 'field' ) );
	$format    = sanitize_key( (string) ( $request->get_param( 'format' ) ?? 'display' ) );

	if ( $page_slug === '' || $field_id === '' || ! wpps_opb_page_exists( $page_slug ) ) {
		return new \WP_Error( 'wpps_opb_invalid_field', __( 'Invalid page or field.', 'wp-powersuite' ), [ 'status' => 400 ] );
	}

	if ( ! wpps_opb_user_can_manage_page( $page_slug ) ) {
		return new \WP_Error( 'wpps_opb_forbidden', __( 'You are not allowed to access this page.', 'wp-powersuite' ), [ 'status' => 403 ] );
	}

	$field = wpps_opb_get_field_definition( $page_slug, $field_id );
	if ( $field === null ) {
		return new \WP_Error( 'wpps_opb_field_not_found', __( 'Field not found.', 'wp-powersuite' ), [ 'status' => 404 ] );
	}

	$is_secret = function_exists( 'wpps_opb_field_is_secret' ) && wpps_opb_field_is_secret( $field );
	$raw       = wpps_opb_get( $page_slug, $field_id, '' );
	$display   = wpps_opb_get_display( $page_slug, $field_id, '' );

	$response = [
		'page'      => $page_slug,
		'field'     => $field_id,
		'type'      => sanitize_key( (string) ( $field['type'] ?? 'text' ) ),
		'is_secret' => $is_secret,
	];

	if ( $is_secret ) {
		$response['configured'] = $raw !== '' && $raw !== null;
		$response['raw']        = null;
		$response['display']    = '';
		$response['output']     = '';

		return new \WP_REST_Response( $response );
	}

	if ( $format === 'raw' && ! wpps_opb_user_can_read_raw_values( $page_slug ) ) {
		return new \WP_Error( 'wpps_opb_forbidden', __( 'You are not allowed to retrieve raw option values.', 'wp-powersuite' ), [ 'status' => 403 ] );
	}

	$response['raw']     = ( $format === 'raw' || wpps_opb_user_can_read_raw_values( $page_slug ) ) ? $raw : null;
	$response['display'] = $display;
	$response['output']  = wpps_opb_render_field_output( $page_slug, $field_id, [ 'format' => $format === 'raw' ? 'display' : $format ] );

	return new \WP_REST_Response( $response );
}
