<?php
/** Provider writers for bounded global SEO settings. */

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

/** @param array<int|string,mixed> $robots @return string[] */
function wpagent_seo_settings_set_noindex( array $robots, bool $noindex ): array {
	$robots = array_values( array_filter( $robots, static fn( $value ) => ! in_array( $value, array( 'index', 'noindex' ), true ) ) );
	array_unshift( $robots, $noindex ? 'noindex' : 'index' );
	return array_values( array_unique( $robots ) );
}

/** @param array<string,mixed> $patch @return true|WP_Error */
function wpagent_write_rankmath_seo_settings( array $patch ) {
	if ( ! class_exists( 'RankMath\Helper' ) ) {
		return new WP_Error( 'wpagent_seo_settings_provider_unavailable', __( 'Rank Math ist nicht vollständig geladen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$options = get_option( 'rank-math-options-titles', array() );
	$options = is_array( $options ) ? $options : array();
	$templates = array(
		'homepage_title_template'             => 'homepage_title',
		'homepage_description_template'       => 'homepage_description',
		'author_archive_title_template'       => 'author_archive_title',
		'author_archive_description_template' => 'author_archive_description',
		'date_archive_title_template'         => 'date_archive_title',
		'date_archive_description_template'   => 'date_archive_description',
		'search_title_template'               => 'search_title',
	);
	foreach ( $templates as $field => $key ) {
		if ( array_key_exists( $field, $patch ) ) {
			$options[ $key ] = wpagent_seo_settings_template_to_provider( 'rankmath', $patch[ $field ] );
		}
	}
	if ( array_key_exists( 'title_separator', $patch ) ) {
		$options['title_separator'] = wpagent_seo_separator_entities()[ $patch['title_separator'] ];
	}
	if ( array_key_exists( 'author_archives_enabled', $patch ) ) {
		$options['disable_author_archives'] = $patch['author_archives_enabled'] ? 'off' : 'on';
	}
	if ( array_key_exists( 'author_archives_noindex', $patch ) ) {
		$options['author_custom_robots'] = 'on';
		$options['author_robots']        = wpagent_seo_settings_set_noindex( (array) ( $options['author_robots'] ?? array() ), $patch['author_archives_noindex'] );
	}
	if ( array_key_exists( 'date_archives_enabled', $patch ) ) {
		$options['disable_date_archives'] = $patch['date_archives_enabled'] ? 'off' : 'on';
	}
	if ( array_key_exists( 'date_archives_noindex', $patch ) ) {
		$options['date_archive_robots'] = wpagent_seo_settings_set_noindex( (array) ( $options['date_archive_robots'] ?? array() ), $patch['date_archives_noindex'] );
	}
	if ( array_key_exists( 'search_noindex', $patch ) ) {
		$options['noindex_search'] = $patch['search_noindex'] ? 'on' : 'off';
	}
	if ( array_key_exists( 'identity_type', $patch ) ) {
		$options['knowledgegraph_type'] = 'person' === $patch['identity_type'] ? 'person' : 'company';
	}
	foreach ( array( 'identity_name' => 'knowledgegraph_name', 'website_name' => 'website_name', 'alternate_website_name' => 'website_alternate_name' ) as $field => $key ) {
		if ( array_key_exists( $field, $patch ) ) {
			$options[ $key ] = $patch[ $field ];
		}
	}
	if ( array_key_exists( 'identity_logo_url', $patch ) ) {
		$options['knowledgegraph_logo']    = $patch['identity_logo_url'];
		$options['knowledgegraph_logo_id'] = 0;
	}
	update_option( 'rank-math-options-titles', $options );
	wpagent_seo_settings_refresh_provider( 'rankmath' );
	return true;
}

/** @param array<string,mixed> $patch @return true|WP_Error */
function wpagent_write_yoast_seo_settings( array $patch ) {
	if ( ! class_exists( 'WPSEO_Options' ) ) {
		return new WP_Error( 'wpagent_seo_settings_provider_unavailable', __( 'Yoast SEO ist nicht vollständig geladen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$set = static function ( string $key, $value ): void {
		WPSEO_Options::set( $key, $value, 'wpseo_titles' );
	};
	$templates = array(
		'homepage_title_template'             => 'title-home-wpseo',
		'homepage_description_template'       => 'metadesc-home-wpseo',
		'author_archive_title_template'       => 'title-author-wpseo',
		'author_archive_description_template' => 'metadesc-author-wpseo',
		'date_archive_title_template'         => 'title-archive-wpseo',
		'date_archive_description_template'   => 'metadesc-archive-wpseo',
		'search_title_template'               => 'title-search-wpseo',
	);
	foreach ( $templates as $field => $key ) {
		if ( array_key_exists( $field, $patch ) ) {
			$set( $key, wpagent_seo_settings_template_to_provider( 'yoast', $patch[ $field ] ) );
		}
	}
	if ( array_key_exists( 'title_separator', $patch ) ) {
		$key = array_search( $patch['title_separator'], wpagent_yoast_separator_map(), true );
		if ( false === $key ) {
			return new WP_Error( 'wpagent_seo_settings_invalid_separator', __( 'Yoast unterstützt dieses Trennzeichen nicht.', 'wp-agent-companion' ), array( 'status' => 400 ) );
		}
		$set( 'separator', $key );
	}
	$booleans = array(
		'author_archives_enabled' => array( 'disable-author', true ),
		'author_archives_noindex' => array( 'noindex-author-wpseo', false ),
		'date_archives_enabled'   => array( 'disable-date', true ),
		'date_archives_noindex'   => array( 'noindex-archive-wpseo', false ),
	);
	foreach ( $booleans as $field => $config ) {
		if ( array_key_exists( $field, $patch ) ) {
			$set( $config[0], $config[1] ? ! $patch[ $field ] : $patch[ $field ] );
		}
	}
	if ( array_key_exists( 'identity_type', $patch ) ) {
		$set( 'company_or_person', 'person' === $patch['identity_type'] ? 'person' : 'company' );
	}
	$type = array_key_exists( 'identity_type', $patch ) ? $patch['identity_type'] : ( 'person' === WPSEO_Options::get( 'company_or_person', 'company', array( 'wpseo_titles' ) ) ? 'person' : 'organization' );
	if ( array_key_exists( 'identity_name', $patch ) ) {
		$set( 'person' === $type ? 'person_name' : 'company_name', $patch['identity_name'] );
	}
	if ( array_key_exists( 'identity_logo_url', $patch ) ) {
		$prefix = 'person' === $type ? 'person' : 'company';
		$set( $prefix . '_logo', $patch['identity_logo_url'] );
		$set( $prefix . '_logo_id', 0 );
		$set( $prefix . '_logo_meta', false );
	}
	foreach ( array( 'website_name' => 'website_name', 'alternate_website_name' => 'alternate_website_name' ) as $field => $key ) {
		if ( array_key_exists( $field, $patch ) ) {
			$set( $key, $patch[ $field ] );
		}
	}
	WPSEO_Options::clear_cache();
	return true;
}

function wpagent_set_aioseo_archive_noindex( string $archive, bool $noindex ): void {
	aioseo()->options->searchAppearance->archives->{$archive}->show = ! $noindex;
	aioseo()->options->searchAppearance->archives->{$archive}->advanced->robotsMeta->default = false;
	aioseo()->options->searchAppearance->archives->{$archive}->advanced->robotsMeta->noindex = $noindex;
}

/** @param array<string,mixed> $patch @return true|WP_Error */
function wpagent_write_aioseo_seo_settings( array $patch ) {
	$tree = wpagent_aioseo_settings_tree();
	if ( is_wp_error( $tree ) ) {
		return $tree;
	}
	$templates = array(
		'homepage_title_template'             => array( 'global', 'siteTitle' ),
		'homepage_description_template'       => array( 'global', 'metaDescription' ),
		'author_archive_title_template'       => array( 'author', 'title' ),
		'author_archive_description_template' => array( 'author', 'metaDescription' ),
		'date_archive_title_template'         => array( 'date', 'title' ),
		'date_archive_description_template'   => array( 'date', 'metaDescription' ),
		'search_title_template'               => array( 'search', 'title' ),
		'search_description_template'         => array( 'search', 'metaDescription' ),
	);
	foreach ( $templates as $field => $target ) {
		if ( ! array_key_exists( $field, $patch ) ) {
			continue;
		}
		$value = wpagent_seo_settings_template_to_provider( 'aioseo', $patch[ $field ] );
		if ( 'global' === $target[0] ) {
			aioseo()->options->searchAppearance->global->{$target[1]} = $value;
		} else {
			aioseo()->options->searchAppearance->archives->{$target[0]}->{$target[1]} = $value;
		}
	}
	if ( array_key_exists( 'title_separator', $patch ) ) {
		aioseo()->options->searchAppearance->global->separator = wpagent_seo_separator_entities()[ $patch['title_separator'] ];
	}
	foreach ( array( 'author_archives_noindex' => 'author', 'date_archives_noindex' => 'date', 'search_noindex' => 'search' ) as $field => $archive ) {
		if ( array_key_exists( $field, $patch ) ) {
			wpagent_set_aioseo_archive_noindex( $archive, $patch[ $field ] );
		}
	}
	if ( array_key_exists( 'identity_type', $patch ) ) {
		aioseo()->options->searchAppearance->global->schema->siteRepresents = $patch['identity_type'];
	}
	$type = array_key_exists( 'identity_type', $patch ) ? $patch['identity_type'] : ( 'person' === (string) $tree['schema']['siteRepresents'] ? 'person' : 'organization' );
	if ( array_key_exists( 'identity_name', $patch ) ) {
		$key = 'person' === $type ? 'personName' : 'organizationName';
		aioseo()->options->searchAppearance->global->schema->{$key} = $patch['identity_name'];
	}
	if ( array_key_exists( 'identity_logo_url', $patch ) ) {
		$key = 'person' === $type ? 'personLogo' : 'organizationLogo';
		aioseo()->options->searchAppearance->global->schema->{$key} = $patch['identity_logo_url'];
	}
	if ( array_key_exists( 'website_name', $patch ) ) {
		aioseo()->options->searchAppearance->global->schema->websiteName = $patch['website_name'];
	}
	if ( array_key_exists( 'alternate_website_name', $patch ) ) {
		aioseo()->options->searchAppearance->global->schema->websiteAlternateName = $patch['alternate_website_name'];
	}
	aioseo()->options->save( true );
	// AIOSEO updates its in-memory options before update_option(). Reload from the
	// database so the caller's verification detects blocked or partial writes.
	wpagent_seo_settings_refresh_provider( 'aioseo' );
	return true;
}

/** @return WP_REST_Request */
function wpagent_seopress_settings_request( array $options ): WP_REST_Request {
	$request = new WP_REST_Request( 'POST' );
	$request->set_header( 'content-type', 'application/json' );
	$request->set_body( (string) wp_json_encode( $options ) );
	return $request;
}

/** @param array<string,mixed> $patch @return true|WP_Error */
function wpagent_write_seopress_seo_settings( array $patch ) {
	if ( ! function_exists( 'seopress_sanitize_options_fields' ) || ! class_exists( 'SEOPress\Actions\Api\Options\TitlesSettings' ) || ! class_exists( 'SEOPress\Actions\Api\Options\SocialSettings' ) ) {
		return new WP_Error( 'wpagent_seo_settings_provider_unavailable', __( 'SEOPress ist nicht vollständig geladen.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$titles = get_option( 'seopress_titles_option_name', array() );
	$social = get_option( 'seopress_social_option_name', array() );
	$titles = is_array( $titles ) ? $titles : array();
	$social = is_array( $social ) ? $social : array();
	$title_changed  = false;
	$social_changed = false;
	$title_map = array(
		'homepage_title_template'             => 'seopress_titles_home_site_title',
		'homepage_description_template'       => 'seopress_titles_home_site_desc',
		'author_archive_title_template'       => 'seopress_titles_archives_author_title',
		'author_archive_description_template' => 'seopress_titles_archives_author_desc',
		'date_archive_title_template'         => 'seopress_titles_archives_date_title',
		'date_archive_description_template'   => 'seopress_titles_archives_date_desc',
		'search_title_template'               => 'seopress_titles_archives_search_title',
		'search_description_template'         => 'seopress_titles_archives_search_desc',
	);
	foreach ( $title_map as $field => $key ) {
		if ( array_key_exists( $field, $patch ) ) {
			$titles[ $key ] = wpagent_seo_settings_template_to_provider( 'seopress', $patch[ $field ] );
			$title_changed  = true;
		}
	}
	if ( array_key_exists( 'title_separator', $patch ) ) {
		$titles['seopress_titles_sep'] = $patch['title_separator'];
		$title_changed = true;
	}
	foreach ( array( 'author_archives_noindex' => 'seopress_titles_archives_author_noindex', 'date_archives_noindex' => 'seopress_titles_archives_date_noindex', 'search_noindex' => 'seopress_titles_archives_search_title_noindex' ) as $field => $key ) {
		if ( array_key_exists( $field, $patch ) ) {
			$titles[ $key ] = $patch[ $field ] ? '1' : '';
			$title_changed  = true;
		}
	}
	if ( array_key_exists( 'identity_type', $patch ) ) {
		$social['seopress_social_knowledge_type'] = 'person' === $patch['identity_type'] ? 'Person' : 'Organization';
		$social_changed = true;
	}
	foreach ( array( 'identity_name' => 'seopress_social_knowledge_name', 'identity_logo_url' => 'seopress_social_knowledge_img' ) as $field => $key ) {
		if ( array_key_exists( $field, $patch ) ) {
			$social[ $key ] = $patch[ $field ];
			$social_changed = true;
		}
	}
	if ( $title_changed ) {
		$response = ( new \SEOPress\Actions\Api\Options\TitlesSettings() )->processPost( wpagent_seopress_settings_request( $titles ) );
		if ( is_wp_error( $response ) ) {
			return $response;
		}
	}
	if ( $social_changed ) {
		$response = ( new \SEOPress\Actions\Api\Options\SocialSettings() )->processPost( wpagent_seopress_settings_request( $social ) );
		if ( is_wp_error( $response ) ) {
			return $response;
		}
	}
	return true;
}

/** @param array<string,mixed> $patch @return true|WP_Error */
function wpagent_write_seo_settings( string $plugin, array $patch ) {
	$writers = array(
		'rankmath' => 'wpagent_write_rankmath_seo_settings',
		'yoast'    => 'wpagent_write_yoast_seo_settings',
		'aioseo'   => 'wpagent_write_aioseo_seo_settings',
		'seopress' => 'wpagent_write_seopress_seo_settings',
	);
	if ( ! isset( $writers[ $plugin ] ) ) {
		return new WP_Error( 'wpagent_seo_plugin_missing', __( 'Kein unterstütztes SEO-Plugin aktiv.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	return call_user_func( $writers[ $plugin ], $patch );
}
