<?php

namespace WeDevs\Wpuf\Pro\AI_Review\Providers;

use WeDevs\Wpuf\Pro\AI_Review\Interfaces\Provider_Interface;

/**
 * Abstract AI Provider
 *
 * Base class for all AI provider implementations
 *
 * @since 4.2.9
 */
abstract class Abstract_Provider implements Provider_Interface {

	/**
	 * API endpoint
	 *
	 * @var string
	 */
	protected $endpoint;

	/**
	 * API key
	 *
	 * @var string
	 */
	protected $api_key;

	/**
	 * Model to use
	 *
	 * @var string
	 */
	protected $model;

	/**
	 * Timeout for API requests
	 *
	 * @var int
	 */
	protected $timeout = 30;

	/**
	 * Max tokens for response
	 *
	 * @var int
	 */
	protected $max_tokens = 500;

	/**
	 * Temperature for response
	 *
	 * @var float
	 */
	protected $temperature = 0.3;

	/**
	 * Constructor
	 *
	 * @since 4.2.9
	 *
	 * @param string $endpoint API endpoint
	 * @param string $api_key  API key
	 * @param string $model    Model to use
	 */
	public function __construct( $endpoint, $api_key, $model ) {
		$this->endpoint = $endpoint;
		$this->api_key  = $api_key;
		$this->model    = $model;
	}

	/**
	 * Make API call to the AI provider
	 *
	 * @since 4.2.9
	 *
	 * @param string $endpoint API endpoint
	 * @param string $api_key  API key
	 * @param string $model    Model to use
	 * @param string $prompt   Review prompt
	 * @return string API response
	 * @throws \Exception
	 */
	abstract public function make_api_call( $endpoint, $api_key, $model, $prompt );

	/**
	 * Validate API key format
	 *
	 * @since 4.2.9
	 *
	 * @param string $api_key API key to validate
	 * @return bool True if valid format
	 */
	abstract public function validate_api_key( $api_key );

	/**
	 * Make HTTP request with retry logic
	 *
	 * @since 4.2.9
	 *
	 * @param string $url  Request URL
	 * @param array  $args Request arguments
	 * @return array Response data
	 * @throws \Exception
	 */
	protected function make_request( $url, $args ) {
		$max_retries = 3;
		$retry_delay = 1;

		for ( $attempt = 1; $attempt <= $max_retries; $attempt++ ) {
			$response = wp_remote_post( $url, array_merge( $args, [ 'timeout' => $this->timeout ] ) );

			if ( is_wp_error( $response ) ) {
				$error_code = $response->get_error_code();

				// Retry on specific errors
				if ( $attempt < $max_retries && in_array( $error_code, [ 'http_request_failed', 'timeout', 'connection_failed' ], true ) ) {
					sleep( $retry_delay * $attempt );
					continue;
				}

				throw new \Exception( 'API error: ' . $response->get_error_message() );
			}

			$status_code = wp_remote_retrieve_response_code( $response );

			// Handle rate limiting
			if ( $status_code === 429 ) {
				$body = wp_remote_retrieve_body( $response );
				$decoded = json_decode( $body, true );

				if ( $attempt < $max_retries ) {
					$retry_after = isset( $decoded['error']['retry_after'] ) ? (int) $decoded['error']['retry_after'] : $retry_delay * $attempt;
					sleep( $retry_after );
					continue;
				}

				throw new \Exception( 'API rate limit exceeded. Please try again later.' );
			}

			// Handle server errors
			if ( $status_code >= 500 && $attempt < $max_retries ) {
				sleep( $retry_delay * $attempt );
				continue;
			}

			return $response;
		}

		throw new \Exception( 'API failed after ' . $max_retries . ' attempts' );
	}

	/**
	 * Get request headers
	 *
	 * @since 4.2.9
	 *
	 * @return array Request headers
	 */
	abstract protected function get_request_headers();

	/**
	 * Parse response from API
	 *
	 * @since 4.2.9
	 *
	 * @param string $response_body Response body
	 * @return string Parsed response content
	 * @throws \Exception
	 */
	abstract protected function parse_response( $response_body );

	/**
	 * Build request body
	 *
	 * @since 4.2.9
	 *
	 * @param string $prompt Review prompt
	 * @return array Request body
	 */
	abstract protected function build_request_body( $prompt );
}
