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

namespace AxCopilot.Services.Agent;

public class AgentContext
{
	public string WorkFolder { get; init; } = "";

	public string Permission { get; init; } = "Ask";

	public Dictionary<string, string> ToolPermissions { get; init; } = new Dictionary<string, string>();

	public List<string> BlockedPaths { get; init; } = new List<string>();

	public List<string> BlockedExtensions { get; init; } = new List<string>();

	public string ActiveTab { get; init; } = "Chat";

	public bool DevMode { get; init; }

	public bool DevModeStepApproval { get; init; }

	public Func<string, string, Task<bool>>? AskPermission { get; init; }

	public Func<string, List<string>, Task<string?>>? UserDecision { get; init; }

	public Func<string, List<string>, string, Task<string?>>? UserAskCallback { get; init; }

	public bool IsPathAllowed(string path)
	{
		string fullPath = Path.GetFullPath(path);
		string ext = Path.GetExtension(fullPath).ToLowerInvariant();
		if (BlockedExtensions.Any((string e) => string.Equals(e, ext, StringComparison.OrdinalIgnoreCase)))
		{
			return false;
		}
		foreach (string blockedPath in BlockedPaths)
		{
			string value = blockedPath.Replace("*", "");
			if (!string.IsNullOrEmpty(value) && fullPath.Contains(value, StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
		}
		if (!string.IsNullOrEmpty(WorkFolder))
		{
			string fullPath2 = Path.GetFullPath(WorkFolder);
			if (!fullPath.StartsWith(fullPath2, StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
		}
		return true;
	}

	public static string EnsureTimestampedPath(string fullPath)
	{
		string path = Path.GetDirectoryName(fullPath) ?? "";
		string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fullPath);
		string extension = Path.GetExtension(fullPath);
		string text = DateTime.Now.ToString("yyyyMMdd_HHmm");
		if (Regex.IsMatch(fileNameWithoutExtension, "_\\d{8}_\\d{4}$"))
		{
			return fullPath;
		}
		return Path.Combine(path, fileNameWithoutExtension + "_" + text + extension);
	}

	public async Task<bool> CheckWritePermissionAsync(string toolName, string filePath)
	{
		string effectivePerm = Permission;
		if (ToolPermissions.TryGetValue(toolName, out string toolPerm))
		{
			effectivePerm = toolPerm;
		}
		if (string.Equals(effectivePerm, "Deny", StringComparison.OrdinalIgnoreCase))
		{
			return false;
		}
		if (string.Equals(effectivePerm, "Auto", StringComparison.OrdinalIgnoreCase))
		{
			return true;
		}
		if (AskPermission != null)
		{
			return await AskPermission(toolName, filePath);
		}
		return false;
	}
}
