<?php
/**
 * Sync Service for Context Awareness.
 *
 * @package Replyan_AI
 */

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

class Replyan_AI_Sync_Service {

	private Replyan_AI_Source_Manager    $source_manager;
	private Replyan_AI_Content_Cleaner   $cleaner;
	private Replyan_AI_Content_Chunker   $chunker;
	private Replyan_AI_Embedding_Service $embedding_service;
	private Replyan_AI_Vector_Storage    $storage;

	public function __construct() {
		$this->source_manager    = new Replyan_AI_Source_Manager();
		$this->cleaner           = new Replyan_AI_Content_Cleaner();
		$this->chunker           = new Replyan_AI_Content_Chunker();
		$this->embedding_service = new Replyan_AI_Embedding_Service();
		$this->storage           = new Replyan_AI_Vector_Storage();
	}

	/**
	 * Validates the configuration.
	 *
	 * @throws Exception If validation fails.
	 */
	public function validate(): void {
		$settings = Replyan_AI_Settings::get();

		if ( empty( $settings['knowledge_sources'] ) ) {
			throw new Exception( 'Please select at least one knowledge source.' );
		}

		if ( empty( $settings['embedding_provider'] ) ) {
			throw new Exception( 'Please configure an embedding provider before syncing.' );
		}

		if ( empty( $settings['embedding_model'] ) ) {
			throw new Exception( 'Please configure an embedding model before syncing.' );
		}
	}

	/**
	 * Retrieves all documents to process.
	 *
	 * @return array
	 */
	public function get_documents(): array {
		return $this->source_manager->getDocuments();
	}

	/**
	 * Processes a single document.
	 *
	 * @param array $document The document array from Source Provider.
	 * @return array Process result.
	 */
	public function process_document( array $document ): array {
		try {
			$clean_content = $this->cleaner->clean( $document['content'] );
			
			// Generate SHA-256 hash of the cleaned content and title
			$checksum = hash( 'sha256', $document['title'] . $clean_content );

			if ( $this->storage->is_unchanged( $document['source_id'], $checksum ) ) {
				return array(
					'status'  => 'skipped',
					'message' => 'Document unchanged.',
				);
			}

			$chunks = $this->chunker->chunk( $clean_content );

			// Clear existing chunks for this document
			$this->storage->delete_chunks( $document['source_id'] );

			$processed_chunks = 0;

			foreach ( $chunks as $index => $chunk_text ) {
				$embedding   = $this->embedding_service->generate( $chunk_text );
				$token_count = $this->chunker->estimate_tokens( $chunk_text );

				$this->storage->save_chunk( array(
					'post_id'     => $document['source_id'],
					'chunk_index' => $index,
					'post_type'   => $document['source_type'],
					'title'       => $document['title'],
					'url'         => $document['url'],
					'content'     => $chunk_text,
					'embedding'   => $embedding,
					'token_count' => $token_count,
					'checksum'    => $checksum,
				) );

				$processed_chunks++;
			}

			return array(
				'status'  => 'success',
				'chunks'  => $processed_chunks,
				'message' => 'Processed ' . $processed_chunks . ' chunks.',
			);
		} catch ( Exception $e ) {
			return array(
				'status'  => 'error',
				'message' => $e->getMessage(),
			);
		}
	}
}
