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

/**
 * Log in to the MindWebConcierge API and retrieve an access token.
 *
 * @param string $base_url
 * @param string $username
 * @param string $password
 * @return array
 */
function mindweco_plugin_api_login( $base_url, $username, $password ) {
	$url = trailingslashit( esc_url_raw( $base_url ) ) . 'auth/login';

	$response = wp_remote_post( $url, array(
		'body'    => array(
			'username' => sanitize_text_field( $username ),
			'password' => $password,
		),
		'headers' => array(
			'Accept' => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$http_status = wp_remote_retrieve_response_code( $response );
	$body        = wp_remote_retrieve_body( $response );
	$decoded     = json_decode( $body, true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array(
			'error'       => 'Invalid JSON: ' . json_last_error_msg(),
			'raw'         => $body,
			'http_status' => $http_status,
		);
	}

	$decoded['http_status'] = $http_status;
	return $decoded;
}

/**
 * Create a category via the WordPress endpoint.
 *
 * @param string $base_url
 * @param string $token
 * @param string $name
 * @param int    $indexing_id
 * @param string $sitemap_xml
 * @param string $language
 * @param int    $parent_id
 * @return array
 */
function mindweco_plugin_api_create_category(
	$base_url,
	$token,
	$name,
	$indexing_id,
	$sitemap_xml,
	$language,
	$parent_id = 0
) {
	$query_params = array(
		'name'       => sanitize_text_field( $name ),
		'indexing_id' => absint( $indexing_id ),
		'language'   => sanitize_text_field( $language ),
		'parent_id'  => absint( $parent_id ),
	);

	$url = trailingslashit( esc_url_raw( $base_url ) ) . 'categories/wordpress?' . http_build_query( $query_params );

	$body = $sitemap_xml ? $sitemap_xml : '<sitemap></sitemap>';

	$response = wp_remote_post( $url, array(
		'body'    => $body,
		'headers' => array(
			'Authorization' => 'Bearer ' . $token,
			'Content-Type'  => 'application/xml',
			'Accept'        => 'application/json',
		),
		'timeout' => 60,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$http_code = wp_remote_retrieve_response_code( $response );
	$body      = wp_remote_retrieve_body( $response );

	if ( $http_code >= 400 ) {
		return array( 'error' => 'HTTP Error ' . $http_code, 'response' => $body );
	}

	$result = json_decode( $body, true );
	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid response format' );
	}

	return $result;
}

/**
 * Regenerate category
 *
 * @param string $base_url
 * @param string $token
 * @param int    $category_id
 * @param string $sitemap_xml
 * @param string $language
 * @return array
 */

function mindweco_plugin_regenerate_welcome_message($base_url, $token, $category_id, $sitemap_xml, $language) {

	$query_params = array(
		'category_id' => absint($category_id),
		'language'    => sanitize_text_field($language),
	);

	$url = trailingslashit(esc_url_raw($base_url)) 
		. 'categories/' . absint($category_id) . '/regenerate-welcome?' 
		. http_build_query($query_params);

	$body = $sitemap_xml ? $sitemap_xml : '<sitemap></sitemap>';

	$response = wp_remote_post( $url, array(
		'body'    => $body,
		'headers' => array(
			'Authorization' => 'Bearer ' . $token,
			'Content-Type'  => 'application/xml',
			'Accept'        => 'application/json',
		),
		'timeout' => 60,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$http_code = wp_remote_retrieve_response_code( $response );
	$body      = wp_remote_retrieve_body( $response );

	if ( $http_code >= 400 ) {
		return array( 'error' => 'HTTP Error ' . $http_code, 'response' => $body );
	}

	$result = json_decode( $body, true );
	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid response format' );
	}

	return $result;


}


/**
 * Retrieve all categories.
 *
 * @param string $base_url
 * @param string $token
 * @return array
 */
function mindweco_plugin_api_get_categories( $base_url, $token ) {
	$url = trailingslashit( esc_url_raw( $base_url ) ) . 'categories/';

	$response = wp_remote_get( $url, array(
		'headers' => array(
			'Authorization' => 'Bearer ' . $token,
			'Accept'        => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response' );
	}

	return $data;
}

/**
 * Index WordPress post items.
 *
 * @param string $base_url
 * @param string $token
 * @param int    $category_id
 * @param int    $chunk_size
 * @param int    $chunk_overlap
 * @param string $url
 * @param array  $wp_json
 * @param string $header_levels
 * @param array  $meta
 * @param int    $local_item_id
 * @return array
 */
function mindweco_plugin_api_index_items( $base_url, $token, $category_id, $chunk_size, $chunk_overlap, $url, $wp_json, $header_levels, $meta, $local_item_id ) {
	$api_url = trailingslashit( esc_url_raw( $base_url ) ) . 'api/indexingitems/wordpress';

	$payload = array(
		'category_id'   => absint( $category_id ),
		'chunk_size'    => absint( $chunk_size ),
		'chunk_overlap' => absint( $chunk_overlap ),
		'url'           => esc_url_raw( $url ),
		'wp_json'       => wp_json_encode( $wp_json, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ),
		'header_levels' => sanitize_text_field( $header_levels ),
		'meta'          => wp_json_encode( $meta, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ),
		'local_item_id' => absint( $local_item_id ),
	);

	$response = wp_remote_post( $api_url, array(
		'body'    => $payload,
		'headers' => array(
			'Authorization' => 'Bearer ' . $token,
			'Accept'        => 'application/json',
		),
		'timeout' => 300,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$http_code    = wp_remote_retrieve_response_code( $response );
	$response_body = wp_remote_retrieve_body( $response );

	if ( 200 !== $http_code && 201 !== $http_code ) {
		return array(
			'error'     => 'HTTP ' . $http_code,
			'response'  => $response_body,
			'http_code' => $http_code,
		);
	}

	$decoded = json_decode( $response_body, true );
	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response: ' . json_last_error_msg() );
	}

	if ( empty( $decoded['item_id'] ) ) {
		return array( 'error' => 'No item_id in API response' );
	}

	return $decoded;
}

/**
 * Index WooCommerce products.
 *
 * @param string $base_url
 * @param string $token
 * @param int    $category_id
 * @param int    $chunk_size
 * @param int    $chunk_overlap
 * @param array  $product_json
 * @param array  $meta
 * @param int    $local_item_id
 * @return array
 */
function mindweco_plugin_api_index_products( $base_url, $token, $category_id, $chunk_size, $chunk_overlap, $product_json, $meta, $local_item_id ) {
	$api_url = trailingslashit( esc_url_raw( $base_url ) ) . 'api/indexingitems/woocommerce/product';

	$payload = array(
		'category_id'   => absint( $category_id ),
		'chunk_size'    => absint( $chunk_size ),
		'chunk_overlap' => absint( $chunk_overlap ),
		'product_json'  => wp_json_encode( $product_json, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ),
		'meta'          => wp_json_encode( $meta, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ),
		'local_item_id' => absint( $local_item_id ),
	);

	$response = wp_remote_post( $api_url, array(
		'body'    => $payload,
		'headers' => array(
			'Authorization' => 'Bearer ' . $token,
			'Accept'        => 'application/json',
		),
		'timeout' => 300,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$http_code     = wp_remote_retrieve_response_code( $response );
	$response_body = wp_remote_retrieve_body( $response );

	if ( 200 !== $http_code && 201 !== $http_code ) {
		return array(
			'error'     => 'HTTP ' . $http_code,
			'response'  => $response_body,
			'http_code' => $http_code,
		);
	}

	$decoded = json_decode( $response_body, true );
	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response: ' . json_last_error_msg() );
	}

	if ( empty( $decoded['item_id'] ) ) {
		return array( 'error' => 'No item_id in API response' );
	}

	return $decoded;
}

/**
 * Index Wordpress Media Files.
 *
 * @param string $base_url
 * @param string $token
 * @param int    $category_id
 * @param int    $chunk_size
 * @param int    $chunk_overlap
 * @param string $url
 * @param int    $document_id
 * @param array  $media_item    { id, title, url, mime_type, date, filesize }
 * @param int    $local_item_id
 * @return array
 */
function mindweco_plugin_api_index_media_files( $base_url, $token, $category_id, $chunk_size, $chunk_overlap, $url, $document_id, $media_item, $local_item_id ) {

    $supported_types = array(
        'application/pdf'                                                          => 'pdf',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
    );

    $mime_type = isset( $media_item['mime_type'] ) ? $media_item['mime_type'] : '';

    if ( ! array_key_exists( $mime_type, $supported_types ) ) {
        return array(
            'success' => false,
            'message' => sprintf(
                /* translators: %s: mime type */
                esc_html__( 'Unsupported mime type: %s', 'mind-web-concierge' ),
                esc_html( $mime_type )
            ),
        );
    }

    $file_url  = isset( $media_item['url'] ) ? $media_item['url'] : '';
    $file_path = mindweco_url_to_local_path( $file_url );

    if ( ! $file_path || ! file_exists( $file_path ) ) {
        return array(
            'success' => false,
            'message' => esc_html__( 'File not found on disk.', 'mind-web-concierge' ),
        );
    }

    // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
    $file_contents = file_get_contents( $file_path );

    if ( false === $file_contents ) {
        return array(
            'success' => false,
            'message' => esc_html__( 'Could not read file.', 'mind-web-concierge' ),
        );
    }

    $filename = basename( $file_path );
    $boundary = wp_generate_uuid4();

    $fields = array(
        'category_id'   => (int) $category_id,
        'chunk_size'    => (int) $chunk_size,
        'chunk_overlap' => (int) $chunk_overlap,
        'url'           => esc_url_raw( $url ),
        'document_id'   => (int) $document_id,
        'local_item_id' => (int) $local_item_id,
    );

    $payload = '';

    foreach ( $fields as $name => $value ) {
        $payload .= '--' . $boundary . "\r\n";
        $payload .= 'Content-Disposition: form-data; name="' . sanitize_key( $name ) . '"' . "\r\n\r\n";
        $payload .= $value . "\r\n";
    }

    $payload .= '--' . $boundary . "\r\n";
    $payload .= 'Content-Disposition: form-data; name="document"; filename="' . sanitize_file_name( $filename ) . '"' . "\r\n";
    $payload .= 'Content-Type: ' . sanitize_mime_type( $mime_type ) . "\r\n\r\n";
    $payload .= $file_contents . "\r\n";
    $payload .= '--' . $boundary . '--';

    $api_url = trailingslashit( esc_url_raw( $base_url ) ) . 'api/indexingitems/' . $supported_types[ $mime_type ];

    $response = wp_remote_post(
        $api_url,
        array(
            'headers' => array(
                'Authorization' => 'Bearer ' . sanitize_text_field( $token ),
                'Content-Type'  => 'multipart/form-data; boundary=' . $boundary,
            ),
            'body'    => $payload,
            'timeout' => 60,
        )
    );

    if ( is_wp_error( $response ) ) {
        return array(
            'success' => false,
            'message' => $response->get_error_message(),
        );
    }

    $response_code = wp_remote_retrieve_response_code( $response );
    $body          = json_decode( wp_remote_retrieve_body( $response ), true );

    if ( $response_code < 200 || $response_code >= 300 ) {
        return array(
            'success' => false,
            'message' => isset( $body['message'] ) ? sanitize_text_field( $body['message'] ) : esc_html__( 'Unexpected API response.', 'mind-web-concierge' ),
        );
    }

    return array(
        'success' => true,
        'status'  => $response_code,
        'body'    => $body,
    );
}
/**
 * Convert a WordPress media URL to its absolute local file path.
 *
 * @param string $url
 * @return string|false
 */
function mindweco_url_to_local_path( $url ) {
    $upload_dir = wp_upload_dir();

    if ( strpos( $url, $upload_dir['baseurl'] ) !== 0 ) {
        return false;
    }

    return str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $url );
}

/**
 * Delete an indexed item.
 *
 * @param string $base_url
 * @param string $token
 * @param int    $category_id
 * @param int    $item_id
 * @return array
 */
function mindweco_plugin_api_delete_indexed_items( $base_url, $token, $category_id, $item_id ) {
	$api_url = trailingslashit( esc_url_raw( $base_url ) ) . 'api/' . absint( $category_id ) . '/' . absint( $item_id );

	$response = wp_remote_request( $api_url, array(
		'method'  => 'DELETE',
		'headers' => array(
			'Authorization' => 'Bearer ' . $token,
			'Content-Type'  => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$code = wp_remote_retrieve_response_code( $response );
	$body = wp_remote_retrieve_body( $response );

	if ( $code >= 400 ) {
		return array( 'error' => "HTTP {$code}: {$body}" );
	}

	return json_decode( $body, true ) ?: array( 'success' => true );
}

/**
 * Refresh the API access token and save it.
 *
 * @return string|false
 */
function  mindweco_plugin_refresh_token() {
	$options  = get_option( 'mindweco_plugin_options', array() );
	$base_url = isset( $options['base_url'] ) ? $options['base_url'] : '';
	$username = isset( $options['username'] ) ? $options['username'] : '';
	$password = mindweco_decrypt_api_key( $options['password'] ?? '' );

	if ( ! $base_url || ! $username || ! $password ) {
		return false;
	}

	$login = mindweco_plugin_api_login( $base_url, $username, $password );

	if ( ! isset( $login['access_token'] ) ) {
		return false;
	}

	update_option( 'mindweco_plugin_access_token', mindweco_encrypt_api_key( sanitize_text_field( $login['access_token'] ) ) );

	$token = sanitize_text_field( $login['access_token'] );
	return $token;
}

/**
 * Get the stored knowledge repository token.
 *
 * @return string|false
 */

function mindweco_plugin_knowledge_repository_get_token() {
    $options = get_option( 'mindweco_knowledge_repository_options', array() );
    $token   = isset( $options['token'] ) ? $options['token'] : '';
    if ( ! $token ) {
        return false;
    }
    return mindweco_decrypt_api_key( $token ); 
}

/**
 * Refresh the knowledge repository token.
 *
 * @return string|false
 */
function mindweco_plugin_knowledge_repository_refresh_token() {
    $options  = get_option( 'mindweco_knowledge_repository_options', array() );
    $base_url = isset( $options['base_url'] ) ? $options['base_url'] : '';
    $username = isset( $options['username'] ) ? $options['username'] : '';
    $password = mindweco_decrypt_api_key( isset( $options['password'] ) ? $options['password'] : '' );

    if ( ! $base_url || ! $username || ! $password ) {
        return false;
    }

    $indexing_options = get_option( 'mindweco_plugin_indexing', array() );
    $external_id      = isset( $indexing_options['id'] )    ? $indexing_options['id']    : '';
    $external_name    = isset( $indexing_options['title'] ) ? $indexing_options['title'] : '';

    $login = mindweco_plugin_knowledge_repository_login_with_cookie(
        $base_url,
        $username,
        $password,
        $external_id,
        $external_name,
        0
    );

    if ( isset( $login['error'] ) || ! isset( $login['data']['token'] ) ) {
        return false;
    }

    $new_token        = $login['data']['token'];
    $options['token'] = mindweco_encrypt_api_key( $new_token );
    update_option( 'mindweco_knowledge_repository_options', $options );

    return $new_token;
}

/**
 * Send a streaming request with reference-based context.
 *
 * WordPress HTTP API (wp_remote_post / wp_remote_get) buffers the entire
 * response before returning it, which makes it incompatible with
 * Server-Sent Events (SSE) and streaming endpoints. cURL is used here
 * exclusively because it supports CURLOPT_WRITEFUNCTION, which allows
 * processing incremental response chunks in real time as they arrive.
 * This is not possible with the WordPress HTTP API.
 *
 * All input data is sanitized before being passed to cURL.
 * Output chunks are handled and escaped by the JavaScript layer on render.
 *
 * @param string   $base_url
 * @param string   $token
 * @param string   $question
 * @param int      $category_id
 * @param array    $category_ids
 * @param int      $top_k
 * @param string   $app_guid
 * @param callable $callback
 * @param array    $items_ids
 * @param string   $conversation_id
 * @return array
 */
function mindweco_ask_page_based_ref( $base_url, $token, $question, $category_id, $category_ids, $top_k, $app_guid, $callback, $items_ids, $conversation_id ) {
    $url = trailingslashit( esc_url_raw( $base_url ) ) . 'ask/stream_pro_refs';

    $post_data = array(
        'question'     => sanitize_text_field( $question ),
        'category_id'  => absint( $category_id ),
        'top_k'        => absint( $top_k ),
        'category_ids' => array_map( 'absint', $category_ids ),
        'distance'     => 1,
        'items_ids'    => array_map( 'absint', $items_ids ),
    );

    $headers = array(
        'Authorization' => 'Bearer ' . $token,
        'Content-Type'  => 'application/json',
        'Accept'        => 'text/event-stream',
    );

    if ( ! empty( $app_guid ) ) {
        $headers['X-Subscription-Guid'] = sanitize_text_field( $app_guid );
    }
    if ( ! empty( $conversation_id ) ) {
        $headers['conversationId'] = sanitize_text_field( $conversation_id );
    }

    // cURL is required here — WordPress HTTP API does not support streaming.
    // CURLOPT_WRITEFUNCTION processes each chunk as it arrives in real time.
    $ch = curl_init( $url ); // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_init
    $curl_headers = array();
    foreach ( $headers as $key => $value ) {
        $curl_headers[] = $key . ': ' . $value;
    }

    curl_setopt_array( $ch, array( // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt_array
        CURLOPT_POST          => 1,
        CURLOPT_POSTFIELDS    => wp_json_encode( $post_data ),
        CURLOPT_HTTPHEADER    => $curl_headers,
        CURLOPT_WRITEFUNCTION => $callback,
        CURLOPT_TIMEOUT       => 0,
        CURLOPT_BUFFERSIZE    => 128,
        CURLOPT_HTTP_VERSION  => CURL_HTTP_VERSION_1_1,
    ) );

    $result     = curl_exec( $ch );    // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_exec
    $curl_error = curl_error( $ch );   // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_error
    $http_code  = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_getinfo
    curl_close( $ch );                 // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close

    return array(
        'success'   => ( 200 === $http_code && ! $curl_error ),
        'http_code' => $http_code,
        'error'     => $curl_error,
    );
}
/**
 * Add a Stripe trial subscription with a new user.
 *
 * @param string $stripe_base_url
 * @param string $app_guid
 * @param string $product_id
 * @param string $customer_email
 * @param string $title
 * @param string $site_base_url
 * @return array
 */
function mindweco_stripe_add_trial( $stripe_base_url, $app_guid, $product_id, $customer_email, $title, $site_base_url ) {
	$url = trailingslashit( esc_url_raw( $stripe_base_url ) ) . 'Subscription/AddTrialWithUser';

	$payload = array(
		'AppGuid'         => sanitize_text_field( $app_guid ),
		'StripeProductId' => sanitize_text_field( $product_id ),
		'CustomerEmail'   => sanitize_email( $customer_email ),
		'title'           => sanitize_text_field( $title ),
		'base_url'        => esc_url_raw( $site_base_url ),
	);


	$response = wp_remote_post( $url, array(
		'body'    => wp_json_encode( $payload ),
		'headers' => array(
			'Content-Type' => 'application/json',
			'Accept'       => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$body    = wp_remote_retrieve_body( $response );
	$decoded = json_decode( $body, true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response: ' . json_last_error_msg(), 'raw' => $body );
	}

	return $decoded;
}

function mindweco_get_history($base_url, $conversation_id) {
    $url = trailingslashit( esc_url_raw( $base_url ) ) 
         . 'operator/conversations/' 
         . rawurlencode( $conversation_id ) 
         . '/messages';

    $response = wp_remote_get( $url, array(
        'headers' => array( 'Accept' => 'application/json' ),
        'timeout' => 20,
    ) );

    if ( is_wp_error( $response ) ) {
        return array( 'error' => $response->get_error_message() );
    }

    $code = (int) wp_remote_retrieve_response_code( $response );
    $body = trim( wp_remote_retrieve_body( $response ) );

    if ( 204 === $code || '' === $body ) {
        return array();
    }

    if ( $code >= 400 ) {
        return array( 'error' => 'HTTP error: ' . $code );
    }

    $data = json_decode( $body, true );

    if ( json_last_error() !== JSON_ERROR_NONE ) {
        return array( 'error' => 'Invalid JSON response' );
    }

    return $data;
}

/**
 * Add a Stripe trial subscription without creating a user.
 *
 * @param string $stripe_base_url
 * @param string $app_guid
 * @param string $product_id
 * @param string $customer_email
 * @return array
 */
function mindweco_stripe_add_trial_without_user( $stripe_base_url, $app_guid, $product_id, $customer_email ) {
	$url = trailingslashit( esc_url_raw( $stripe_base_url ) ) . 'Subscription/AddTrial';

	$payload = array(
		'AppGuid'         => sanitize_text_field( $app_guid ),
		'StripeProductId' => sanitize_text_field( $product_id ),
		'CustomerEmail'   => sanitize_email( $customer_email ),
	);

	$response = wp_remote_post( $url, array(
		'body'    => wp_json_encode( $payload ),
		'headers' => array(
			'Content-Type' => 'application/json',
			'Accept'       => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$body    = wp_remote_retrieve_body( $response );
	$decoded = json_decode( $body, true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response: ' . json_last_error_msg(), 'raw' => $body );
	}

	return $decoded;
}

/**
 * Get the active Stripe subscription for a given app GUID.
 *
 * @param string $stripe_base_url
 * @param string $app_guid
 * @return array
 */
function mindweco_stripe_active_subscription( $stripe_base_url, $app_guid ) {
    $url = trailingslashit( esc_url_raw( $stripe_base_url ) ) . 'Subscription/GetActiveSubscription/' . rawurlencode( $app_guid );

    $response = wp_remote_get( $url, array(
        'headers' => array( 'Accept' => 'application/json' ),
        'timeout' => 20,
    ) );

    if ( is_wp_error( $response ) ) {
        return array( 'error' => $response->get_error_message() );
    }

    $code = (int) wp_remote_retrieve_response_code( $response );
    $body = trim( wp_remote_retrieve_body( $response ) );

    if ( 204 === $code || '' === $body ) {
        return array();
    }

    if ( $code >= 400 ) {
        return array( 'error' => 'HTTP error: ' . $code );
    }

   $data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response' );
	}

	return $data;
}

/**
 * Get all Stripe subscriptions for a given app GUID.
 *
 * @param string $stripe_base_url
 * @param string $app_guid
 * @return array
 */
function mindweco_get_all_subscriptions( $stripe_base_url, $app_guid ) {
	$url = trailingslashit( esc_url_raw( $stripe_base_url ) ) . 'Subscription/' . rawurlencode( $app_guid );

	$response = wp_remote_get( $url, array(
		'headers' => array( 'Accept' => 'application/json' ),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response' );
	}

	return $data;
}

/**
 * Get Stripe subscription history for a given app GUID.
 *
 * @param string $stripe_base_url
 * @param string $app_guid
 * @return array
 */
function mindweco_get_history_subscription( $stripe_base_url, $app_guid ) {
	$url = trailingslashit( esc_url_raw( $stripe_base_url ) ) . 'Subscription/GetHistory/' . rawurlencode( $app_guid );

	$response = wp_remote_get( $url, array(
		'headers' => array( 'Accept' => 'application/json' ),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response' );
	}

	return $data;
}

/**
 * Cancel a Stripe subscription.
 *
 * @param string $stripe_base_url
 * @param string $app_guid
 * @param string $subscription_id
 * @param string $cancel
 * @return array
 */
function mindweco_plugin_cancel_subscription( $stripe_base_url, $app_guid, $subscription_id, $cancel = 'true' ) {
	$url = trailingslashit( esc_url_raw( $stripe_base_url ) ) . 'Subscription/CancelSubscription/' . rawurlencode( $subscription_id );

	$payload = array(
		'AppGuid' => sanitize_text_field( $app_guid ),
		'Cancel'  => $cancel,
	);

	$response = wp_remote_post( $url, array(
		'body'    => wp_json_encode( $payload ),
		'headers' => array(
			'Content-Type' => 'application/json',
			'Accept'       => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response' );
	}

	return $data;
}

/**
 * Reactivate a cancelled Stripe subscription.
 *
 * @param string $stripe_base_url
 * @param string $app_guid
 * @param string $subscription_id
 * @param string $cancel
 * @return array
 */
function mindweco_plugin_reactivate_subscription( $stripe_base_url, $app_guid, $subscription_id, $cancel = 'false' ) {
	$url = trailingslashit( esc_url_raw( $stripe_base_url ) ) . 'Subscription/CancelSubscription/' . rawurlencode( $subscription_id );

	$payload = array(
		'AppGuid' => sanitize_text_field( $app_guid ),
		'Cancel'  => $cancel,
	);

	$response = wp_remote_post( $url, array(
		'body'    => wp_json_encode( $payload ),
		'headers' => array(
			'Content-Type' => 'application/json',
			'Accept'       => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response' );
	}

	return $data;
}

/**
 * Log in to the knowledge repository and retrieve a token.
 *
 * @param string $knowledge_repository_base_url
 * @param string $username
 * @param string $password
 * @param string $external_id
 * @param string $external_name
 * @param int    $type
 * @return array
 */
function mindweco_plugin_knowledge_repository_login_with_cookie( $knowledge_repository_base_url, $username, $password, $external_id = '', $external_name = '', $type = 0 ) {
	$login_url = trailingslashit( esc_url_raw( $knowledge_repository_base_url ) ) . 'api/Identity/LoginWithCredentials';

	$payload = wp_json_encode( array(
		'userName' => sanitize_text_field( $username ),
		'password' => $password,
		'externalConnection' => array(
			'externalId'   => sanitize_text_field( $external_id ),
			'externalName' => sanitize_text_field( $external_name ),
			'type'         => absint( $type ),
		),
	) );

	$response = wp_remote_post( $login_url, array(
		'body'    => $payload,
		'headers' => array(
			'Content-Type' => 'application/json',
			'Accept'       => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => 'Connection error: ' . $response->get_error_message() );
	}

	$http_code = wp_remote_retrieve_response_code( $response );

	if ( 200 !== $http_code ) {
		return array( 'error' => 'Login failed. Please check your credentials.' );
	}

	$body = wp_remote_retrieve_body( $response );
	$data = json_decode( $body, true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response from login' );
	}

	if ( ! isset( $data['token'] ) ) {
		return array( 'error' => 'No authentication token received' );
	}

	return array( 'data' => $data );
}

/**
 * Log out from the knowledge repository.
 *
 * @param string $knowledge_repository_base_url
 * @param int    $external_app_id
 * @param int    $user_id
 * @return array
 */
function mindweco_plugin_knowledge_repository_logout( $knowledge_repository_base_url, $external_app_id, $user_id ) {
	$logout_url = add_query_arg(
		array(
			'ExternalAppId' => absint( $external_app_id ),
			'UserId'        => absint( $user_id ),
		),
		trailingslashit( esc_url_raw( $knowledge_repository_base_url ) ) . 'api/Identity/RemoveExternalAppConnection'
	);

	$response = wp_remote_post( $logout_url, array(
		'headers' => array( 'accept' => 'text/plain' ),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$http_code = wp_remote_retrieve_response_code( $response );
	$body      = wp_remote_retrieve_body( $response );

	if ( 'true' === trim( $body ) ) {
		return array( 'http_code' => $http_code, 'success' => true );
	}

	return array( 'http_code' => $http_code, 'success' => false, 'raw' => $body );
}

/**
 * Get notebooks from the knowledge repository.
 *
 * @param string $knowledge_repository_base_url
 * @param string $token
 * @return array
 */
function mindweco_plugin_get_notebooks( $knowledge_repository_base_url, $token ) {
	$url = trailingslashit( esc_url_raw( $knowledge_repository_base_url ) ) . 'api/ApiNotebook';

	$response = wp_remote_get( $url, array(
		'headers' => array(
			'Authorization' => 'Bearer ' . trim( $token ),
			'Accept'        => 'text/plain',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => 'Connection error: ' . $response->get_error_message() );
	}

	$http_code = wp_remote_retrieve_response_code( $response );
	$body      = wp_remote_retrieve_body( $response );

	if ( false !== strpos( $body, '<!DOCTYPE html' ) ) {
		return array( 'error' => 'Server returned HTML instead of JSON (check URL or auth).' );
	}

	if ( 401 === $http_code ) {
		return array( 'status' => 401, 'error' => 'Unauthorized - token expired' );
	}

	if ( 200 !== $http_code ) {
		return array( 'status' => $http_code, 'error' => 'Failed to fetch notebooks. Status code: ' . $http_code );
	}

	$data = json_decode( $body, true );
	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response from notebooks' );
	}

	$notebooks = isset( $data['notebooks'] ) ? $data['notebooks'] : $data;

	if ( is_array( $notebooks ) && isset( $notebooks['notebooks'] ) ) {
		$notebooks = $notebooks['notebooks'];
	}

	return array( 'notebooks' => $notebooks );
}

/**
 * Create and attach an LLM config to an indexing config.
 *
 * @param string $base_url
 * @param string $token
 * @param string $name
 * @param string $llm_base_url
 * @param string $model_name
 * @param string $provider
 * @param string $api_key
 * @param int    $indexing_id
 * @return array
 */
function mindweco_plugin_create_attach_llm_to_config( $base_url, $token, $name, $llm_base_url, $model_name, $provider, $api_key, $indexing_id ) {
	$url = trailingslashit( esc_url_raw( $base_url ) ) . 'indexing/create-and-attach-llm-config-to-indexing';

	$payload = array(
		'name'         => sanitize_text_field( $name ),
		'llm_base_url' => esc_url_raw( $llm_base_url ),
		'model_name'   => sanitize_text_field( $model_name ),
		'provider'     => sanitize_text_field( $provider ),
		'api_key'      => sanitize_text_field( $api_key ),
		'indexing_id'  => absint( $indexing_id ),
	);

	$response = wp_remote_post( $url, array(
		'body'    => wp_json_encode( $payload ),
		'headers' => array(
			'Authorization' => 'Bearer ' . $token,
			'Content-Type'  => 'application/json',
			'Accept'        => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$http_code = wp_remote_retrieve_response_code( $response );
	$body      = wp_remote_retrieve_body( $response );

	if ( $http_code < 200 || $http_code >= 300 ) {
		return array( 'error' => 'API returned HTTP ' . $http_code . '. Body: ' . $body );
	}

	$decoded = json_decode( $body, true );
	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Failed to parse API response: ' . json_last_error_msg() );
	}

	return $decoded;
}

/**
 * Update an LLM configuration.
 *
 * @param string $base_url
 * @param string $token
 * @param int    $llm_id
 * @param string $name
 * @param string $api_key
 * @param string $llm_base_url
 * @param string $model_name
 * @param int    $user_id
 * @return array|null
 */
function mindweco_plugin_update_llm_config( $base_url, $token, $llm_id, $name, $api_key, $llm_base_url, $model_name, $user_id ) {
	$url = trailingslashit( esc_url_raw( $base_url ) ) . 'llm-configs/' . absint( $llm_id );

	$payload = array(
		'name'         => sanitize_text_field( $name ),
		'api_key'      => sanitize_text_field( $api_key ),
		'llm_base_url' => esc_url_raw( $llm_base_url ),
		'model_name'   => sanitize_text_field( $model_name ),
		'user_id'      => absint( $user_id ),
	);

	$response = wp_remote_request( $url, array(
		'method'  => 'PUT',
		'body'    => wp_json_encode( $payload ),
		'headers' => array(
			'Authorization' => 'Bearer ' . $token,
			'Content-Type'  => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$data = json_decode( wp_remote_retrieve_body( $response ), true );

	if ( json_last_error() !== JSON_ERROR_NONE ) {
		return array( 'error' => 'Invalid JSON response' );
	}

	return $data;
}

/**
 * Delete an LLM configuration.
 *
 * @param string $base_url
 * @param string $token
 * @param int    $llm_id
 * @return array
 */
function mindweco_plugin_delete_llm_config( $base_url, $token, $llm_id ) {
	$url = trailingslashit( esc_url_raw( $base_url ) ) . 'llm-configs/' . absint( $llm_id );

	$response = wp_remote_request( $url, array(
		'method'  => 'DELETE',
		'headers' => array(
			'Authorization' => 'Bearer ' . $token,
			'Content-Type'  => 'application/json',
		),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => $response->get_error_message() );
	}

	$http_code = wp_remote_retrieve_response_code( $response );
	$body      = wp_remote_retrieve_body( $response );

	if ( $http_code >= 200 && $http_code < 300 ) {
		if ( empty( $body ) ) {
			return array( 'success' => true, 'message' => 'LLM config deleted' );
		}

		$decoded = json_decode( $body, true );
		if ( json_last_error() === JSON_ERROR_NONE ) {
			return $decoded;
		}

		return array( 'success' => true, 'message' => 'LLM config deleted' );
	}

	return array( 'error' => 'HTTP Error: ' . $http_code . ' - ' . $body );
}

/**
 * Download an invoice PDF URL.
 *
 * @param string $stripe_base_url
 * @param string $invoice_number
 * @return array
 */
function mindweco_download_subscription_invoice( $stripe_base_url, $invoice_number ) {
	$url = trailingslashit( esc_url_raw( $stripe_base_url ) ) . 'Invoices/GetInvoicePdfUrl/' . rawurlencode( $invoice_number );

	$response = wp_remote_get( $url, array(
		'headers' => array( 'Content-Type' => 'application/json' ),
		'timeout' => 20,
	) );

	if ( is_wp_error( $response ) ) {
		return array( 'error' => 'Request error: ' . $response->get_error_message() );
	}

	$body = trim( wp_remote_retrieve_body( $response ) );

	if ( ! empty( $body ) ) {
		return array( 'url' => esc_url_raw( $body ) );
	}

	return array( 'error' => 'No URL returned from API' );
}
