<?php

namespace Limb_Chatbot\Includes\Services\Automations;

use Limb_Chatbot\Includes\Data_Objects\Dataset;
use Limb_Chatbot\Includes\Data_Objects\Dataset_Meta;
use Limb_Chatbot\Includes\Repositories\Vector_Index_Repository;
use Limb_Chatbot\Includes\Services\Dataset_Service;
use Limb_Chatbot\Includes\Services\Helper;
use Limb_Chatbot\Includes\Services\Vector_Index_Service;

/**
 * Handles dataset cleanup when a post is deleted.
 *
 * Removes all associated datasets and entries when a post is deleted.
 *
 * @since 1.0.11
 */
class Post_Deletion_Handler {

	/**
	 * Dataset service.
	 *
	 * @var Dataset_Service
	 * @since 1.0.11
	 */
	private Dataset_Service $dataset_service;

	/**
	 * Constructor.
	 *
	 * @param  Dataset_Service  $dataset_service  Dataset service instance.
	 *
	 * @since 1.0.11
	 */
	public function __construct( Dataset_Service $dataset_service ) {
		$this->dataset_service = $dataset_service;
	}

	/**
	 * Handle post deletion by cleaning up associated datasets.
	 *
	 * When a post is deleted, all datasets created from this post are deleted,
	 * along with their entries and metadata.
	 *
	 * @param  int  $post_id  Post ID.
	 * @param  \WP_Post  $post  The post object.
	 *
	 * @return void
	 * @since 1.0.11
	 */
	public function handle( int $post_id, \WP_Post $post ): void {
		try {
			// Find all datasets for this post
			$datasets = $this->find_post_datasets( $post );

			if ( empty( $datasets ) ) {
				return;
			}

			// Delete each dataset and its entries
			foreach ( $datasets as $dataset ) {
				if ( $dataset instanceof Dataset ) {
					try {
						$this->delete_dataset( $dataset );
					} catch ( \Exception $e ) {
						Helper::log( $e );
					}
				}
			}
		} catch ( \Exception $e ) {
			Helper::log( $e );
		}
	}

	/**
	 * Find all datasets for a post.
	 *
	 * @param  \WP_Post  $post  The post object.
	 *
	 * @return array<Dataset> Array of datasets for this post.
	 * @since 1.0.11
	 */
	private function find_post_datasets( \WP_Post $post ): array {
		try {
			$criteria = [
				'source_type'     => [ Dataset::SOURCE_POST, Dataset::SOURCE_CPT ],
				'source_sub_type' => $post->post_type,
				'source'          => $post->ID,
			];

			$datasets = Dataset::where( $criteria );
			$results  = [];

			if ( ! $datasets->is_empty() ) {
				foreach ( $datasets->get() as $dataset ) {
					if ( $dataset instanceof Dataset ) {
						$results[] = $dataset;
					}
				}
			}

			return $results;
		} catch ( \Exception $e ) {
			Helper::log( $e );

			return [];
		}
	}

	/**
	 * Delete a dataset and its entries.
	 *
	 * @param  Dataset  $dataset  The dataset to delete.
	 *
	 * @return void
	 * @since 1.0.11
	 */
	private function delete_dataset( Dataset $dataset ): void {
		try {
			// Check if dataset is last in storage and remove vector index if so
			$vector_index_id      = $dataset->is_last_in_storage();
			$vector_index_service = new Vector_Index_Service( new Vector_Index_Repository() );
			if ( $vector_index_id ) {
				$vector_index_service->remove( $vector_index_id );
			}

			// Clear dataset entries (deletes all entries and their vectors)
			$this->dataset_service->clear( $dataset );

			// Delete dataset metadata
			Dataset_Meta::delete( [ 'dataset_id' => $dataset->get_id() ] );

			// Delete the dataset itself
			Dataset::delete( [ 'id' => $dataset->get_id() ] );
		} catch ( \Exception $e ) {
			Helper::log( $e );
		}
	}
}
