using System.Text.RegularExpressions;
using k8s;
using LazyBear.MCP.Services.ToolRegistry;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;

namespace LazyBear.MCP.Services.Kubernetes;

[McpServerToolType]
public abstract class KubernetesToolsBase(
    K8sClientProvider clientProvider,
    IConfiguration configuration,
    ToolRegistryService registry,
    ILogger? logger = null)
{
    protected readonly IKubernetes? _client = clientProvider.Client;
    protected readonly string? _clientInitializationError = clientProvider.InitializationError;
    protected readonly string _defaultNamespace = configuration["Kubernetes:DefaultNamespace"] ?? "default";
    protected readonly ILogger? _logger = logger;
    protected readonly ToolRegistryService _registry = registry;

    protected const string K8sModuleName = "Kubernetes";

    protected bool TryCheckEnabled(string toolName, out string error)
    {
        if (!_registry.IsToolEnabled(K8sModuleName, toolName))
        {
            error = $"Инструмент '{toolName}' модуля Kubernetes отключён в TUI.";
            return false;
        }
        error = string.Empty;
        return true;
    }

    protected static readonly Regex NamespaceRegex = new(@"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", RegexOptions.Compiled, TimeSpan.FromSeconds(1));
    protected static readonly Regex ResourceNameRegex = new(@"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", RegexOptions.Compiled, TimeSpan.FromSeconds(1));

    protected string ResolveNamespace(string? @namespace)
    {
        return string.IsNullOrWhiteSpace(@namespace) ? _defaultNamespace : @namespace;
    }

    protected void ValidateNamespace(string value, string parameterName)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException($"Namespace не может быть пустым", parameterName);
        }
        if (value.Length > 63)
        {
            throw new ArgumentException($"Namespace не может быть длиннее 63 символов", parameterName);
        }
        if (!NamespaceRegex.IsMatch(value))
        {
            throw new ArgumentException($"Невалидный формат namespace: '{value}'. Только lowercase alphanumetic, -, не может начинаться/заканчиваться на -", parameterName);
        }
    }

    protected void ValidateResourceName(string value, string parameterName)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException($"Resource name не может быть пустым", parameterName);
        }
        if (value.Length > 253)
        {
            throw new ArgumentException($"Resource name не может быть длиннее 253 символов", parameterName);
        }
        if (!ResourceNameRegex.IsMatch(value))
        {
            throw new ArgumentException($"Невалидный формат: '{value}'. Только lowercase alphanumetic, -, не может начинаться/заканчиваться на -", parameterName);
        }
    }

    protected bool TryGetClient(out IKubernetes client, out string error)
    {
        if (_client is null)
        {
            client = null!;
            var details = string.IsNullOrWhiteSpace(_clientInitializationError)
                ? string.Empty
                : $" Детали: {_clientInitializationError}";
            error = "Kubernetes клиент не инициализирован. Проверьте Kubernetes:KubeconfigPath или in-cluster окружение (KUBERNETES_SERVICE_HOST/KUBERNETES_SERVICE_PORT)." + details;
            return false;
        }

        client = _client;
        error = string.Empty;
        return true;
    }

    protected string FormatError(string toolName, string @namespace, Exception exception, string? resourceName = null)
    {
        _logger?.LogError(exception, "Ошибка Kubernetes в tool '{ToolName}' (namespace='{Namespace}'{ResourcePart}): {ExceptionMessage}", 
            toolName, @namespace, 
            string.IsNullOrWhiteSpace(resourceName) ? string.Empty : $", resource='{resourceName}'",
            exception.Message);

        var resourcePart = string.IsNullOrWhiteSpace(resourceName) ? string.Empty : $", resource='{resourceName}'";

        if (exception is global::k8s.Autorest.HttpOperationException httpException)
        {
            var statusCode = httpException.Response?.StatusCode;
            var reason = httpException.Response?.ReasonPhrase;
            var body = string.IsNullOrWhiteSpace(httpException.Response?.Content)
                ? "-"
                : httpException.Response!.Content;

            return $"Ошибка Kubernetes в tool '{toolName}' (namespace='{@namespace}'{resourcePart}): status={(int?)statusCode ?? 0} {reason}, details={body}";
        }

        return $"Ошибка Kubernetes в tool '{toolName}' (namespace='{@namespace}'{resourcePart}): {exception.GetType().Name}: {exception.Message}";
    }

    protected string FormatException(string toolName, Exception exception, string? resource = null)
    {
        _logger?.LogError(exception, "Ошибка exception в tool '{ToolName}'{ResourcePart}: {ExceptionMessage}", 
            toolName, 
            string.IsNullOrWhiteSpace(resource) ? string.Empty : $", resource='{resource}'",
            exception.Message);

        var resourcePart = string.IsNullOrWhiteSpace(resource) ? string.Empty : $", resource='{resource}'";
        return $"Ошибка в tool '{toolName}'{resourcePart}: {exception.GetType().Name}: {exception.Message}";
    }
}
