<?php
/** Verified write abilities for WooCommerce global product attributes. */

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

function wpagent_ability_upsert_product_attribute(): array {
	return array(
		'label'               => __( 'Globales Produktattribut anlegen oder aktualisieren', 'wp-agent-companion' ),
		'description'         => __( 'Schreibt ein WooCommerce-Produktattribut über die öffentliche API mit Sperre, Konfliktschutz und Read-back. Bei einem unklaren Providerergebnis wird niemals automatisch ein möglicherweise fremder Zustand überschrieben.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'attribute_id'       => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'name'               => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 200 ),
				'slug'               => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 31 ),
				'type'               => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 64 ),
				'order_by'           => array( 'type' => 'string', 'enum' => array( 'menu_order', 'name', 'name_num', 'id' ) ),
				'has_archives'       => array( 'type' => 'boolean' ),
			),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'attribute' => wpagent_wc_attribute_schema(),
				'created'   => array( 'type' => 'boolean' ),
				'verified'  => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'attribute', 'created', 'verified' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_upsert_product_attribute',
		'permission_callback' => 'wpagent_perm_wc_manage_product_terms',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ) ),
	);
}

/** @return WP_Error */
function wpagent_wc_attribute_recovery_required( int $attribute_id = 0 ) {
	wpagent_wc_refresh_attribute_cache();
	$current = $attribute_id > 0 ? wpagent_wc_attribute_record( $attribute_id ) : null;
	$hash    = $current ? wpagent_wc_attribute_payload( $current )['state_hash'] : null;
	return new WP_Error(
		'wpagent_wc_attribute_recovery_required',
		__( 'WooCommerce hat das Produktattribut nicht exakt bestätigt. WPAgently führt kein automatisches Rollback aus, weil dies einen zwischenzeitlich fremd geänderten Zustand überschreiben könnte. Lies das Attribut neu und prüfe es manuell.', 'wp-agent-companion' ),
		array(
			'status'             => 502,
			'recovery_required'  => true,
			'attribute_id'       => $attribute_id,
			'current_state_hash' => $hash,
		)
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_upsert_product_attribute( $input ) {
	$input     = is_array( $input ) ? $input : array();
	$available = wpagent_wc_require_attribute_runtime();
	if ( is_wp_error( $available ) ) {
		return $available;
	}
	$attribute_id = absint( $input['attribute_id'] ?? 0 );
	$creating     = 0 === $attribute_id;
	$lock         = wpagent_wc_attribute_acquire_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		$record   = $creating ? null : wpagent_wc_attribute_record( $attribute_id );
		$previous = $record ? wpagent_wc_attribute_payload( $record ) : null;
		if ( ! $creating && ! $previous ) {
			return new WP_Error( 'wpagent_wc_attribute_not_found', __( 'Globales WooCommerce-Produktattribut nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
		}
		if ( ! $creating ) {
			$expected_hash = strtolower( (string) ( $input['expected_state_hash'] ?? '' ) );
			if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_hash ) || ! hash_equals( $previous['state_hash'], $expected_hash ) ) {
				return new WP_Error( 'wpagent_wc_attribute_conflict', __( 'Das Produktattribut hat sich seit dem Lesen geändert. Lies es neu und wiederhole den Vorgang.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $previous['state_hash'] ) );
			}
		}
		$next = wpagent_wc_validate_attribute_fields( $input, $creating, $previous );
		if ( is_wp_error( $next ) ) {
			return $next;
		}
		try {
			$result = $creating ? wc_create_attribute( $next ) : wc_update_attribute( $attribute_id, $next );
		} catch ( Throwable $error ) {
			if ( $creating ) {
				$attribute_id = wpagent_wc_attribute_id_by_slug( $next['slug'] );
			}
			return wpagent_wc_attribute_recovery_required( $attribute_id );
		}
		if ( is_wp_error( $result ) ) {
			if ( $creating ) {
				$attribute_id = wpagent_wc_attribute_id_by_slug( $next['slug'] );
			}
			return wpagent_wc_attribute_recovery_required( $attribute_id );
		}
		$attribute_id = absint( $result );
		$fresh_record = wpagent_wc_attribute_record( $attribute_id );
		if ( ! $fresh_record ) {
			return wpagent_wc_attribute_recovery_required( $attribute_id );
		}
		$fresh    = wpagent_wc_attribute_payload( $fresh_record );
		$expected = array_merge( array( 'attribute_id' => $attribute_id ), $next );
		foreach ( array( 'attribute_id', 'name', 'slug', 'type', 'order_by', 'has_archives' ) as $field ) {
			if ( $fresh[ $field ] !== $expected[ $field ] ) {
				return wpagent_wc_attribute_recovery_required( $attribute_id );
			}
		}
		return array( 'attribute' => $fresh, 'created' => $creating, 'verified' => true );
	} finally {
		wpagent_wc_attribute_release_lock( $lock );
	}
}

function wpagent_ability_delete_product_attribute(): array {
	return array(
		'label'               => __( 'Globales Produktattribut löschen (manuell erforderlich)', 'wp-agent-companion' ),
		'description'         => __( 'Die Remote-Löschung globaler WooCommerce-Produktattribute ist bewusst deaktiviert. WooCommerce bietet dafür keine provider-atomare bedingte Löschung; führe die potenziell weitreichende Bereinigung manuell im WooCommerce-Admin aus.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'attribute_id'       => array( 'type' => 'integer', 'minimum' => 1 ),
				'expected_state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'confirm'            => array( 'type' => 'boolean' ),
				'confirm_data_loss'  => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'attribute_id', 'expected_state_hash', 'confirm', 'confirm_data_loss' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'attribute_id' => array( 'type' => 'integer' ),
				'deleted'      => array( 'type' => 'boolean' ),
				'verified'     => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'attribute_id', 'deleted', 'verified' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_delete_product_attribute',
		'permission_callback' => 'wpagent_perm_wc_manage_product_terms',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false, 'manual_only' => true ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_product_attribute( $input ) {
	unset( $input );
	return new WP_Error( 'wpagent_wc_attribute_delete_manual_only', __( 'Globale WooCommerce-Produktattribute werden von WPAgently nicht remote gelöscht. Die Löschung kann zugehörige Terme und Produktzuweisungen verändern, ohne dass WooCommerce eine provider-atomare bedingte Operation anbietet. Prüfe und lösche das Attribut manuell im WooCommerce-Admin.', 'wp-agent-companion' ), array( 'status' => 409, 'manual_only' => true ) );
}
