using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using AxCopilot.SDK;
using AxCopilot.Services;

namespace AxCopilot.Handlers;

public class JsonSkillHandler : IActionHandler
{
	private readonly JsonSkillDefinition _def;

	private readonly HttpClient _http = new HttpClient();

	private List<LauncherItem>? _cache;

	private DateTime _cacheExpiry = DateTime.MinValue;

	public string? Prefix => _def.Prefix;

	public PluginMetadata Metadata => new PluginMetadata(_def.Id, _def.Name, _def.Version, "JSON Skill");

	public JsonSkillHandler(JsonSkillDefinition def)
	{
		_def = def;
		_http.Timeout = TimeSpan.FromSeconds(3.0);
		if (def.Credential?.Type == "bearer_token")
		{
			string token = CredentialManager.GetToken(def.Credential.CredentialKey);
			if (!string.IsNullOrEmpty(token))
			{
				_http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
			}
		}
	}

	public async Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
	{
		if (_cache != null && DateTime.Now < _cacheExpiry)
		{
			return _cache;
		}
		if (_def.Request == null || _def.Response == null)
		{
			return Enumerable.Empty<LauncherItem>();
		}
		try
		{
			string url = _def.Request.Url.Replace("{{INPUT}}", Uri.EscapeDataString(query));
			if (!Uri.TryCreate(url, UriKind.Absolute, out Uri parsedUrl) || (parsedUrl.Scheme != Uri.UriSchemeHttp && parsedUrl.Scheme != Uri.UriSchemeHttps))
			{
				LogService.Error("[" + _def.Name + "] 유효하지 않은 URL: " + url);
				return new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("설정 오류", "스킬 URL이 유효하지 않습니다 (http/https만 허용)", null, null));
			}
			string text = _def.Request.Method.ToUpper();
			if (1 == 0)
			{
			}
			HttpResponseMessage httpResponseMessage = ((!(text == "POST")) ? (await _http.GetAsync(url, ct)) : (await _http.PostAsync(url, BuildBody(query), ct)));
			if (1 == 0)
			{
			}
			HttpResponseMessage response = httpResponseMessage;
			response.EnsureSuccessStatusCode();
			List<LauncherItem> items = ParseResults(await response.Content.ReadAsStringAsync(ct));
			JsonSkillCache? cache = _def.Cache;
			if (cache != null && cache.Ttl > 0)
			{
				_cache = items;
				_cacheExpiry = DateTime.Now.AddSeconds(_def.Cache.Ttl);
			}
			return items;
		}
		catch (TaskCanceledException)
		{
			if (_cache != null)
			{
				LogService.Warn("[" + _def.Name + "] API 타임아웃, 캐시 반환");
				return _cache;
			}
			return new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("네트워크 오류", "연결을 확인하세요", null, null));
		}
		catch (Exception ex2)
		{
			LogService.Error("[" + _def.Name + "] API 호출 실패: " + ex2.Message);
			return new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("오류: " + ex2.Message, _def.Name, null, null));
		}
	}

	public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
	{
		if (item.ActionUrl != null && Uri.TryCreate(item.ActionUrl, UriKind.Absolute, out Uri result) && (result.Scheme == Uri.UriSchemeHttp || result.Scheme == Uri.UriSchemeHttps))
		{
			Process.Start(new ProcessStartInfo(item.ActionUrl)
			{
				UseShellExecute = true
			});
		}
		return Task.CompletedTask;
	}

	private HttpContent BuildBody(string query)
	{
		string content = JsonSerializer.Serialize(_def.Request?.Body).Replace("\"{{INPUT}}\"", "\"" + query + "\"");
		return new StringContent(content, Encoding.UTF8, "application/json");
	}

	private List<LauncherItem> ParseResults(string json)
	{
		List<LauncherItem> list = new List<LauncherItem>();
		try
		{
			JsonNode jsonNode = JsonNode.Parse(json);
			if (jsonNode == null)
			{
				return list;
			}
			JsonNode jsonNode2 = NavigatePath(jsonNode, _def.Response.ResultsPath);
			if (!(jsonNode2 is JsonArray source))
			{
				return list;
			}
			foreach (JsonNode item in source.Take(10))
			{
				if (item != null)
				{
					string title = NavigatePath(item, _def.Response.TitleField)?.ToString() ?? "(제목 없음)";
					string subtitle = ((_def.Response.SubtitleField == null) ? "" : (NavigatePath(item, _def.Response.SubtitleField)?.ToString() ?? ""));
					string actionUrl = ((_def.Response.ActionUrl == null) ? null : NavigatePath(item, _def.Response.ActionUrl)?.ToString());
					list.Add(new LauncherItem(title, subtitle, null, item, actionUrl, "\ue82d"));
				}
			}
		}
		catch (Exception ex)
		{
			LogService.Error("[" + _def.Name + "] 응답 파싱 실패: " + ex.Message);
		}
		return list;
	}

	private static JsonNode? NavigatePath(JsonNode root, string path)
	{
		string[] array = path.Split('.');
		JsonNode jsonNode = root;
		string[] array2 = array;
		foreach (string text in array2)
		{
			if (jsonNode == null)
			{
				return null;
			}
			int num = text.IndexOf('[');
			if (num >= 0)
			{
				int num2 = text.IndexOf(']');
				if (num2 < 0)
				{
					return null;
				}
				string propertyName = text.Substring(0, num);
				int num3 = num + 1;
				int index = int.Parse(text.Substring(num3, num2 - num3));
				jsonNode = jsonNode[propertyName]?[index];
			}
			else
			{
				jsonNode = jsonNode[text];
			}
		}
		return jsonNode;
	}
}
