using Microsoft.ApplicationInsights;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace PlanTempus.Application.Components
{
    public abstract class ApiViewComponentBase : ViewComponent
    {
        private readonly HttpClient _httpClient;
        private readonly TelemetryClient _telemetry;
        
        protected ApiViewComponentBase(IHttpClientFactory httpClientFactory, TelemetryClient telemetry)
        {
            _httpClient = httpClientFactory.CreateClient("ApiClient");
            _telemetry = telemetry;
        }
        
        /// <summary>
        /// Fetches data from API as JObject
        /// </summary>
        /// <param name="apiEndpoint">API endpoint path (e.g. "/api/product/get/1")</param>
        /// <returns>JObject with API result</returns>
        protected async Task<JObject> GetJObjectFromApiAsync(string apiEndpoint)
        {
            try
            {
                _telemetry.TrackEvent("ApiCall", new Dictionary<string, string> 
                { 
                    ["Endpoint"] = apiEndpoint,
                    ["Source"] = "GetJObjectFromApiAsync" 
                });
                
                // Use HttpClient to get JSON string
                var response = await _httpClient.GetAsync(apiEndpoint);
                response.EnsureSuccessStatusCode();
                
                var jsonString = await response.Content.ReadAsStringAsync();
                return JObject.Parse(jsonString);
            }
            catch (Exception ex)
            {
                _telemetry.TrackException(ex, new Dictionary<string, string> 
                { 
                    ["Endpoint"] = apiEndpoint,
                    ["Method"] = "GetJObjectFromApiAsync" 
                });
                return null;
            }
        }
        
        /// <summary>
        /// Fetches data from API as JArray
        /// </summary>
        /// <param name="apiEndpoint">API endpoint path</param>
        /// <returns>JArray with API result</returns>
        protected async Task<JArray> GetJArrayFromApiAsync(string apiEndpoint)
        {
            try
            {
                _telemetry.TrackEvent("ApiCall", new Dictionary<string, string> 
                { 
                    ["Endpoint"] = apiEndpoint,
                    ["Source"] = "GetJArrayFromApiAsync" 
                });
                
                // Use HttpClient to get JSON string
                var response = await _httpClient.GetAsync(apiEndpoint);
                response.EnsureSuccessStatusCode();
                
                var jsonString = await response.Content.ReadAsStringAsync();
                return JArray.Parse(jsonString);
            }
            catch (Exception ex)
            {
                _telemetry.TrackException(ex, new Dictionary<string, string> 
                { 
                    ["Endpoint"] = apiEndpoint,
                    ["Method"] = "GetJArrayFromApiAsync" 
                });
                return null;
            }
        }
        
        /// <summary>
        /// Sends POST request to API and receives JObject response
        /// </summary>
        /// <param name="apiEndpoint">API endpoint path</param>
        /// <param name="data">Data to be sent (can be JObject or other type)</param>
        /// <returns>JObject with response data</returns>
        protected async Task<JObject> PostToApiAsync(string apiEndpoint, object data)
        {
            try
            {
                _telemetry.TrackEvent("ApiPost", new Dictionary<string, string> 
                { 
                    ["Endpoint"] = apiEndpoint
                });
                
                // Convert data to JSON string
                var content = new StringContent(
                    JsonConvert.SerializeObject(data),
                    System.Text.Encoding.UTF8,
                    "application/json");
                
                var response = await _httpClient.PostAsync(apiEndpoint, content);
                response.EnsureSuccessStatusCode();
                
                var jsonString = await response.Content.ReadAsStringAsync();
                return JObject.Parse(jsonString);
            }
            catch (Exception ex)
            {
                _telemetry.TrackException(ex, new Dictionary<string, string> 
                { 
                    ["Endpoint"] = apiEndpoint,
                    ["Method"] = "PostToApiAsync" 
                });
                return null;
            }
        }
        
        /// <summary>
        /// Handles errors in a consistent way
        /// </summary>
        protected IViewComponentResult HandleError(string message = "An error occurred.")
        {
            _telemetry.TrackEvent("ComponentError", new Dictionary<string, string> 
            { 
                ["Message"] = message,
                ["Component"] = this.GetType().Name
            });
            
            return Content(message);
        }
    }
}