<?php
/**
 * GSC Ajax Controller.
 *
 * All endpoints require a valid nonce and master-admin authorisation.
 *
 *   - platform_helm_gsc_save        — store service-account JSON + property
 *   - platform_helm_gsc_test        — list properties (verifies the connection)
 *   - platform_helm_gsc_sync        — run a Search Analytics sync now
 *   - platform_helm_gsc_disconnect  — clear credentials
 *   - platform_helm_gsc_save_range  — set the lookback window
 *
 * @package Platform\Helm\Modules\GSC
 */

declare( strict_types = 1 );

namespace Platform\Helm\Modules\GSC;

use Platform\Helm\Core\Authorization;

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

final class GscAjaxController {

	public const NONCE_ACTION = 'platform_helm_gsc';

	public function __construct(
		private GscClient $client,
		private GscSync $sync
	) {}

	public function register_hooks(): void {
		add_action( 'wp_ajax_platform_helm_gsc_save',       [ $this, 'ajax_save' ] );
		add_action( 'wp_ajax_platform_helm_gsc_save_oauth', [ $this, 'ajax_save_oauth' ] );
		add_action( 'wp_ajax_platform_helm_gsc_test',       [ $this, 'ajax_test' ] );
		add_action( 'wp_ajax_platform_helm_gsc_sync',       [ $this, 'ajax_sync' ] );
		add_action( 'wp_ajax_platform_helm_gsc_disconnect', [ $this, 'ajax_disconnect' ] );
		add_action( 'wp_ajax_platform_helm_gsc_save_range', [ $this, 'ajax_save_range' ] );
	}

	public function ajax_save_oauth(): void {
		$this->verify();
		$client_id     = isset( $_POST['client_id'] ) ? sanitize_text_field( wp_unslash( (string) $_POST['client_id'] ) ) : '';
		$client_secret = isset( $_POST['client_secret'] ) ? trim( (string) wp_unslash( $_POST['client_secret'] ) ) : ''; // phpcs:ignore WordPress.Security.ValidationSanitization
		if ( '' === $client_id || '' === $client_secret ) {
			wp_send_json_error( [ 'message' => __( 'Enter both the Client ID and Client Secret.', 'platform-helm' ) ], 400 );
		}
		GscCredentials::save_oauth_client( $client_id, $client_secret );
		wp_send_json_success( [ 'auth_url' => GscOAuth::build_auth_url() ] );
	}

	public function ajax_save(): void {
		$this->verify();
		$json     = isset( $_POST['credentials'] ) ? trim( (string) wp_unslash( $_POST['credentials'] ) ) : ''; // phpcs:ignore WordPress.Security.ValidationSanitization
		$property = isset( $_POST['property'] ) ? sanitize_text_field( wp_unslash( (string) $_POST['property'] ) ) : '';
		if ( '' === $json ) {
			wp_send_json_error( [ 'message' => __( 'Paste the service-account key file first.', 'platform-helm' ) ], 400 );
		}
		$saved = GscCredentials::save( $json, $property );
		if ( is_wp_error( $saved ) ) {
			wp_send_json_error( [ 'message' => $saved->get_error_message() ], 400 );
		}
		// Verify by listing sites.
		$sites = $this->client->list_sites();
		if ( is_wp_error( $sites ) ) {
			wp_send_json_error( [ 'message' => $sites->get_error_message() ], 400 );
		}
		wp_send_json_success( [
			'message' => __( 'Connected. Now pick your property and run the first sync.', 'platform-helm' ),
			'email'   => GscCredentials::client_email(),
			'sites'   => $sites,
		] );
	}

	public function ajax_test(): void {
		$this->verify();
		$sites = $this->client->list_sites();
		if ( is_wp_error( $sites ) ) {
			wp_send_json_error( [ 'message' => $sites->get_error_message() ], 400 );
		}
		// If a property is posted, save it.
		if ( isset( $_POST['property'] ) ) {
			$property = sanitize_text_field( wp_unslash( (string) $_POST['property'] ) );
			if ( '' !== $property ) {
				GscCredentials::set_property( $property );
			}
		}
		wp_send_json_success( [
			'message'  => __( 'Connection OK.', 'platform-helm' ),
			'sites'    => $sites,
			'property' => GscCredentials::property(),
		] );
	}

	public function ajax_sync(): void {
		$this->verify();
		$result = $this->sync->run();
		if ( ! $result['ok'] ) {
			wp_send_json_error( [ 'message' => $result['message'] ], 400 );
		}
		// Also refresh the query layer (Refresh Intelligence + Cannibalization).
		$q = $this->sync->run_queries();
		if ( ! empty( $q['ok'] ) && ! empty( $q['rows'] ) ) {
			$result['message'] .= ' ' . sprintf(
				/* translators: %s: number of query rows */
				__( 'Query layer: %s page/query rows cached.', 'platform-helm' ),
				number_format_i18n( (int) $q['rows'] )
			);
		}
		wp_send_json_success( $result );
	}

	public function ajax_disconnect(): void {
		$this->verify();
		GscCredentials::clear();
		wp_send_json_success( [ 'message' => __( 'Disconnected. Cached metrics are kept until you clear them.', 'platform-helm' ) ] );
	}

	public function ajax_save_range(): void {
		$this->verify();
		$days = isset( $_POST['days'] ) ? (int) $_POST['days'] : GscCredentials::DEFAULT_RANGE_DAYS;
		GscCredentials::set_range_days( $days );
		wp_send_json_success( [
			'days'    => GscCredentials::range_days(),
			'message' => sprintf(
				/* translators: %d: number of days */
				__( 'Saved. Each sync will pull the last %d days.', 'platform-helm' ),
				GscCredentials::range_days()
			),
		] );
	}

	private function verify(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );
		Authorization::require_master_admin_ajax();
	}
}
