using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AxCopilot.Models;

namespace AxCopilot.Services.Agent;

public static class ContextCondenser
{
	private const int MaxToolResultChars = 1500;

	private const int RecentKeepCount = 6;

	private static int GetModelInputLimit(string service, string model)
	{
		string text = (service + ":" + model).ToLowerInvariant();
		string text2 = text;
		if (1 == 0)
		{
		}
		int result = ((!text.Contains("claude")) ? ((!text.Contains("gemini-2.5")) ? ((!text.Contains("gemini-2.0")) ? ((!text.Contains("gemini")) ? ((!text.Contains("gpt-4")) ? 16000 : 120000) : 900000) : 900000) : 900000) : 180000);
		if (1 == 0)
		{
		}
		return result;
	}

	public static async Task<bool> CondenseIfNeededAsync(List<ChatMessage> messages, LlmService llm, int maxOutputTokens, CancellationToken ct = default(CancellationToken))
	{
		if (messages.Count < 6)
		{
			return false;
		}
		(string service, string model) settings = llm.GetCurrentModelInfo();
		int inputLimit = GetModelInputLimit(settings.service, settings.model);
		int threshold = (int)((double)inputLimit * 0.65);
		int currentTokens = TokenEstimator.EstimateMessages(messages);
		if (currentTokens < threshold)
		{
			return false;
		}
		bool didCompress = false;
		didCompress |= TruncateToolResults(messages);
		currentTokens = TokenEstimator.EstimateMessages(messages);
		if (currentTokens < threshold)
		{
			return didCompress;
		}
		bool flag = didCompress;
		didCompress = flag | await SummarizeOldMessagesAsync(messages, llm, ct);
		if (didCompress)
		{
			int afterTokens = TokenEstimator.EstimateMessages(messages);
			LogService.Info($"Context Condenser: {currentTokens} → {afterTokens} 토큰 (절감 {currentTokens - afterTokens})");
		}
		return didCompress;
	}

	private static bool TruncateToolResults(List<ChatMessage> messages)
	{
		bool result = false;
		int num = Math.Max(0, messages.Count - 6);
		for (int i = 0; i < num; i++)
		{
			ChatMessage chatMessage = messages[i];
			if (chatMessage.Content == null)
			{
				continue;
			}
			if (chatMessage.Content.StartsWith("{\"type\":\"tool_result\"") && chatMessage.Content.Length > 1500)
			{
				messages[i] = new ChatMessage
				{
					Role = chatMessage.Role,
					Content = TruncateToolResultJson(chatMessage.Content),
					Timestamp = chatMessage.Timestamp
				};
				result = true;
			}
			else if (chatMessage.Role == "assistant" && chatMessage.Content.Length > 3000 && chatMessage.Content.StartsWith("{\"_tool_use_blocks\""))
			{
				if (chatMessage.Content.Length > 4500)
				{
					messages[i] = new ChatMessage
					{
						Role = chatMessage.Role,
						Content = chatMessage.Content.Substring(0, 3000) + "...[축약됨]\"]}",
						Timestamp = chatMessage.Timestamp
					};
					result = true;
				}
			}
			else if (chatMessage.Content.Length > 4500 && chatMessage.Role != "system")
			{
				messages[i] = new ChatMessage
				{
					Role = chatMessage.Role,
					Content = chatMessage.Content.Substring(0, 1500) + "\n\n...[이전 내용 축약됨 — 원본 " + $"{chatMessage.Content.Length:N0}자 중 {1500:N0}자 유지]",
					Timestamp = chatMessage.Timestamp
				};
				result = true;
			}
		}
		return result;
	}

	private static string TruncateToolResultJson(string json)
	{
		int num = json.IndexOf("\"output\":\"", StringComparison.Ordinal);
		if (num < 0)
		{
			return json.Substring(0, Math.Min(json.Length, 1500)) + "...[축약됨]}";
		}
		int num2 = num + "\"output\":\"".Length;
		int num3 = num2;
		while (num3 < json.Length)
		{
			if (json[num3] == '\\')
			{
				num3 += 2;
				continue;
			}
			if (json[num3] == '"')
			{
				break;
			}
			num3++;
		}
		int num4 = num3 - num2;
		if (num4 <= 1500)
		{
			return json;
		}
		int num5 = 750;
		string text = json.Substring(0, num2);
		int num6 = num2;
		string text2 = json.Substring(num6, num3 - num6);
		num6 = num3;
		string text3 = json.Substring(num6, json.Length - num6);
		string[] obj = new string[9]
		{
			text,
			text2.Substring(0, num5),
			"\\n...[축약됨: ",
			$"{num4:N0}",
			"자 중 ",
			$"{1500:N0}",
			"자 유지]\\n",
			null,
			null
		};
		num6 = num5;
		int length = text2.Length;
		int num7 = length - num6;
		obj[7] = text2.Substring(num7, length - num7);
		obj[8] = text3;
		return string.Concat(obj);
	}

	private static async Task<bool> SummarizeOldMessagesAsync(List<ChatMessage> messages, LlmService llm, CancellationToken ct)
	{
		ChatMessage systemMsg = messages.FirstOrDefault((ChatMessage chatMessage) => chatMessage.Role == "system");
		if (systemMsg == null)
		{
		}
		List<ChatMessage> nonSystemMessages = messages.Where((ChatMessage chatMessage) => chatMessage.Role != "system").ToList();
		int keepCount = Math.Min(6, nonSystemMessages.Count);
		List<ChatMessage> recentMessages = nonSystemMessages.Skip(nonSystemMessages.Count - keepCount).ToList();
		List<ChatMessage> oldMessages = nonSystemMessages.Take(nonSystemMessages.Count - keepCount).ToList();
		if (oldMessages.Count < 3)
		{
			return false;
		}
		StringBuilder sb = new StringBuilder();
		sb.AppendLine("다음 대화 기록을 간결하게 요약하세요.");
		sb.AppendLine("반드시 유지할 정보: 사용자 요청, 핵심 결정 사항, 생성/수정된 파일 경로, 작업 진행 상황, 중요한 결과.");
		sb.AppendLine("제거할 정보: 도구 실행의 상세 출력, 반복되는 내용, 중간 사고 과정.");
		sb.AppendLine("요약은 대화와 동일한 언어로 작성하세요. 글머리 기호(-)로 핵심 사항만 나열하세요.\n---");
		foreach (ChatMessage m in oldMessages)
		{
			string content = m.Content ?? "";
			if (content.StartsWith("{\"_tool_use_blocks\""))
			{
				content = "[도구 호출]";
			}
			else if (content.StartsWith("{\"type\":\"tool_result\""))
			{
				content = "[도구 결과]";
			}
			else if (content.Length > 300)
			{
				content = content.Substring(0, 300) + "...";
			}
			StringBuilder stringBuilder = sb;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(4, 2, stringBuilder);
			handler.AppendLiteral("[");
			handler.AppendFormatted(m.Role);
			handler.AppendLiteral("]: ");
			handler.AppendFormatted(content);
			stringBuilder.AppendLine(ref handler);
		}
		try
		{
			List<ChatMessage> summaryMessages = new List<ChatMessage>
			{
				new ChatMessage
				{
					Role = "user",
					Content = sb.ToString()
				}
			};
			string summary = await llm.SendAsync(summaryMessages, ct);
			if (string.IsNullOrEmpty(summary))
			{
				return false;
			}
			messages.Clear();
			if (systemMsg != null)
			{
				messages.Add(systemMsg);
			}
			messages.Add(new ChatMessage
			{
				Role = "user",
				Content = $"[이전 대화 요약 — {oldMessages.Count}개 메시지 압축]\n{summary}",
				Timestamp = DateTime.Now
			});
			messages.Add(new ChatMessage
			{
				Role = "assistant",
				Content = "이전 대화 내용을 확인했습니다. 이어서 작업하겠습니다.",
				Timestamp = DateTime.Now
			});
			messages.AddRange(recentMessages);
			return true;
		}
		catch (Exception ex)
		{
			LogService.Warn("Context Condenser 요약 실패: " + ex.Message);
			return false;
		}
	}
}
