<?php
/**
 * GSC Connector Module.
 *
 * Connects to Google Search Console via a service account and caches
 * per-post Search Analytics locally on a daily cron. The Content Auditor
 * (separate module) reads that cache to make traffic-aware decisions.
 *
 *   - Auth: service-account JWT (no Google SDK) — see GscClient.
 *   - Storage: a small custom table — see GscStore.
 *   - Sync: daily cron + manual — see GscSync.
 *   - UI: Tools → Search Console — see GscSettingsPage.
 *
 * @package Platform\Helm\Modules\GSC
 */

declare( strict_types = 1 );

namespace Platform\Helm\Modules\GSC;

use Platform\Helm\Contracts\ModuleInterface;
use Platform\Helm\Core\Assets;

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

final class GscModule implements ModuleInterface {

	public const SYNC_CRON_HOOK = 'platform_helm_gsc_daily_sync';

	private GscStore $store;
	private GscQueryStore $query_store;
	private GscSnapshotStore $snapshots;
	private GscIndexStore $index_store;
	private GscSync $sync;
	private GscAjaxController $ajax;
	private GscSettingsPage $settings_page;
	private GscCannibalizationPage $cannibal_page;
	private GscMonitorPage $monitor_page;
	private GscIndexPage $index_page;
	private GscOffBrandPage $offbrand_page;
	private GscContentGapPage $content_gap_page;
	private GscOAuth $oauth;

	public function __construct( Assets $assets ) {
		$client              = new GscClient();
		$this->store         = new GscStore();
		$this->query_store   = new GscQueryStore();
		$this->snapshots     = new GscSnapshotStore();
		$this->index_store   = new GscIndexStore();
		$this->sync          = new GscSync( $client, $this->store, $this->query_store, $this->snapshots );
		$this->ajax          = new GscAjaxController( $client, $this->sync );
		$this->settings_page = new GscSettingsPage( $assets, $this->store );
		$this->cannibal_page = new GscCannibalizationPage( $assets, $this->query_store );
		$this->monitor_page  = new GscMonitorPage( $assets, $this->snapshots );
		$this->index_page    = new GscIndexPage( $assets, $this->index_store, new GscIndexChecker( $client, $this->index_store ) );
		$this->offbrand_page = new GscOffBrandPage( $assets, $this->store, $this->query_store );
		$this->content_gap_page = new GscContentGapPage( $assets, $this->query_store );
		$this->oauth         = new GscOAuth();
	}

	public function id(): string {
		return 'gsc_connector';
	}

	public function name(): string {
		return __( 'Search Console Connector', 'platform-helm' );
	}

	public function description(): string {
		return __( 'Connects to Google Search Console via a service account and caches per-post traffic locally on a daily cron, ready for the Content Auditor. Lean: no live API calls during normal browsing.', 'platform-helm' );
	}

	public function default_enabled(): bool {
		return false;
	}

	public function boot(): void {
		$this->store->maybe_create_table();
		$this->query_store->maybe_create_table();
		$this->snapshots->maybe_create_table();
		$this->index_store->maybe_create_table();
		$this->settings_page->register_hooks();
		$this->cannibal_page->register_hooks();
		$this->monitor_page->register_hooks();
		$this->index_page->register_hooks();
		$this->offbrand_page->register_hooks();
		$this->content_gap_page->register_hooks();
		$this->ajax->register_hooks();
		$this->oauth->register_hooks();

		add_action( self::SYNC_CRON_HOOK, [ $this, 'run_daily_sync' ] );
		if ( ! wp_next_scheduled( self::SYNC_CRON_HOOK ) ) {
			// Spread off business hours; cron fires on the next visit after due.
			wp_schedule_event( time() + HOUR_IN_SECONDS, 'daily', self::SYNC_CRON_HOOK );
		}
	}

	public function run_daily_sync(): void {
		if ( ! GscCredentials::is_connected() ) {
			return;
		}
		$this->sync->run();
		$this->sync->run_queries();
	}
}
