<?php
/**
 * Odysseo SEO — Settings page (Settings → Odysseo SEO).
 *
 * @package    Odysseo
 * @author     Chandrabhan Shekhawat
 * @company    Gigai Kripa Services
 * @link       https://gigaikripaservices.com/
 * @copyright  Copyright (c) 2026, Gigai Kripa Services
 */

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

/**
 * Registers and renders the plugin settings screen.
 */
class Odysseo_SEO_Settings {

	const GROUP = 'odysseo_seo_settings_group';
	const PAGE  = 'odysseo-seo';

	/**
	 * Hook up.
	 */
	public function __construct() {
		add_action( 'admin_menu', array( $this, 'add_page' ) );
		add_action( 'admin_init', array( $this, 'register' ) );
	}

	/**
	 * Add the page under the core "Settings" menu.
	 */
	public function add_page() {
		add_options_page(
			__( 'Odysseo SEO', 'odysseo-core' ),
			__( 'Odysseo SEO', 'odysseo-core' ),
			'manage_options',
			self::PAGE,
			array( $this, 'render' )
		);
	}

	/**
	 * Register the single settings option + its sanitizer.
	 */
	public function register() {
		register_setting(
			self::GROUP,
			ODYSSEO_SEO_OPTION,
			array(
				'type'              => 'array',
				'sanitize_callback' => array( $this, 'sanitize' ),
				'default'           => array(),
			)
		);
	}

	/**
	 * Sanitize all settings. The API key is only overwritten when a new value is
	 * actually typed, so the stored secret is never required to round-trip through
	 * the form (and is never echoed back in full).
	 *
	 * @param mixed $input Raw submitted values.
	 * @return array
	 */
	public function sanitize( $input ) {
		$current = odysseo_seo_get_settings();
		$input   = is_array( $input ) ? $input : array();
		$out     = array();

		$provider        = isset( $input['provider'] ) ? sanitize_key( $input['provider'] ) : 'openai';
		$out['provider'] = in_array( $provider, array( 'openai', 'gemini' ), true ) ? $provider : 'openai';

		$out['model_openai'] = ! empty( $input['model_openai'] ) ? sanitize_text_field( $input['model_openai'] ) : 'gpt-4o-mini';
		$out['model_gemini'] = ! empty( $input['model_gemini'] ) ? sanitize_text_field( $input['model_gemini'] ) : 'gemini-1.5-flash';

		// GSC: accept a full <meta> tag or just the token; store only the token.
		$gsc = isset( $input['gsc_verification'] ) ? wp_strip_all_tags( (string) $input['gsc_verification'] ) : '';
		if ( preg_match( '/content=["\']?([A-Za-z0-9_\-]+)/', (string) ( $input['gsc_verification'] ?? '' ), $m ) ) {
			$gsc = $m[1];
		}
		$out['gsc_verification'] = sanitize_text_field( $gsc );

		// API key: blank submission = keep the existing stored key.
		$new_key        = isset( $input['api_key'] ) ? trim( (string) $input['api_key'] ) : '';
		$out['api_key'] = '' === $new_key ? $current['api_key'] : sanitize_text_field( $new_key );

		// Structured-data toggles (checkboxes: present = on).
		foreach ( array( 'org', 'website', 'breadcrumb', 'article', 'destination', 'package', 'vehicle', 'faq', 'service', 'rating' ) as $t ) {
			$out[ 'schema_' . $t ] = empty( $input[ 'schema_' . $t ] ) ? '0' : '1';
		}
		// Organization-level fields.
		$out['schema_legal_name']  = isset( $input['schema_legal_name'] ) ? sanitize_text_field( $input['schema_legal_name'] ) : '';
		$out['schema_logo']        = isset( $input['schema_logo'] ) ? esc_url_raw( $input['schema_logo'] ) : '';
		$out['schema_founding']    = isset( $input['schema_founding'] ) ? sanitize_text_field( $input['schema_founding'] ) : '';
		$out['schema_price_range'] = isset( $input['schema_price_range'] ) ? sanitize_text_field( $input['schema_price_range'] ) : '';

		return $out;
	}

	/**
	 * Show the last 4 chars of a stored key, masked.
	 *
	 * @param string $key Stored key.
	 * @return string
	 */
	private function mask( $key ) {
		$key = (string) $key;
		if ( '' === $key ) {
			return '';
		}
		$tail = substr( $key, -4 );
		return str_repeat( '•', 8 ) . esc_html( $tail );
	}

	/**
	 * Render the settings form.
	 */
	public function render() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}
		$s            = odysseo_seo_get_settings();
		$key_constant = odysseo_seo_key_is_constant();
		$has_key      = odysseo_seo_has_api_key();
		?>
		<div class="wrap">
			<h1><?php esc_html_e( 'Odysseo SEO', 'odysseo-core' ); ?></h1>

			<p class="description" style="max-width:720px;">
				<?php esc_html_e( 'AI is optional and only runs when you click "Generate with AI" on a post. You supply your own API key, and all AI usage is billed to you by your chosen provider. This tool makes your site SEO-ready (meta tags, structured data, sitemap) — it does not submit your site to Google or guarantee rankings.', 'odysseo-core' ); ?>
			</p>

			<form method="post" action="options.php">
				<?php settings_fields( self::GROUP ); ?>
				<table class="form-table" role="presentation">
					<tr>
						<th scope="row"><label for="odysseo-seo-provider"><?php esc_html_e( 'AI Provider', 'odysseo-core' ); ?></label></th>
						<td>
							<select id="odysseo-seo-provider" name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[provider]">
								<option value="openai" <?php selected( $s['provider'], 'openai' ); ?>>OpenAI</option>
								<option value="gemini" <?php selected( $s['provider'], 'gemini' ); ?>>Google Gemini</option>
							</select>
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="odysseo-seo-api-key"><?php esc_html_e( 'API Key', 'odysseo-core' ); ?></label></th>
						<td>
							<?php if ( $key_constant ) : ?>
								<p><strong><?php esc_html_e( 'Set via the ODYSSEO_SEO_API_KEY constant in wp-config.php.', 'odysseo-core' ); ?></strong></p>
							<?php else : ?>
								<input type="password" id="odysseo-seo-api-key" class="regular-text" autocomplete="off"
									name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[api_key]" value=""
									placeholder="<?php echo $has_key ? esc_attr( $this->mask( $s['api_key'] ) ) : esc_attr__( 'Paste your API key', 'odysseo-core' ); ?>">
								<p class="description">
									<?php
									echo $has_key
										? esc_html__( 'A key is saved. Leave blank to keep it, or paste a new key to replace it.', 'odysseo-core' )
										: esc_html__( 'Stored in the database. For extra safety you may instead define ODYSSEO_SEO_API_KEY in wp-config.php.', 'odysseo-core' );
									?>
								</p>
							<?php endif; ?>
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="odysseo-seo-model-openai"><?php esc_html_e( 'OpenAI Model', 'odysseo-core' ); ?></label></th>
						<td><input type="text" id="odysseo-seo-model-openai" class="regular-text" name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[model_openai]" value="<?php echo esc_attr( $s['model_openai'] ); ?>">
							<p class="description"><?php esc_html_e( 'Default: gpt-4o-mini', 'odysseo-core' ); ?></p></td>
					</tr>
					<tr>
						<th scope="row"><label for="odysseo-seo-model-gemini"><?php esc_html_e( 'Gemini Model', 'odysseo-core' ); ?></label></th>
						<td><input type="text" id="odysseo-seo-model-gemini" class="regular-text" name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[model_gemini]" value="<?php echo esc_attr( $s['model_gemini'] ); ?>">
							<p class="description"><?php esc_html_e( 'Default: gemini-1.5-flash', 'odysseo-core' ); ?></p></td>
					</tr>
					<tr>
						<th scope="row"><label for="odysseo-seo-gsc"><?php esc_html_e( 'Google Search Console verification', 'odysseo-core' ); ?></label></th>
						<td><input type="text" id="odysseo-seo-gsc" class="regular-text" name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[gsc_verification]" value="<?php echo esc_attr( $s['gsc_verification'] ); ?>">
							<p class="description"><?php esc_html_e( 'Optional. Paste the verification token (or the full meta tag) from Search Console.', 'odysseo-core' ); ?></p></td>
					</tr>
				</table>

				<hr>
				<h2><?php esc_html_e( 'Structured Data (Schema)', 'odysseo-core' ); ?></h2>
				<p class="description" style="max-width:720px;">
					<?php esc_html_e( 'The theme outputs JSON-LD structured data automatically. Toggle any type off if another SEO plugin already provides it. Verify the current output with the Rich Results Test.', 'odysseo-core' ); ?>
					<a href="https://search.google.com/test/rich-results" target="_blank" rel="noopener"><?php esc_html_e( 'Open Rich Results Test ↗', 'odysseo-core' ); ?></a>
				</p>
				<table class="form-table" role="presentation">
					<?php
					$types = array(
						'org'         => __( 'Organization / TravelAgency (home, contact)', 'odysseo-core' ),
						'website'     => __( 'WebSite + Sitelinks Search (home)', 'odysseo-core' ),
						'breadcrumb'  => __( 'BreadcrumbList (all inner pages)', 'odysseo-core' ),
						'article'     => __( 'Article (blog posts)', 'odysseo-core' ),
						'destination' => __( 'TouristDestination (destinations)', 'odysseo-core' ),
						'package'     => __( 'Product + Offer + TouristTrip (tour packages)', 'odysseo-core' ),
						'vehicle'     => __( 'Vehicle + Offer (fleet)', 'odysseo-core' ),
						'faq'         => __( 'FAQPage (About page FAQs)', 'odysseo-core' ),
						'service'     => __( 'Service / OfferCatalog (home)', 'odysseo-core' ),
						'rating'      => __( 'AggregateRating (from testimonials)', 'odysseo-core' ),
					);
					foreach ( $types as $key => $label ) :
						$id = 'odysseo-seo-schema-' . $key;
						?>
						<tr>
							<th scope="row"><label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( $label ); ?></label></th>
							<td>
								<label><input type="checkbox" id="<?php echo esc_attr( $id ); ?>" name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[schema_<?php echo esc_attr( $key ); ?>]" value="1" <?php checked( odysseo_seo_schema_on( $key ) ); ?>> <?php esc_html_e( 'Enabled', 'odysseo-core' ); ?></label>
							</td>
						</tr>
					<?php endforeach; ?>
				</table>

				<h3><?php esc_html_e( 'Organization details (used in schema)', 'odysseo-core' ); ?></h3>
				<table class="form-table" role="presentation">
					<tr>
						<th scope="row"><label for="odysseo-seo-legal"><?php esc_html_e( 'Legal / business name', 'odysseo-core' ); ?></label></th>
						<td><input type="text" id="odysseo-seo-legal" class="regular-text" name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[schema_legal_name]" value="<?php echo esc_attr( $s['schema_legal_name'] ); ?>" placeholder="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>">
							<p class="description"><?php esc_html_e( 'Defaults to the Site Title.', 'odysseo-core' ); ?></p></td>
					</tr>
					<tr>
						<th scope="row"><label for="odysseo-seo-logo"><?php esc_html_e( 'Logo URL', 'odysseo-core' ); ?></label></th>
						<td><input type="url" id="odysseo-seo-logo" class="regular-text" name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[schema_logo]" value="<?php echo esc_attr( $s['schema_logo'] ); ?>" placeholder="https://example.com/logo.png">
							<p class="description"><?php esc_html_e( 'Defaults to the theme logo.', 'odysseo-core' ); ?></p></td>
					</tr>
					<tr>
						<th scope="row"><label for="odysseo-seo-founding"><?php esc_html_e( 'Founding year', 'odysseo-core' ); ?></label></th>
						<td><input type="text" id="odysseo-seo-founding" class="regular-text" name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[schema_founding]" value="<?php echo esc_attr( $s['schema_founding'] ); ?>" placeholder="2010"></td>
					</tr>
					<tr>
						<th scope="row"><label for="odysseo-seo-price-range"><?php esc_html_e( 'Price range', 'odysseo-core' ); ?></label></th>
						<td><input type="text" id="odysseo-seo-price-range" class="regular-text" name="<?php echo esc_attr( ODYSSEO_SEO_OPTION ); ?>[schema_price_range]" value="<?php echo esc_attr( $s['schema_price_range'] ); ?>" placeholder="$$">
							<p class="description"><?php esc_html_e( 'e.g. $, $$, $$$ — a rough price indicator for search engines.', 'odysseo-core' ); ?></p></td>
					</tr>
				</table>

				<?php submit_button(); ?>
			</form>
		</div>
		<?php
	}
}
