<?php

namespace Simplyin\Simplyin_W_Plugin\Lib\Remote\Sin_Core_Api;

use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Simplyin\Simplyin_W_Plugin\Helper\Log_Sanitizer;
use Simplyin\Simplyin_W_Plugin\Tracking_Numbers;
use WC_Order;

class Simplyin_Api_Legacy_Client {

	protected $simplyin_api_url;
	protected $merchand_api_key;
	protected $version;
	protected $plugin_name;
	protected $saveLogs = false;
	protected $logs = [];
	private $client;

	public function __construct( $plugin_name = '', $version = '' ) {
		$this->plugin_name = $plugin_name;
		$this->version     = $version;

		$this->merchand_api_key = get_option( 'simplyin_api_key' );
		global $simplyin_config;
		// Normalize base URL once on construct to avoid trailing slashes issues
		$this->simplyin_api_url = rtrim( (string) $simplyin_config['backendSimplyIn'],
			'/' );
		if ( in_array( $simplyin_config['environmentVersion'],
			[ "dev", "pp", "st" ] ) ) {
			$this->saveLogs = true;
		}
		$this->client = new Client( [
			'timeout'         => 15,
			'connect_timeout' => 5,
		] );
	}

	public function get_available_payment_methods(): array {

		//$raw = ( new Sample_Response() )->get_sample_response();

		$raw = $this->sendRequest(
			"payments/getAvailablePaymentMethods",
			'GET'
		);


		return $raw;


	}

	public function sendRequest(
		$endpoint,
		$method = 'GET',
		?array $bodyData = null,
		$params = [],
		$merchantApiKey = "",
		$skipMerchantApiKey = false
	) {

		if ( ! empty( $merchantApiKey ) ) {
			$this->merchand_api_key = $merchantApiKey;
		}

		if ( empty( $this->merchand_api_key ) && ! $skipMerchantApiKey ) {
			simplyin()
				->get_simplyin_logger()
				->log_if_wpdebug_on( sprintf( "[SimplyIn_Api] [Bad request. merchand_api_key is empty] %s",
					wp_json_encode( [
						'Endpoint'           => $endpoint,
						'Method'             => $method,
						'BodyData'           => $bodyData,
						'Params'             => $params,
						'skipMerchantApiKey' => $skipMerchantApiKey ? 'yes' : 'no',
					] )

				),
					"api-call" );

			http_response_code( 400 );  // Bad Request

			return '{"status":"failed","messsage":"Error: Simplyin API Key is empty"}';
		}

		$headers = [
			'Content-Type' => 'application/json',
			'Origin'       => home_url(),
		];

		if ( ! $skipMerchantApiKey ) {
			$headers['X-Auth-Merchant-Api-Key'] = $this->merchand_api_key;
			if ( in_array( strtoupper( $method ),
				[ "POST", "PUT", "PATCH" ] ) ) {
				$bodyData['merchantApiKey'] = $this->merchand_api_key;
			}
		}

		$url = $this->build_url( $endpoint );

		simplyin()
			->get_simplyin_logger()
			->log_if_wpdebug_on( "Endpoint: " . $this->build_url( $endpoint,
					$params ),
				"api-call" );

		$options = [
			'headers'     => $headers,
			'query'       => $params,
			'http_errors' => false, // To handle errors manually
		];

		if ( in_array( strtoupper( $method ),
				[ "POST", "PUT", "PATCH" ] ) && $bodyData !== null ) {
			$options['json'] = $bodyData;
		}

		$responseBody         = null;
		$error                = '';
		$exception            = '';
		$response_status_code = '';
		try {
			$response     = $this->client->request( strtoupper( $method ),
				$url,
				$options );
			$responseBody = $response->getBody()->getContents();
			$response->getStatusCode();
			$response_status_code = $response->getStatusCode();
		} catch ( RequestException $e ) {
			$error = $e->getMessage();
			if ( $e->hasResponse() ) {
				$responseBody = $e->getResponse()->getBody()->getContents();
			}
			$exception = $e;
		}

		simplyin()
			->get_simplyin_logger()
			->log_if_wpdebug_on( sprintf( "[SimplyIn_Api] [sendRequest] %s",
				wp_json_encode( Log_Sanitizer::mask( [
					'Endpoint'             => $endpoint,
					'Method'               => $method,
					'API url'              => $this->build_url( $endpoint,
						$params ),
					'Headers'              => $headers,
					'BodyData'             => $bodyData,
					'skipMerchantApiKey'   => $skipMerchantApiKey ? 'yes' : 'no',
					'Response'             => $responseBody,
					'error'                => $error,
					'RequestException'     => wp_json_encode( $exception ),
					'response_status_code' => $response_status_code,
				] ) )

			),
				"api-call" );

		if ( null === $responseBody ) {
			simplyin()
				->get_simplyin_logger()
				->log_if_wpdebug_on(
					sprintf(
						'[SimplyIn_Api] Network error — no response body. Endpoint: %s, Error: %s',
						$endpoint,
						$error ?? 'unknown'
					),
					'api-client'
				);
			return null;
		}

		return json_decode( $responseBody );
	}

	private function log( $message ) {
		$logs   = get_option( "SimplyIn_Api_Logs", [] );
		$logs[] = $message;
		update_option( "SimplyIn_Api_Logs", $logs );
	}


	public function sendEncryptedData( $encrypted_data ) {
		//todo to remove

		global $simplyin_config;
		update_option( 'SimplyIn_Backend_Url',
			$simplyin_config['backendSimplyIn'] );

		$url = $this->build_url( 'encryption/saveEncryptedOrderStatusChange' );

		$headers = [
			'Content-Type' => 'application/json',
			'Origin'       => home_url(),
		];

		try {
			$this->client->post( $url, [
				'headers' => $headers,
				'body'    => $encrypted_data,
			] );
		} catch ( RequestException $e ) {
			// Log error if needed
			simplyin()
				->get_simplyin_logger()
				->log_if_wpdebug_on( sprintf( "[SimplyIn_Api] [sendEncryptedData] [Exception] %s",
					wp_json_encode( $e->getMessage() )
				),
					"api-call" );
		}
	}

	/**
	 * Build full request URL from base and endpoint (and optional params),
	 * cleaning potential double slashes. Normalization lives only here.
	 *
	 * @param string $endpoint
	 * @param array $params
	 *
	 * @return string
	 */
	private function build_url( string $endpoint, array $params = [] ): string {
		$base = rtrim( $this->simplyin_api_url, '/' );
		$path = ltrim( $endpoint, '/' );
		$url  = $base . '/' . $path;

		if ( ! empty( $params ) ) {
			$url .= '?' . http_build_query( $params );
		}

		return $url;
	}

	public function simplyInOnOrderUpdate(
		$old_status,
		$new_status,
		WC_Order $order
	): void {
		$stopStatuses = [
			"processing",
			"pending",
			"on-hold",
			"",
			"cancelled",
			"refunded",
			"failed",
			"checkout-draft",
		];

		$_order_id = $order->get_id(); // Assuming $order is an instance of WC_Order

		simplyin()
			->get_simplyin_logger()
			->log_if_wpdebug_on( sprintf( "[SimplyIn_Api] [simplyInOnOrderUpdate] %s",
				wp_json_encode( [
					'old status' => $old_status,
					'new status' => $new_status,
					'order_id'   => $_order_id,

				] )

			),
				"api-call" );


		$apiKey = get_option( 'simplyin_api_key' );

		$order_data  = $order->get_data();
		$order_email = $order_data['billing']['email'];

		if ( empty( $order_email ) || in_array( $new_status,
				$stopStatuses,
				true ) ) {

			simplyin()
				->get_simplyin_logger()
				->log_if_wpdebug_on( sprintf( "[SimplyIn_Api] [simplyInOnOrderUpdate] [Stop status detected] %s",
					wp_json_encode( [
						'old status' => $old_status,
						'new status' => $new_status,
						'order_id'   => $_order_id,
					] )

				),
					"api-call" );

			return;
		}

		$tracking_numbers = ( new Tracking_Numbers() )->find_tracking_numbers( $order );

		//todo - to DTO
		$body_data = [
			"email"           => $order_email,
			"shopOrderNumber" => $order_data['id'],
			"newOrderStatus"  => $new_status,
			"apiKey"          => $apiKey,
		];

		if ( ! empty( $tracking_numbers ) ) {
			$body_data['trackings'] = $tracking_numbers;
		}


		simplyin()
			->get_simplyin_logger()
			->log_if_wpdebug_on( sprintf( "[SimplyIn_Api] [simplyInOnOrderUpdate] [encrypted body data] %s",
				wp_json_encode( Log_Sanitizer::mask( $body_data ) )

			),
				"api-call" );

		$plaintext = json_encode( $body_data );

		$key = simplyinGetSecretKey( $order_email );

		$encryptedData = simplyinEncrypt( $plaintext, $key );

		$hashedEmail = simplyinHashEmail( $order_email );

		$orderData = [
			"encryptedOrderStatusChangeContent" => $encryptedData,
			"hashedEmail"                       => $hashedEmail,
		];

		//$this->sendEncryptedData( json_encode( $orderData ) );

		try {
			$this->sendRequest( 'encryption/saveEncryptedOrderStatusChange',
				'POST',
				$orderData,
				[],
				'',
				true
			);
		} catch ( Exception $exception ) {
			simplyin()
				->get_simplyin_logger()
				->log_if_wpdebug_on( sprintf( "[SimplyIn_Api] [simplyInOnOrderUpdate] [Exception] %s",
					wp_json_encode( $exception->getMessage() )

				),
					"api-call" );

		}

	}
}
