<?php
/**
 * Settings REST controller — GET / POST /blocksify/v1/settings.
 *
 * Extends `PressMaximum\DashboardKit\REST\SettingsControllerBase` to
 * inherit `register_routes()` + `permission_check()` + `get_item()` +
 * `update_item()` boilerplate. The Blocksify-specific bits — option
 * name, defaults, and the consumer-owned schema sanitize + saved-action
 * lifecycle — flow through the overrides below.
 *
 * SPEC §5.4 endpoint contract:
 *   GET  → merged saved + defaults (sanitized on read so legacy invalid
 *          values never reach the client).
 *   POST → sanitize against schema, persist, return final shape. Empty
 *          body resets to defaults (JS reset flow per SPEC §8.2.3).
 *
 * @package Blocksify
 */

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

/**
 * REST controller for the settings option store. Delegates the merged-
 * read + sanitized-write lifecycle to `Blocksify_Dashboard_Schema` so
 * the `blocksify_dashboard_settings_saved` action + the
 * `blocksify_dashboard_settings_sanitized` filter fire on every save.
 */
class Blocksify_Dashboard_Settings_Controller extends \PressMaximum\DashboardKit\REST\SettingsControllerBase {

	/**
	 * @return string
	 */
	protected function getNamespace(): string {
		return 'blocksify/v1';
	}

	/**
	 * @return string
	 */
	protected function getRestBase(): string {
		return 'settings';
	}

	/**
	 * Capability gate. Wraps the filterable dashboard capability so role
	 * plugins / multisite super-admins can override globally. SPEC §13.4.
	 *
	 * @return string
	 */
	protected function getCapability(): string {
		return Blocksify_Dashboard::get_capability();
	}

	/**
	 * @return string
	 */
	protected function getOptionName(): string {
		return Blocksify_Dashboard_Schema::OPTION_NAME;
	}

	/**
	 * @return array<string, mixed>
	 */
	protected function getDefaults(): array {
		return Blocksify_Dashboard_Schema::defaults();
	}

	/**
	 * Override kit's `readMerged()` to delegate to the schema's
	 * `get_settings()` — its deep-merge + re-sanitize pass is richer
	 * than the kit base (handles per-key fallback against `defaults()`
	 * + applies the `blocksify_dashboard_settings_sanitized` filter on
	 * the result).
	 *
	 * @return array<string, mixed>
	 */
	protected function readMerged(): array {
		return Blocksify_Dashboard_Schema::get_settings();
	}

	/**
	 * Override kit's `writeMerged()` so the consumer's saved-action
	 * + sanitize-filter contract stays intact (kit's base sanitizes +
	 * saves but doesn't fire the action).
	 *
	 * @param array<string, mixed> $incoming Raw body.
	 * @return array<string, mixed>          Sanitized + saved shape.
	 */
	protected function writeMerged( array $incoming ): array {
		return Blocksify_Dashboard_Schema::update_settings( $incoming );
	}
}
