<?php
/** Read abilities for native WordPress Global Style Variations. */

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

function wpagent_gs_variation_summary_schema(): array {
	return array(
		'type'       => 'object',
		'properties' => array(
			'variation_id'      => wpagent_gs_hash_schema(),
			'title'             => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 200 ),
			'description'       => array( 'type' => 'string', 'maxLength' => 1000 ),
			'scope'             => array( 'type' => 'string', 'enum' => array( 'full', 'color', 'typography' ) ),
			'bytes'             => array( 'type' => 'integer', 'minimum' => 2, 'maximum' => WPAGENT_GLOBAL_STYLES_MAX_BYTES ),
			'settings_sections' => array( 'type' => 'array', 'maxItems' => WPAGENT_GLOBAL_STYLES_MAX_PRESETS, 'items' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 64 ) ),
			'style_sections'    => array( 'type' => 'array', 'maxItems' => WPAGENT_GLOBAL_STYLES_MAX_PRESETS, 'items' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 64 ) ),
			'has_custom_css'    => array( 'type' => 'boolean' ),
		),
		'required'             => array( 'variation_id', 'title', 'description', 'scope', 'bytes', 'settings_sections', 'style_sections', 'has_custom_css' ),
		'additionalProperties' => false,
		'maxProperties'        => 8,
	);
}

function wpagent_ability_list_global_style_variations(): array {
	return array(
		'label'               => __( 'Native Stilvarianten auflisten', 'wp-agent-companion' ),
		'description'         => __( 'Listet die native Standardauswahl und die vom aktiven Theme gelieferten vollständigen, Farb- und Typografievarianten mit stabilen, Theme-gebundenen IDs.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'       => 'object',
			'properties' => array(
				'scope' => array( 'type' => 'string', 'enum' => array( 'all', 'full', 'color', 'typography' ), 'default' => 'all' ),
			),
			'additionalProperties' => false,
			'maxProperties'        => 1,
		),
		'output_schema'       => array(
			'type'       => 'object',
			'properties' => array(
				'theme'      => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 200 ),
				'block_theme' => array( 'type' => 'boolean' ),
				'state_hash' => wpagent_gs_hash_schema(),
				'count'      => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => WPAGENT_GLOBAL_STYLE_VARIATIONS_MAX_ITEMS + 1 ),
				'items'      => array( 'type' => 'array', 'maxItems' => WPAGENT_GLOBAL_STYLE_VARIATIONS_MAX_ITEMS + 1, 'items' => wpagent_gs_variation_summary_schema() ),
			),
			'required'             => array( 'theme', 'block_theme', 'state_hash', 'count', 'items' ),
			'additionalProperties' => false,
			'maxProperties'        => 5,
		),
		'execute_callback'    => 'wpagent_exec_list_global_style_variations',
		'permission_callback' => 'wpagent_perm_edit_theme_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_list_global_style_variations( $input ) {
	$input = wpagent_gs_validate_variation_list_input( $input );
	if ( is_wp_error( $input ) ) {
		return $input;
	}
	$scope = $input['scope'] ?? 'all';
	$state = wpagent_gs_state();
	if ( is_wp_error( $state ) ) {
		return $state;
	}
	$catalog = wpagent_gs_variation_catalog();
	if ( is_wp_error( $catalog ) ) {
		return $catalog;
	}
	if ( (string) $state['theme'] !== (string) get_stylesheet() ) {
		return new WP_Error( 'wpagent_gs_variation_theme_changed', __( 'Das aktive Theme wurde während des Lesens gewechselt. Lies die Stilvarianten erneut.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$items = array();
	foreach ( $catalog as $record ) {
		if ( 'all' !== $scope && $scope !== $record['scope'] ) {
			continue;
		}
		unset( $record['variation'], $record['document'] );
		$items[] = $record;
	}
	return array(
		'theme'       => (string) $state['theme'],
		'block_theme' => function_exists( 'wp_is_block_theme' ) && wp_is_block_theme(),
		'state_hash'  => (string) $state['state_hash'],
		'count'       => count( $items ),
		'items'       => $items,
	);
}

function wpagent_ability_get_global_style_variation(): array {
	return array(
		'label'               => __( 'Native Stilvariante lesen', 'wp-agent-companion' ),
		'description'         => __( 'Liest eine einzelne Theme-Stilvariante vollständig und typgetreu, bevor sie angewandt wird.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'       => 'object',
			'properties' => array( 'variation_id' => wpagent_gs_hash_schema() ),
			'required'   => array( 'variation_id' ),
			'additionalProperties' => false,
			'maxProperties'        => 1,
		),
		'output_schema'       => array(
			'type'       => 'object',
			'properties' => array(
				'theme'        => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 200 ),
				'variation_id' => wpagent_gs_hash_schema(),
				'title'        => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 200 ),
				'description'  => array( 'type' => 'string', 'maxLength' => 1000 ),
				'scope'        => array( 'type' => 'string', 'enum' => array( 'full', 'color', 'typography' ) ),
				'bytes'        => array( 'type' => 'integer', 'minimum' => 2, 'maximum' => WPAGENT_GLOBAL_STYLES_MAX_BYTES ),
				'variation'    => wpagent_gs_json_document_schema(),
			),
			'required'             => array( 'theme', 'variation_id', 'title', 'description', 'scope', 'bytes', 'variation' ),
			'additionalProperties' => false,
			'maxProperties'        => 7,
		),
		'execute_callback'    => 'wpagent_exec_get_global_style_variation',
		'permission_callback' => 'wpagent_perm_edit_theme_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_global_style_variation( $input ) {
	$input = wpagent_gs_validate_variation_get_input( $input );
	if ( is_wp_error( $input ) ) {
		return $input;
	}
	$record = wpagent_gs_find_variation( $input['variation_id'] ?? '' );
	if ( is_wp_error( $record ) ) {
		return $record;
	}
	return array(
		'theme'        => (string) get_stylesheet(),
		'variation_id' => $record['variation_id'],
		'title'        => $record['title'],
		'description'  => $record['description'],
		'scope'        => $record['scope'],
		'bytes'        => $record['bytes'],
		'variation'    => $record['document'],
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_gs_validate_variation_list_input( $input ) {
	if ( ! is_array( $input ) || ( array() !== $input && array_is_list( $input ) ) || array_diff( array_keys( $input ), array( 'scope' ) ) ) {
		return new WP_Error( 'wpagent_gs_variation_input', __( 'Die Stilvarianten-Eingabe enthält unbekannte oder ungültige Felder.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( array_key_exists( 'scope', $input ) && ( ! is_string( $input['scope'] ) || ! in_array( $input['scope'], array( 'all', 'full', 'color', 'typography' ), true ) ) ) {
		return new WP_Error( 'wpagent_gs_variation_scope', __( 'scope muss all, full, color oder typography sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	return $input;
}

/** @return array<string,mixed>|WP_Error */
function wpagent_gs_validate_variation_get_input( $input ) {
	if ( ! is_array( $input ) || array_is_list( $input ) || array_diff( array_keys( $input ), array( 'variation_id' ) ) || ! array_key_exists( 'variation_id', $input ) ) {
		return new WP_Error( 'wpagent_gs_variation_input', __( 'Die Stilvarianten-Eingabe enthält unbekannte oder ungültige Felder.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$variation_id = is_string( $input['variation_id'] ) ? strtolower( $input['variation_id'] ) : '';
	if ( ! preg_match( '/^[a-f0-9]{64}$/', $variation_id ) ) {
		return new WP_Error( 'wpagent_gs_variation_id', __( 'variation_id muss eine vollständige Stilvarianten-ID sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$input['variation_id'] = $variation_id;
	return $input;
}
