<?php
/**
 * Base Controller for Content Generation API
 *
 * Contains shared functionality for all generation controllers:
 * - Permission checks (read/write)
 * - Rate limiting
 * - Input sanitization
 * - Error formatting
 *
 * @package AIPT\Api\BulkGenerator\Desc\Controllers
 * @since 2.5.0
 */

namespace AIPT\Api\BulkGenerator\Desc\Controllers;

use AIPT\Api\Traits\RateLimitTrait;
use WP_Error;
use WP_REST_Request;

/**
 * Abstract base controller with shared methods
 */
abstract class BaseController {
	use RateLimitTrait;

	/**
	 * REST namespace
	 */
	protected const REST_NAMESPACE = 'aipt/v1';

	/**
	 * Register routes - must be implemented by child classes
	 *
	 * @return void
	 */
	abstract public function register_routes();

	/**
	 * Check read permission for GET endpoints
	 *
	 * @return bool True if user has permission
	 */
	public function check_permissions(): bool {
		return current_user_can( 'manage_woocommerce' );
	}

	/**
	 * Check write permission for POST/PUT/DELETE endpoints
	 * Includes nonce verification for additional security
	 *
	 * @param WP_REST_Request $request The REST request object.
	 * @return bool|WP_Error True if user has permission, WP_Error otherwise
	 */
	public function check_permissions_write( $request = null ) {
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
			return new WP_Error(
				'rest_forbidden',
				__( 'You do not have permission to perform this action.', 'ai-product-tools' ),
				array( 'status' => 403 )
			);
		}

		if ( $request instanceof WP_REST_Request ) {
			$nonce = $request->get_header( 'X-WP-Nonce' );
			if ( $nonce && ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
				return new WP_Error(
					'rest_invalid_nonce',
					__( 'Invalid security token. Please refresh the page and try again.', 'ai-product-tools' ),
					array( 'status' => 403 )
				);
			}
		}

		return true;
	}

	/**
	 * Sanitize generation options from request
	 *
	 * @param array $options Raw options from request.
	 * @return array Sanitized options
	 */
	protected function sanitize_generation_options( array $options ): array {
		$sanitized = array();

		$bool_keys = array(
			'generateShortDescription',
			'generateDescription',
			'generateTags',
			'improveExistingDescription',
			'keepExistingDescription',
			'enable_multi_generation',
		);
		foreach ( $bool_keys as $key ) {
			if ( isset( $options[ $key ] ) ) {
				$sanitized[ $key ] = (bool) $options[ $key ];
			}
		}

		$string_keys = array(
			'provider',
			'model',
			'language',
			'writingStyle',
			'writing_style',
			'existingDescriptionPosition',
		);
		foreach ( $string_keys as $key ) {
			if ( isset( $options[ $key ] ) ) {
				$sanitized[ $key ] = sanitize_text_field( $options[ $key ] );
			}
		}

		$int_keys = array(
			'max_length',
			'max_short_length',
			'max_tags_count',
			'additionalTagsCount',
		);
		foreach ( $int_keys as $key ) {
			if ( isset( $options[ $key ] ) ) {
				$sanitized[ $key ] = absint( $options[ $key ] );
			}
		}

		if ( isset( $options['prompts'] ) && is_array( $options['prompts'] ) ) {
			$sanitized['prompts'] = array();
			foreach ( array( 'short', 'full' ) as $type ) {
				if ( isset( $options['prompts'][ $type ] ) && is_array( $options['prompts'][ $type ] ) ) {
					$sanitized['prompts'][ $type ] = array();
					if ( isset( $options['prompts'][ $type ]['system_prompt'] ) ) {
						$sanitized['prompts'][ $type ]['system_prompt'] = sanitize_textarea_field(
							$options['prompts'][ $type ]['system_prompt']
						);
					}
					if ( isset( $options['prompts'][ $type ]['user_prompt'] ) ) {
						$sanitized['prompts'][ $type ]['user_prompt'] = sanitize_textarea_field(
							$options['prompts'][ $type ]['user_prompt']
						);
					}
				}
			}
		}

		if ( isset( $options['beforeContentText'] ) ) {
			$sanitized['beforeContentText'] = sanitize_text_field( $options['beforeContentText'] );
		}
		if ( isset( $options['afterContentText'] ) ) {
			$sanitized['afterContentText'] = sanitize_text_field( $options['afterContentText'] );
		}

		return $sanitized;
	}

	/**
	 * Format API error message with provider information
	 *
	 * @param string $provider      API provider name (OpenAI, Gemini).
	 * @param string $error_message Error message.
	 * @return string Formatted error message
	 */
	protected function format_api_error_message( string $provider, string $error_message ): string {
		return \AIPT\Core\ErrorHandler::format_api_error_message( $provider, $error_message );
	}

	/**
	 * Create a success response
	 *
	 * @param array  $data    Response data.
	 * @param string $message Optional success message.
	 * @return \WP_REST_Response
	 */
	protected function success_response( array $data, string $message = '' ): \WP_REST_Response {
		$response = array(
			'success' => true,
			'data'    => $data,
		);

		if ( ! empty( $message ) ) {
			$response['message'] = $message;
		}

		return new \WP_REST_Response( $response, 200 );
	}

	/**
	 * Create an error response
	 *
	 * @param string $code    Error code.
	 * @param string $message Error message.
	 * @param int    $status  HTTP status code.
	 * @return WP_Error
	 */
	protected function error_response( string $code, string $message, int $status = 400 ): WP_Error {
		return new WP_Error( $code, $message, array( 'status' => $status ) );
	}

	/**
	 * Extract content types from options array
	 *
	 * @param array $options Options with generation flags.
	 * @return array Content types to generate
	 */
	protected function extract_content_types( array $options ): array {
		$types = array();

		if ( ! empty( $options['generateShortDescription'] ) ) {
			$types[] = 'short_description';
		}
		if ( ! empty( $options['generateDescription'] ) ) {
			$types[] = 'description';
		}
		if ( ! empty( $options['generateTags'] ) ) {
			$types[] = 'tags';
		}

		return $types;
	}
}
