<?php
/** Ability: wp-agent/delete-post-schema */

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

function wpagent_ability_delete_post_schema(): array {
	return array(
		'label'               => __( 'Post-Schema löschen und verifizieren', 'wp-agent-companion' ),
		'description'         => __( 'Löscht genau ein Rank-Math-Schema erst nach exakter ID-Bestätigung und aktuellem Konflikt-Hash. Der Providerzustand wird rückgelesen und ein Teilfehler verifiziert zurückgerollt.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'           => array( 'type' => 'integer', 'minimum' => 1 ),
				'schema_id'         => array( 'type' => 'string', 'pattern' => '^schema-[1-9][0-9]*$' ),
				'confirm_schema_id' => array( 'type' => 'string', 'pattern' => '^schema-[1-9][0-9]*$' ),
				'expected_hash'     => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'post_id', 'schema_id', 'confirm_schema_id', 'expected_hash' ),
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'post_id'               => array( 'type' => 'integer' ),
				'plugin'                => array( 'type' => 'string' ),
				'schema_id'             => array( 'type' => 'string' ),
				'deleted'               => array( 'type' => 'boolean' ),
				'rich_snippet_disabled' => array( 'type' => 'boolean' ),
				'previous_hash'          => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'state_hash'             => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'verified'               => array( 'type' => 'boolean' ),
				'rolled_back'            => array( 'type' => 'boolean' ),
				'rollback_verified'      => array( 'type' => array( 'boolean', 'null' ) ),
			),
			'required'             => array( 'post_id', 'plugin', 'schema_id', 'deleted', 'rich_snippet_disabled', 'previous_hash', 'state_hash', 'verified', 'rolled_back', 'rollback_verified' ),
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_delete_post_schema',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => true, 'idempotent' => false ) ),
	);
}

/** @param mixed $input @return array<string,mixed>|WP_Error */
function wpagent_exec_delete_post_schema( $input ) {
	$input   = is_array( $input ) ? $input : array();
	$post_id = absint( $input['post_id'] ?? 0 );
	if ( ! $post_id || ! get_post( $post_id ) ) {
		return new WP_Error( 'wpagent_no_post', __( 'Beitrag nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}
	if ( ! current_user_can( 'edit_post', $post_id ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$schema_id = (string) ( $input['schema_id'] ?? '' );
	$confirmed = (string) ( $input['confirm_schema_id'] ?? '' );
	if ( ! preg_match( '/^schema-[1-9][0-9]*$/', $schema_id ) ) {
		return new WP_Error( 'wpagent_invalid_schema_id', __( 'Die Rank-Math-Schema-ID ist ungültig.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( ! preg_match( '/^schema-[1-9][0-9]*$/', $confirmed ) || $schema_id !== $confirmed ) {
		return new WP_Error( 'wpagent_schema_delete_confirmation', __( 'confirm_schema_id muss die zu löschende schema_id exakt wiederholen.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$expected_hash = strtolower( (string) ( $input['expected_hash'] ?? '' ) );
	if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_hash ) ) {
		return new WP_Error( 'wpagent_schema_hash', __( 'expected_hash muss ein vollständiger SHA-256-Hash aus get-post-schema sein.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$plugin = wpagent_detect_seo_plugin();
	if ( 'rankmath' !== $plugin ) {
		return new WP_Error( 'wpagent_schema_delete_provider_unsupported', __( 'Nur Rank Math stellt den bestätigten Pfad zum Löschen benutzerdefinierter Post-Schemas bereit.', 'wp-agent-companion' ), array( 'status' => 409, 'plugin' => $plugin ) );
	}
	if ( ! class_exists( 'RankMath\\Schema\\DB' ) || ! class_exists( 'RankMath\\Helper' ) ) {
		return new WP_Error( 'wpagent_schema_api_missing', __( 'Rank Math stellt seinen Schema-Löschpfad nicht bereit.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( ! \RankMath\Helper::has_cap( 'onpage_snippet' ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Rank Math erlaubt diesem Benutzer keine Schemaänderungen.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}

	$lock = wpagent_seo_acquire_lock( $post_id );
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		return wpagent_delete_rankmath_post_schema( $post_id, $schema_id, $expected_hash );
	} finally {
		wpagent_seo_release_lock( $post_id, $lock );
	}
}

/** @return array<string,mixed>|WP_Error */
function wpagent_delete_rankmath_post_schema( int $post_id, string $schema_id, string $expected_hash ) {
	$current = wpagent_read_post_schema( $post_id, 'rankmath' );
	if ( is_wp_error( $current ) ) {
		return $current;
	}
	if ( ! hash_equals( $current['state_hash'], $expected_hash ) ) {
		return new WP_Error( 'wpagent_schema_conflict', __( 'Die Post-Schemadaten wurden seit dem Lesen verändert. Bitte erneut lesen und den neuen state_hash verwenden.', 'wp-agent-companion' ), array( 'status' => 409, 'state_hash' => $current['state_hash'] ) );
	}
	$schemas = \RankMath\Schema\DB::get_schemas( $post_id, 'postmeta', true );
	if ( ! isset( $schemas[ $schema_id ] ) || ! is_array( $schemas[ $schema_id ] ) ) {
		return new WP_Error( 'wpagent_schema_not_found', __( 'Das Rank-Math-Schema wurde nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}

	$meta_id = absint( str_replace( 'schema-', '', $schema_id ) );
	$record  = get_metadata_by_mid( 'post', $meta_id );
	$value   = false === $record ? null : maybe_unserialize( $record->meta_value ?? null );
	$key     = false === $record ? '' : (string) ( $record->meta_key ?? '' );
	$owner   = false === $record ? 0 : absint( $record->post_id ?? $record->object_id ?? 0 );
	if ( $post_id !== $owner || ! str_starts_with( $key, 'rank_math_schema_' ) || $value !== $schemas[ $schema_id ] ) {
		return new WP_Error( 'wpagent_schema_record_mismatch', __( 'Die Rank-Math-Schema-ID stimmt nicht eindeutig mit dem gespeicherten Metadatensatz überein.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}

	$schema       = $schemas[ $schema_id ];
	$shortcode    = isset( $schema['metadata']['shortcode'] ) ? (string) $schema['metadata']['shortcode'] : '';
	$shortcut_key = '' !== $shortcode ? 'rank_math_shortcode_schema_' . $shortcode : '';
	$side_keys    = array( 'rank_math_rich_snippet' );
	if ( '' !== $shortcut_key ) {
		$side_keys[] = $shortcut_key;
	}
	$side_state = wpagent_capture_seo_postmeta( $post_id, $side_keys );
	if ( '' !== $shortcut_key ) {
		$links = $side_state[ $shortcut_key ];
		if ( 1 !== count( $links ) || $meta_id !== absint( $links[0] ) ) {
			return new WP_Error( 'wpagent_schema_shortcode_mismatch', __( 'Die Rank-Math-Shortcode-Zuordnung ist inkonsistent und muss vor dem Löschen manuell geprüft werden.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
	}

	try {
		update_post_meta( $post_id, 'rank_math_rich_snippet', 'off' );
		if ( '' !== $shortcut_key ) {
			delete_post_meta( $post_id, $shortcut_key, $side_state[ $shortcut_key ][0] );
			if ( metadata_exists( 'post', $post_id, $shortcut_key ) ) {
				throw new RuntimeException( 'Rank Math schema shortcut deletion failed.' );
			}
		}
		delete_metadata_by_mid( 'post', $meta_id );
		$fresh         = \RankMath\Schema\DB::get_schemas( $post_id, 'postmeta', true );
		$rich_values   = get_post_meta( $post_id, 'rank_math_rich_snippet', false );
		$rich_disabled = ! empty( $rich_values ) && ! in_array( false, array_map( static fn( $item ): bool => 'off' === (string) $item, $rich_values ), true );
		$verified      = ! isset( $fresh[ $schema_id ] ) && $rich_disabled && ( '' === $shortcut_key || ! metadata_exists( 'post', $post_id, $shortcut_key ) );
		if ( ! $verified ) {
			throw new RuntimeException( 'Rank Math schema deletion could not be verified.' );
		}
		$final = wpagent_rankmath_schema_state_from_raw( $post_id, $fresh );
		return array(
			'post_id' => $post_id, 'plugin' => 'rankmath', 'schema_id' => $schema_id,
			'deleted' => true, 'rich_snippet_disabled' => true,
			'previous_hash' => $current['state_hash'], 'state_hash' => $final['state_hash'],
			'verified' => true, 'rolled_back' => false, 'rollback_verified' => null,
		);
	} catch ( Throwable ) {
		$rollback_verified = wpagent_restore_deleted_rankmath_schema( $post_id, $meta_id, $key, $schema, $side_state );
		return new WP_Error(
			'wpagent_schema_delete_failed',
			$rollback_verified
				? __( 'Rank Math konnte das Schema nicht verifiziert löschen. Der vorherige Zustand wurde wiederhergestellt.', 'wp-agent-companion' )
				: __( 'Rank Math konnte das Schema nicht sicher löschen und das Rollback wurde nicht bestätigt. Prüfe den Beitrag sofort manuell.', 'wp-agent-companion' ),
			array( 'status' => $rollback_verified ? 502 : 500, 'rolled_back' => true, 'rollback_verified' => $rollback_verified )
		);
	}
}
