<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class SmallPict_API_Client {
	private $api_base = SMALLPICT_API_BASE;
	private $session_token;
	private $tenant_id;

	public function __construct( $token = null ) {
		$this->session_token = $token;
	}

	public function set_token( $token ) {
		$this->session_token = $token;
	}

	private function request( $method, $endpoint, $body = null ) {
		$url  = $this->api_base . $endpoint;
		$args = array(
			'method'  => $method,
			'headers' => array(
				'Content-Type'  => 'application/json',
				'Authorization' => 'Bearer ' . $this->session_token,
			),
			'timeout' => 30,
		);

		if ( $body ) {
			$args['body'] = wp_json_encode( $body );
		}

		// Retry Logic (Max 3 attempts)
		$max_retries = 3;
		$attempt     = 0;

		while ( $attempt < $max_retries ) {
			$res = wp_remote_request( $url, $args );

			if ( is_wp_error( $res ) ) {
				return $res;
			}

			$status_code = wp_remote_retrieve_response_code( $res );

			// Success
			if ( $status_code >= 200 && $status_code < 300 ) {
				return json_decode( wp_remote_retrieve_body( $res ), true );
			}

			// Handle Rate Limiting (429) & Server Errors (5xx)
			if ( $status_code == 429 || $status_code >= 500 ) {
				++$attempt;
				if ( $attempt < $max_retries ) {
					// Exponential Backoff: 1s, 2s, 4s
					$sleep_s = pow( 2, $attempt - 1 );
					if ( $status_code == 429 ) {
						// Check Retry-After header
						$retry_after = wp_remote_retrieve_header( $res, 'retry-after' );
						if ( $retry_after ) {
							$sleep_s = max( $sleep_s, (int) $retry_after );
						}
						// Cap at 10s to avoid timeouts
						$sleep_s = min( $sleep_s, 10 );
					}

					// error_log( "SmallPict API: Retry warning (Attempt $attempt) due to status $status_code. Sleeping $sleep_s seconds." );
					sleep( $sleep_s );
					continue;
				}
			}

			// If we are here, it's a client error (4xx excluding 429) or max retries exceeded
			$response_body = json_decode( wp_remote_retrieve_body( $res ), true );
			$error_msg     = isset( $response_body['error'] ) ? $response_body['error'] : 'Unknown API Error';

			// Auth Failure
			if ( $status_code == 401 || $status_code == 403 ) {
				// If it's 401, maybe trigger re-auth hook if possible.
				// For now, logged error is sufficient, caller handles UI.
				// error_log( "SmallPict API Auth Error: Re-authentication may be required." );
			}

			// error_log("SmallPict API Error [$status_code]: " . print_r($response_body, true));

			return new WP_Error(
				'api_error',
				$error_msg,
				array( 'status' => $status_code )
			);
		}

		return new WP_Error( 'api_error', 'Max retries exceeded' );
	}

	public function exchange_auth( $install_id, $token, $domain, $plan = 'free', $is_sandbox = false ) {
		// Bootstrap call - sends Freemius data to backend to get session token
		$res = wp_remote_post(
			$this->api_base . '/auth/exchange',
			array(
				'body'    => wp_json_encode(
					array(
						'install_id' => $install_id,
						'token'      => $token,
						'domain'     => $domain,
						'plan'       => $plan,
						'is_sandbox' => $is_sandbox,
					)
				),
				'headers' => array( 'Content-Type' => 'application/json' ),
			)
		);

		if ( is_wp_error( $res ) ) {
			return $res;
		}

		$body = json_decode( wp_remote_retrieve_body( $res ), true );
		return $body;
	}

	public function request_upload_url( $filename, $mime_type ) {
		return $this->request(
			'POST',
			'/uploads',
			array(
				'filename'     => $filename,
				'content_type' => $mime_type,
			)
		);
	}

	public function submit_job( $job_id, $object_key, $bucket, $options, $client_hints = array() ) {
		return $this->request(
			'POST',
			'/jobs',
			array(
				'job_id'       => $job_id,
				'input'        => array(
					'bucket'     => $bucket,
					'object_key' => $object_key,
				),
				'options'      => $options,
				'client_hints' => $client_hints,
			)
		);
	}

	public function get_job_status( $job_id ) {
		return $this->request( 'GET', '/jobs/' . $job_id );
	}

	public function get_usage() {
		return $this->request( 'GET', '/usage' );
	}
}
