using System.ComponentModel;
using k8s;
using k8s.Autorest;
using LazyBear.MCP.Services.ToolRegistry;
using ModelContextProtocol.Server;

namespace LazyBear.MCP.Services.Kubernetes;

[McpServerToolType]
public sealed class K8sConfigTools(
    K8sClientProvider clientProvider,
    IConfiguration configuration,
    ToolRegistryService registry,
    ILogger<K8sConfigTools>? logger = null)
    : KubernetesToolsBase(clientProvider, configuration, registry, logger)
{
    private const int MaxSecretKeyLimit = 100;

    [McpServerTool, Description("Список ConfigMap в namespace")]
    public async Task<string> ListConfigMaps(
        [Description("Namespace Kubernetes")] string? @namespace = null,
        CancellationToken cancellationToken = default)
    {
        if (!TryCheckEnabled("ListConfigMaps", out var enabledError)) return enabledError;

        ValidateNamespace(@namespace ?? _defaultNamespace, nameof(@namespace));
        var ns = ResolveNamespace(@namespace);
        if (!TryGetClient(out var client, out var clientError))
        {
            return clientError;
        }

        try
        {
            var configMaps = await client.CoreV1.ListNamespacedConfigMapAsync(ns, cancellationToken: cancellationToken);

            if (configMaps.Items.Count == 0)
            {
                return $"В namespace '{ns}' configMap не найдены.";
            }

            var lines = configMaps.Items.Select(cm =>
            {
                var name = cm.Metadata?.Name ?? "unknown";
                var keyCount = cm.Data?.Count ?? 0;
                return $"{name}: keys={keyCount}";
            });

            return $"ConfigMap namespace '{ns}':\n{string.Join('\n', lines)}";
        }
        catch (Exception ex)
        {
            return FormatError("list_config_maps", ns, ex);
        }
    }

    [McpServerTool, Description("Получить данные ConfigMap")]
    public async Task<string> GetConfigMapData(
        [Description("Имя ConfigMap")] string name,
        [Description("Namespace Kubernetes")] string? @namespace = null,
        CancellationToken cancellationToken = default)
    {
        if (!TryCheckEnabled("GetConfigMapData", out var enabledError)) return enabledError;

        ValidateResourceName(name, nameof(name));
        ValidateNamespace(@namespace ?? _defaultNamespace, nameof(@namespace));
        var ns = ResolveNamespace(@namespace);
        if (!TryGetClient(out var client, out var clientError))
        {
            return clientError;
        }

        try
        {
            var configMap = await client.CoreV1.ReadNamespacedConfigMapAsync(name, ns, cancellationToken: cancellationToken);

            if (configMap.Data is null || configMap.Data.Count == 0)
            {
                return $"ConfigMap '{name}' в namespace '{ns}' не содержит данных.";
            }

            var lines = configMap.Data.Select(item => $"{item.Key}={item.Value}");
            return $"Данные ConfigMap '{name}' namespace '{ns}':\n{string.Join('\n', lines)}";
        }
        catch (Exception ex)
        {
            return FormatError("get_config_map_data", ns, ex, name);
        }
    }

    [McpServerTool, Description("Список Secret в namespace (без значений)")]
    public async Task<string> ListSecrets(
        [Description("Namespace Kubernetes")] string? @namespace = null,
        CancellationToken cancellationToken = default)
    {
        if (!TryCheckEnabled("ListSecrets", out var enabledError)) return enabledError;

        ValidateNamespace(@namespace ?? _defaultNamespace, nameof(@namespace));
        var ns = ResolveNamespace(@namespace);
        if (!TryGetClient(out var client, out var clientError))
        {
            return clientError;
        }

        try
        {
            var secrets = await client.CoreV1.ListNamespacedSecretAsync(ns, cancellationToken: cancellationToken);

            if (secrets.Items.Count == 0)
            {
                return $"В namespace '{ns}' secret не найдены.";
            }

            var lines = secrets.Items.Select(secret =>
            {
                var name = secret.Metadata?.Name ?? "unknown";
                var type = secret.Type ?? "Opaque";
                return $"{name}: type={type}";
            });

            return $"Secret namespace '{ns}':\n{string.Join('\n', lines)}";
        }
        catch (Exception ex)
        {
            return FormatError("list_secrets", ns, ex);
        }
    }

    [McpServerTool, Description("Ключи Secret без значений")]
    public async Task<string> GetSecretKeys(
        [Description("Имя Secret")] string name,
        [Description("Namespace Kubernetes")] string? @namespace = null,
        CancellationToken cancellationToken = default)
    {
        if (!TryCheckEnabled("GetSecretKeys", out var enabledError)) return enabledError;

        ValidateResourceName(name, nameof(name));
        ValidateNamespace(@namespace ?? _defaultNamespace, nameof(@namespace));
        var ns = ResolveNamespace(@namespace);
        if (!TryGetClient(out var client, out var clientError))
        {
            return clientError;
        }

        try
        {
            var secret = await client.CoreV1.ReadNamespacedSecretAsync(name, ns, cancellationToken: cancellationToken);

            var keys = new HashSet<string>(StringComparer.Ordinal);
            if (secret.Data is not null)
            {
                foreach (var key in secret.Data.Keys)
                {
                    keys.Add(key);
                }
            }

            if (secret.StringData is not null)
            {
                foreach (var key in secret.StringData.Keys)
                {
                    keys.Add(key);
                }
            }

            if (keys.Count == 0)
            {
                return $"Secret '{name}' в namespace '{ns}' не содержит ключей.";
            }

            return $"Ключи Secret '{name}' namespace '{ns}': {string.Join(", ", keys.OrderBy(k => k))}";
        }
        catch (Exception ex)
        {
            return FormatError("get_secret_keys", ns, ex, name);
        }
    }
}
