<?php
/**
 * Content Controller - Handles history and approval operations
 *
 * Consolidated from ApprovalController + HistoryController (old)
 * Routes: /history, /apply, /approve, /reject, /delete, bulk operations
 *
 * @package AIPT\Api\BulkGenerator\Desc\Controllers
 * @since 2.5.0
 */

namespace AIPT\Api\BulkGenerator\Desc\Controllers;

use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use AIPT\Api\BulkGenerator\Desc\ContentGenerator;
use AIPT\Api\BulkGenerator\Desc\Core\ProductDataProvider;
use AIPT\Api\BulkGenerator\Common\DatabaseManager;

class ContentController extends BaseController {

	private ContentGenerator $generator;
	private DatabaseManager $db;

	public function __construct( ?ContentGenerator $generator = null, ?DatabaseManager $db = null ) {
		$this->generator = $generator ?? new ContentGenerator();
		$this->db        = $db ?? new DatabaseManager();
	}

	public function register_routes(): void {
		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/history',
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => array( $this, 'get_history' ),
				'permission_callback' => array( $this, 'check_permissions' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/apply',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'apply_content' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/bulk-apply',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'bulk_apply' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/approve-description',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'approve_description' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/reject-description',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'reject_description' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/bulk-approve',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'bulk_approve' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/bulk-reject',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'bulk_reject' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/delete-history-item',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'delete_history_item' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/bulk-delete',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'bulk_delete' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/delete-all-history',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'delete_all_history' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
			)
		);

		register_rest_route(
			self::REST_NAMESPACE . '/description-generator',
			'/cancel',
			array(
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'cancel_generation' ),
				'permission_callback' => array( $this, 'check_permissions_write' ),
				'args'                => array(
					'history_id' => array(
						'required'          => true,
						'sanitize_callback' => 'absint',
					),
				),
			)
		);
	}

	public function get_history(): WP_REST_Response {
		$history = $this->db->get_history_items();

		if ( empty( $history ) ) {
			return new WP_REST_Response( array(), 200 );
		}

		$product_ids   = array_unique( array_column( $history, 'product_id' ) );
		$products_data = ProductDataProvider::bulkGet( $product_ids, false );

		$formatted = array();
		foreach ( $history as $item ) {
			$product_id    = (int) $item['product_id'];
			$product_data  = $products_data[ $product_id ] ?? null;
			$product_name  = $product_data ? $product_data['name'] : __( 'Unknown Product', 'ai-product-tools' );
			$product_image = $product_data ? $product_data['image'] : wc_placeholder_img_src( 'thumbnail' );

			$formatted[] = array(
				'id'               => (int) $item['id'],
				'product_id'       => $product_id,
				'product_name'     => $product_name,
				'product_image'    => $product_image,
				'description_type' => $item['description_type'],
				'generated_text'   => $item['generated_text'] ?? '',
				'status'           => $item['status'],
				'created_at'       => $item['created_at'],
				'updated_at'       => $item['updated_at'] ?? null,
			);
		}

		return new WP_REST_Response( $formatted, 200 );
	}

	public function apply_content( WP_REST_Request $request ): WP_REST_Response {
		$data       = $request->get_json_params();
		$product_id = absint( $data['product_id'] ?? 0 );
		$type       = sanitize_text_field( $data['description_type'] ?? '' );
		$content    = wp_kses_post( $data['description'] ?? '' );
		$options    = $this->sanitize_generation_options( $data['options'] ?? array() );

		if ( ! $product_id || ! $type || empty( $content ) ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'Missing required fields', 'ai-product-tools' ) ),
				400
			);
		}

		$internal_type = $this->map_db_type_to_internal( $type );
		$result        = $this->generator->applyContent( $product_id, array( $internal_type => $content ), $options );

		if ( $result ) {
			$this->db->delete_history_items(
				array(
					'product_id'       => $product_id,
					'description_type' => $type,
					'status'           => 'pending',
				)
			);

			return new WP_REST_Response(
				array( 'success' => true, 'message' => __( 'Content applied successfully', 'ai-product-tools' ) ),
				200
			);
		}

		return new WP_REST_Response(
			array( 'success' => false, 'message' => __( 'Failed to apply content', 'ai-product-tools' ) ),
			500
		);
	}

	public function bulk_apply( WP_REST_Request $request ): WP_REST_Response {
		$data    = $request->get_json_params();
		$results = $data['results'] ?? array();
		$options = $this->sanitize_generation_options( $data['options'] ?? array() );

		if ( empty( $results ) ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'No content to apply', 'ai-product-tools' ) ),
				400
			);
		}

		$success_count = 0;
		$errors        = array();

		foreach ( $results as $item ) {
			$product_id = absint( $item['product_id'] ?? 0 );
			$type       = sanitize_text_field( $item['type'] ?? '' );
			$content    = wp_kses_post( $item['text'] ?? '' );
			$status     = $item['status'] ?? 'pending';

			if ( ! $product_id || ! $type || empty( $content ) ) {
				continue;
			}

			if ( 'rejected' === $status ) {
				$this->db->update_history_status(
					array( 'product_id' => $product_id, 'description_type' => $type ),
					'rejected'
				);
				continue;
			}

			$internal_type = $this->map_db_type_to_internal( $type );
			$result        = $this->generator->applyContent( $product_id, array( $internal_type => $content ), $options );

			if ( $result ) {
				$this->db->delete_history_items(
					array(
						'product_id'       => $product_id,
						'description_type' => $type,
						'status'           => 'pending',
					)
				);
				$success_count++;
			} else {
				/* translators: %d: product ID */
				$errors[] = sprintf( __( 'Failed to apply for product #%d', 'ai-product-tools' ), $product_id );
			}
		}

		return new WP_REST_Response(
			array(
				'success' => true,
				'message' => sprintf(
					/* translators: %d: number of items applied */
					__( '%d item(s) applied successfully', 'ai-product-tools' ),
					$success_count
				),
				'applied_count' => $success_count,
				'errors'        => $errors,
			),
			200
		);
	}

	public function approve_description( WP_REST_Request $request ): WP_REST_Response {

		$json_params = $request->get_json_params();

		$product_id  = absint( $json_params['product_id'] ?? $request->get_param( 'product_id' ) ?? 0 );
		$type        = sanitize_text_field( $json_params['description_type'] ?? $request->get_param( 'description_type' ) ?? '' );
		$content     = wp_kses_post( $json_params['description'] ?? $request->get_param( 'description' ) ?? '' );
		$raw_options = $json_params['options'] ?? $request->get_param( 'options' ) ?? array();
		$options     = is_array( $raw_options ) ? $this->sanitize_generation_options( $raw_options ) : array();

		$id          = absint( $json_params['id'] ?? $request->get_param( 'id' ) ?? 0 );

		if ( ! $product_id ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'Product ID is required', 'ai-product-tools' ) ),
				400
			);
		}

		if ( empty( $type ) || ! in_array( $type, array( 'short', 'full', 'tags' ), true ) ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'Valid description type is required (short, full, or tags)', 'ai-product-tools' ) ),
				400
			);
		}

		if ( empty( $content ) ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'Description content is required', 'ai-product-tools' ) ),
				400
			);
		}

		$internal_type = $this->map_db_type_to_internal( $type );
		$result        = $this->generator->applyContent( $product_id, array( $internal_type => $content ), $options );

		if ( $result ) {

			$where = $id > 0
				? array( 'id' => $id, 'product_id' => $product_id, 'description_type' => $type )
				: array( 'product_id' => $product_id, 'description_type' => $type );
			$this->db->update_history_status( $where, 'approved' );

			$this->record_usage_event(
				'advanced_desc',
				'approved',
				1,
				array( 'product_id' => $product_id )
			);

			return new WP_REST_Response(
				array( 'success' => true, 'message' => __( 'Description approved and applied', 'ai-product-tools' ) ),
				200
			);
		}

		return new WP_REST_Response(
			array( 'success' => false, 'message' => __( 'Failed to approve description', 'ai-product-tools' ) ),
			500
		);
	}

	public function reject_description( WP_REST_Request $request ): WP_REST_Response {
		$json_params = $request->get_json_params();
		$product_id  = absint( $json_params['product_id'] ?? $request->get_param( 'product_id' ) ?? 0 );
		$type        = sanitize_text_field( $json_params['description_type'] ?? $request->get_param( 'description_type' ) ?? '' );

		if ( ! $product_id || empty( $type ) ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'Product ID and description type are required', 'ai-product-tools' ) ),
				400
			);
		}

		$result = $this->db->update_history_status(
			array( 'product_id' => $product_id, 'description_type' => $type ),
			'rejected'
		);

		if ( false !== $result ) {
			$this->record_usage_event(
				'advanced_desc',
				'rejected',
				1,
				array( 'product_id' => $product_id )
			);

			return new WP_REST_Response(
				array( 'success' => true, 'message' => __( 'Description rejected', 'ai-product-tools' ) ),
				200
			);
		}

		return new WP_REST_Response(
			array( 'success' => false, 'message' => __( 'Failed to reject description', 'ai-product-tools' ) ),
			500
		);
	}

	public function bulk_approve( WP_REST_Request $request ): WP_REST_Response {
		$data  = $request->get_json_params();
		$items = $data['items'] ?? array();

		if ( empty( $items ) ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'No items to approve', 'ai-product-tools' ) ),
				400
			);
		}

		$raw_options = $data['options'] ?? array();
		$options     = is_array( $raw_options ) ? $this->sanitize_generation_options( $raw_options ) : array();

		$success_count       = 0;
		$first_approved_pid  = 0;
		$errors              = array();

		foreach ( $items as $item ) {
			$product_id = absint( $item['product_id'] ?? 0 );
			$type       = sanitize_text_field( $item['description_type'] ?? '' );
			$content    = wp_kses_post( $item['description'] ?? '' );

			if ( ! $product_id || ! $type || empty( $content ) ) {
				continue;
			}

			$internal_type = $this->map_db_type_to_internal( $type );
			$result        = $this->generator->applyContent( $product_id, array( $internal_type => $content ), $options );

			if ( $result ) {
				$this->db->update_history_status(
					array( 'product_id' => $product_id, 'description_type' => $type ),
					'approved'
				);
				$success_count++;
				if ( 0 === $first_approved_pid ) {
					$first_approved_pid = $product_id;
				}
			} else {
				/* translators: %d: product ID */
				$errors[] = sprintf( __( 'Failed to approve for product #%d', 'ai-product-tools' ), $product_id );
			}
		}

		if ( $success_count > 0 ) {
			$this->record_usage_event(
				'advanced_desc',
				'approved',
				$success_count,
				array( 'product_id' => $first_approved_pid )
			);
		}

		return new WP_REST_Response(
			array(
				'success'        => true,
				/* translators: %d: number of items approved */
				'message'        => sprintf( __( '%d item(s) approved', 'ai-product-tools' ), $success_count ),
				'approved_count' => $success_count,
				'errors'         => $errors,
			),
			200
		);
	}

	public function bulk_reject( WP_REST_Request $request ): WP_REST_Response {
		$data    = $request->get_json_params();
		$results = $data['results'] ?? array();

		if ( empty( $results ) ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'No items to reject', 'ai-product-tools' ) ),
				400
			);
		}

		$success_count       = 0;
		$first_rejected_pid  = 0;

		foreach ( $results as $item ) {
			$product_id = absint( $item['product_id'] ?? 0 );
			$type       = sanitize_text_field( $item['description_type'] ?? '' );

			if ( ! $product_id || ! $type ) {
				continue;
			}

			$result = $this->db->update_history_status(
				array( 'product_id' => $product_id, 'description_type' => $type ),
				'rejected'
			);

			if ( false !== $result ) {
				$success_count++;
				if ( 0 === $first_rejected_pid ) {
					$first_rejected_pid = $product_id;
				}
			}
		}

		if ( $success_count > 0 ) {
			$this->record_usage_event(
				'advanced_desc',
				'rejected',
				$success_count,
				array( 'product_id' => $first_rejected_pid )
			);
		}

		return new WP_REST_Response(
			array(
				'success'        => true,
				/* translators: %d: number of items rejected */
				'message'        => sprintf( __( '%d item(s) rejected', 'ai-product-tools' ), $success_count ),
				'rejected_count' => $success_count,
			),
			200
		);
	}

	public function delete_history_item( WP_REST_Request $request ): WP_REST_Response {
		$json_params = $request->get_json_params();
		$product_id  = absint( $json_params['product_id'] ?? $request->get_param( 'product_id' ) ?? 0 );
		$type        = sanitize_text_field( $json_params['description_type'] ?? $request->get_param( 'description_type' ) ?? '' );

		$id          = absint( $json_params['id'] ?? $request->get_param( 'id' ) ?? 0 );

		if ( ! $product_id || empty( $type ) ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'Product ID and description type are required', 'ai-product-tools' ) ),
				400
			);
		}

		$where  = $id > 0
			? array( 'id' => $id, 'product_id' => $product_id, 'description_type' => $type )
			: array( 'product_id' => $product_id, 'description_type' => $type );
		$result = $this->db->delete_history_items( $where );

		if ( false !== $result ) {
			return new WP_REST_Response(
				array( 'success' => true, 'message' => __( 'Item deleted', 'ai-product-tools' ) ),
				200
			);
		}

		return new WP_REST_Response(
			array( 'success' => false, 'message' => __( 'Failed to delete item', 'ai-product-tools' ) ),
			500
		);
	}

	public function bulk_delete( WP_REST_Request $request ): WP_REST_Response {
		$data  = $request->get_json_params();
		$items = $data['items'] ?? array();

		if ( empty( $items ) ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'No items to delete', 'ai-product-tools' ) ),
				400
			);
		}

		$success_count = 0;

		foreach ( $items as $item ) {
			$product_id = absint( $item['product_id'] ?? 0 );
			$type       = sanitize_text_field( $item['description_type'] ?? '' );

			if ( ! $product_id || ! $type ) {
				continue;
			}

			$result = $this->db->delete_history_items(
				array( 'product_id' => $product_id, 'description_type' => $type )
			);

			if ( $result ) {
				$success_count++;
			}
		}

		return new WP_REST_Response(
			array(
				'success'       => true,
				/* translators: %d: number of items deleted */
				'message'       => sprintf( __( '%d item(s) deleted', 'ai-product-tools' ), $success_count ),
				'deleted_count' => $success_count,
			),
			200
		);
	}

	public function delete_all_history(): WP_REST_Response {
		$result = $this->db->truncate_history_table();

		if ( false !== $result ) {
			return new WP_REST_Response(
				array( 'success' => true, 'message' => __( 'All history deleted', 'ai-product-tools' ) ),
				200
			);
		}

		return new WP_REST_Response(
			array( 'success' => false, 'message' => __( 'Failed to delete history', 'ai-product-tools' ) ),
			500
		);
	}

	public function cancel_generation( WP_REST_Request $request ): WP_REST_Response {
		$history_id = absint( $request->get_param( 'history_id' ) );

		if ( ! $history_id ) {
			return new WP_REST_Response(
				array( 'success' => false, 'message' => __( 'Invalid history ID', 'ai-product-tools' ) ),
				400
			);
		}

		$result = $this->db->update_history_status(
			array( 'id' => $history_id ),
			'rejected'
		);

		if ( false !== $result ) {
			return new WP_REST_Response(
				array( 'success' => true, 'message' => __( 'Generation cancelled', 'ai-product-tools' ) ),
				200
			);
		}

		return new WP_REST_Response(
			array( 'success' => false, 'message' => __( 'Failed to cancel generation', 'ai-product-tools' ) ),
			500
		);
	}

	private function map_db_type_to_internal( string $type ): string {
		$mapping = array(
			'short' => 'short_description',
			'full'  => 'description',
			'tags'  => 'tags',
		);

		return $mapping[ $type ] ?? $type;
	}

	/**
	 * Record usage telemetry without breaking the approval workflow.
	 *
	 * @param string $feature Feature identifier.
	 * @param string $action  Action identifier.
	 * @param int    $count   Event count.
	 * @param array  $meta    Event metadata.
	 * @return void
	 */
	private function record_usage_event( string $feature, string $action, int $count, array $meta ): void {
		try {
			\AIPT\Core\Services\UsageTracker::record_event( $feature, $action, $count, $meta );
		} catch ( \Throwable $throwable ) {
			do_action( 'aipt_usage_tracking_failed', $throwable, $feature, $action, $count, $meta );
		}
	}
}
