///////////////////////////////////////////////////////////////////////////////
//
// (C) 2024 ICE TEA GROUP LLC - ALL RIGHTS RESERVED
//
// 
//
// ALL INFORMATION CONTAINED HEREIN IS, AND REMAINS
// THE PROPERTY OF ICE TEA GROUP LLC AND ITS SUPPLIERS, IF ANY.
// THE INTELLECTUAL PROPERTY AND TECHNICAL CONCEPTS CONTAINED
// HEREIN ARE PROPRIETARY TO ICE TEA GROUP LLC AND ITS SUPPLIERS
// AND MAY BE COVERED BY U.S. AND FOREIGN PATENTS, PATENT IN PROCESS, AND
// ARE PROTECTED BY TRADE SECRET OR COPYRIGHT LAW.
//
// DISSEMINATION OF THIS INFORMATION OR REPRODUCTION OF THIS MATERIAL
// IS STRICTLY FORBIDDEN UNLESS PRIOR WRITTEN PERMISSION IS OBTAINED
// FROM ICE TEA GROUP LLC.
//
///////////////////////////////////////////////////////////////////////////////

using System;
using System.ComponentModel;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Wisej.AI.Services
{
	/// <summary>
	/// Represents a web search service using Bing's API.
	/// </summary>
	/// <remarks>
	/// This class extends <see cref="WebSearchServiceBase"/> to provide specific implementation details for interacting with the Bing Web Search API.
	/// </remarks>
	[ApiCategory("Services/IWebSearchService")]
	public class BingWebSearchService : WebSearchServiceBase
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="BingWebSearchService"/> class with the specified URL.
		/// </summary>
		/// <param name="url">The base URL for the Bing Web Search API. Default is "https://api.bing.microsoft.com/v7.0/search".</param>
		public BingWebSearchService(
			string url = "https://api.bing.microsoft.com/v7.0/search")

			: base(url)
		{
		}

		#region Implementation

		/// <summary>
		/// Gets the authentication header name specific to Bing's API.
		/// </summary>
		/// <remarks>
		/// The authentication header for Bing's API is "Ocp-Apim-Subscription-Key".
		/// </remarks>
		public override string Authentication
			=> "Ocp-Apim-Subscription-Key";

		/// <summary>
		/// Performs an asynchronous search using Bing's Web Search API with the specified query.
		/// </summary>
		/// <param name="query">The search query string.</param>
		/// <returns>A task representing the asynchronous operation, with a result of the search response as a formatted string.</returns>
		/// <remarks>
		/// This method formats the query string, sends a GET request to the Bing API, and processes the response to extract and format the search results.
		/// </remarks>
		public override async Task<string> SearchAsync(string query)
		{
			var client = this.Client;
			var q = String.Format(this.QueryString, WebUtility.UrlEncode(query));
			var response = await client.GetAsync($"{this.Url}?{q}");
			response.EnsureSuccessStatusCode();
			var result = JSON.Parse(await response.Content.ReadAsStringAsync());

			var count = 0;
			var sb = new StringBuilder();
			var candidates = result.webPages.value;
			foreach (var website in candidates)
			{
				sb.AppendLine($"URL:{website.url}");
				sb.AppendLine($"Abstract:{website.snippet}");
				sb.AppendLine($"===");

				if (++count >= this.MaxSites)
					break;
			}

			return sb.ToString();
		}

		#endregion
	}
}
