<?php

namespace CelerSearch\Factories;

use CelerSearch\Indices\BaseIndex;
use CelerSearch\Indices\OrdersIndex;
use CelerSearch\Indices\PostsIndex;
use CelerSearch\Indices\ProductsIndex;
use CelerSearch\Observers\BaseObserver;
use CelerSearch\Observers\OrderChangesObserver;
use CelerSearch\Observers\PostChangesObserver;
use CelerSearch\Repositories\IndexRepository;
use CelerSearch\Utilities\Logger;

class ObserverFactory {

	/**
	 * Create appropriate observer for an index
	 *
	 * @param BaseIndex $index The index to observe.
	 *
	 * @return BaseObserver|null
	 */
	public static function create_for_index( BaseIndex $index ): ?BaseObserver {
		$observer = null;

		// PostsIndex and ProductsIndex both observe post changes
		if ( $index instanceof PostsIndex || $index instanceof ProductsIndex ) {
			$observer = new PostChangesObserver( $index );
		}

		// OrdersIndex uses HPOS-compatible WooCommerce hooks
		if ( $index instanceof OrdersIndex ) {
			$observer = new OrderChangesObserver( $index );
		}

		// Future: TermsIndex → TermChangesObserver
		// Future: UsersIndex → UserChangesObserver

		// Allow plugins to provide custom observers for custom index types
		return apply_filters( 'celersearch_observer_for_index', $observer, $index );
	}

	/**
	 * Create observers for all active indices
	 *
	 * @return BaseObserver[]
	 */
	public static function create_all(): array {
		// Check if real-time sync is enabled
		if ( ! self::is_real_time_sync_enabled() ) {
			return [];
		}

		$observers  = [];
		$repository = new IndexRepository();

		// Get all indices (use high per_page to get all)
		$indices = $repository->get( [], 1, 1000 );

		foreach ( $indices as $index_config ) {
			try {
				$index    = IndexFactory::create( $index_config->getId() );
				$observer = self::create_for_index( $index );

				if ( $observer ) {
					$observers[] = $observer;
				}
			} catch ( \Exception $e ) {
				Logger::channel( Logger::CHANNEL_ERRORS )->error( 'Failed to create observer for index', [
					'index_id'  => $index_config->getId(),
					'exception' => $e->getMessage(),
				] );
			}
		}

		return $observers;
	}

	/**
	 * Check if real-time sync is enabled
	 *
	 * @return bool
	 */
	private static function is_real_time_sync_enabled(): bool {
		$settings = get_option( 'celersearch_settings', [] );

		// Default to enabled if not explicitly disabled
		$enabled = $settings['real_time_sync']['enabled'] ?? true;

		return apply_filters( 'celersearch_real_time_sync_enabled', $enabled );
	}
}
