using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace AxCopilot.Services.Agent;

public class DocumentReviewTool : IAgentTool
{
	public string Name => "document_review";

	public string Description => "Review a generated document for quality issues. Checks: empty sections, placeholder text, date consistency, missing headings, broken HTML tags, content completeness. Returns a structured review report with issues found and suggestions.";

	public ToolParameterSchema Parameters
	{
		get
		{
			ToolParameterSchema obj = new ToolParameterSchema
			{
				Properties = new Dictionary<string, ToolProperty>
				{
					["path"] = new ToolProperty
					{
						Type = "string",
						Description = "Path to the document to review"
					},
					["expected_sections"] = new ToolProperty
					{
						Type = "array",
						Description = "Optional list of expected section titles to verify presence",
						Items = new ToolProperty
						{
							Type = "string"
						}
					}
				}
			};
			int num = 1;
			List<string> list = new List<string>(num);
			CollectionsMarshal.SetCount(list, num);
			CollectionsMarshal.AsSpan(list)[0] = "path";
			obj.Required = list;
			return obj;
		}
	}

	public Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct)
	{
		if (!args.TryGetProperty("path", out var value))
		{
			return Task.FromResult(ToolResult.Fail("path가 필요합니다."));
		}
		string path = value.GetString() ?? "";
		string text = FileReadTool.ResolvePath(path, context.WorkFolder);
		if (!context.IsPathAllowed(text))
		{
			return Task.FromResult(ToolResult.Fail("경로 접근 차단: " + text));
		}
		if (!File.Exists(text))
		{
			return Task.FromResult(ToolResult.Fail("파일 없음: " + text));
		}
		string text2 = File.ReadAllText(text);
		string text3 = Path.GetExtension(text).ToLowerInvariant();
		List<string> list = new List<string>();
		List<string> list2 = new List<string>();
		int value2 = text2.Split('\n').Length;
		int length = text2.Length;
		list2.Add($"파일: {Path.GetFileName(text)} ({length:N0}자, {value2}줄)");
		if (string.IsNullOrWhiteSpace(text2))
		{
			list.Add("[CRITICAL] 파일 내용이 비어있습니다");
			return Task.FromResult(ToolResult.Ok(FormatReport(list2, list, new List<string>()), text));
		}
		string[] array = new string[8] { "TODO", "TBD", "FIXME", "Lorem ipsum", "[여기에", "[INSERT", "placeholder", "예시 텍스트" };
		string[] array2 = array;
		foreach (string text4 in array2)
		{
			if (text2.Contains(text4, StringComparison.OrdinalIgnoreCase))
			{
				list.Add("[WARNING] 플레이스홀더 텍스트 발견: \"" + text4 + "\"");
			}
		}
		Regex regex = new Regex("\\d{4}[-년.]\\s*\\d{1,2}[-월.]\\s*\\d{1,2}[일]?");
		foreach (Match item in regex.Matches(text2))
		{
			string s = Regex.Replace(item.Value, "[년월일\\s]", "-").TrimEnd('-');
			if (DateTime.TryParse(s, out var result))
			{
				if (result > DateTime.Now.AddDays(365.0))
				{
					list.Add("[WARNING] 미래 날짜 감지: " + item.Value);
				}
				else if (result < DateTime.Now.AddYears(-50))
				{
					list.Add("[INFO] 매우 오래된 날짜: " + item.Value);
				}
			}
		}
		if ((text3 == ".html" || text3 == ".htm") ? true : false)
		{
			MatchCollection matchCollection = Regex.Matches(text2, "<h[23][^>]*>.*?</h[23]>\\s*<h[23]");
			if (matchCollection.Count > 0)
			{
				list.Add($"[WARNING] 빈 섹션 {matchCollection.Count}개 감지 (헤딩 뒤 내용 없음)");
			}
			int count = Regex.Matches(text2, "<(table|div|section|article)\\b[^/]*>").Count;
			int count2 = Regex.Matches(text2, "</(table|div|section|article)>").Count;
			if (count != count2)
			{
				list.Add($"[WARNING] HTML 태그 불균형: 열림 {count}개, 닫힘 {count2}개");
			}
			MatchCollection matchCollection2 = Regex.Matches(text2, "<img\\b(?![^>]*\\balt\\s*=)[^>]*>");
			if (matchCollection2.Count > 0)
			{
				list.Add($"[INFO] alt 속성 없는 이미지 {matchCollection2.Count}개");
			}
			int count3 = Regex.Matches(text2, "<h1\\b").Count;
			int count4 = Regex.Matches(text2, "<h2\\b").Count;
			list2.Add($"구조: h1={count3}, h2={count4}개 섹션");
		}
		if (args.TryGetProperty("expected_sections", out var value3) && value3.ValueKind == JsonValueKind.Array)
		{
			foreach (JsonElement item2 in value3.EnumerateArray())
			{
				string text5 = item2.GetString() ?? "";
				if (!string.IsNullOrEmpty(text5) && !text2.Contains(text5, StringComparison.OrdinalIgnoreCase))
				{
					list.Add("[MISSING] 기대 섹션 누락: \"" + text5 + "\"");
				}
			}
		}
		IEnumerable<IGrouping<string, string>> source = from text6 in Regex.Split(text2, "[.!?。]\\s+")
			where text6.Length > 20
			group text6 by text6.Trim() into g
			where g.Count() >= 3
			select g;
		foreach (IGrouping<string, string> item3 in source.Take(3))
		{
			list.Add($"[WARNING] 반복 텍스트 ({item3.Count()}회): \"{item3.Key.Substring(0, Math.Min(50, item3.Key.Length))}...\"");
		}
		List<string> list3 = new List<string>();
		if (list.Count == 0)
		{
			list3.Add("문서 검증 통과 — 구조적 이슈가 발견되지 않았습니다.");
		}
		else
		{
			list3.Add($"총 {list.Count}개 이슈 발견. 수정 후 다시 검증하세요.");
			if (list.Any((string text6) => text6.Contains("플레이스홀더")))
			{
				list3.Add("플레이스홀더를 실제 내용으로 교체하세요.");
			}
			if (list.Any((string text6) => text6.Contains("빈 섹션")))
			{
				list3.Add("빈 섹션에 내용을 추가하거나 불필요한 헤딩을 제거하세요.");
			}
		}
		return Task.FromResult(ToolResult.Ok(FormatReport(list2, list, list3), text));
	}

	private static string FormatReport(List<string> stats, List<string> issues, List<string> suggestions)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("=== 문서 검증 보고서 ===\n");
		foreach (string stat in stats)
		{
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder2);
			handler.AppendLiteral("\ud83d\udcca ");
			handler.AppendFormatted(stat);
			stringBuilder3.AppendLine(ref handler);
		}
		stringBuilder.AppendLine();
		if (issues.Count == 0)
		{
			stringBuilder.AppendLine("✅ 이슈 없음 — 문서가 정상입니다.");
		}
		else
		{
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(13, 1, stringBuilder2);
			handler.AppendLiteral("⚠ 발견된 이슈 (");
			handler.AppendFormatted(issues.Count);
			handler.AppendLiteral("건):");
			stringBuilder4.AppendLine(ref handler);
			foreach (string issue in issues)
			{
				stringBuilder2 = stringBuilder;
				StringBuilder stringBuilder5 = stringBuilder2;
				handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2);
				handler.AppendLiteral("  ");
				handler.AppendFormatted(issue);
				stringBuilder5.AppendLine(ref handler);
			}
		}
		stringBuilder.AppendLine();
		foreach (string suggestion in suggestions)
		{
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder6 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder2);
			handler.AppendLiteral("\ud83d\udca1 ");
			handler.AppendFormatted(suggestion);
			stringBuilder6.AppendLine(ref handler);
		}
		return stringBuilder.ToString();
	}
}
