using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using EonaCat.LogStack.Core;
using EonaCat.LogStack.Logging;
using EonaCat.LogStack.Features;

namespace EonaCat.LogStack.Extensions
{
    /// <summary>
    /// Fluent extension methods for integrating advanced logging features.
    /// </summary>
    public static class LoggerFeatureExtensions
    {
        /// <summary>
        /// Registers LogSearchEngine in the dependency injection container.
        /// </summary>
        public static IServiceCollection AddLogSearchEngine(this IServiceCollection services, int maxIndexSize = 10000)
        {
            services.AddSingleton(new LogSearchEngine(maxIndexSize));
            return services;
        }

        /// <summary>
        /// Registers AlertingEngine in the dependency injection container.
        /// </summary>
        public static IServiceCollection AddAlertingEngine(this IServiceCollection services)
        {
            services.AddSingleton(new AlertingEngine());
            return services;
        }

        /// <summary>
        /// Registers LogReplayEngine in the dependency injection container.
        /// </summary>
        public static IServiceCollection AddLogReplayEngine(this IServiceCollection services)
        {
            services.AddSingleton(new LogReplayEngine());
            return services;
        }

        /// <summary>
        /// Registers ConfigurationValidator and ConfigurationHotReloadManager in the DI container.
        /// </summary>
        public static IServiceCollection AddConfigurationValidation(this IServiceCollection services)
        {
            services.AddSingleton(new ConfigurationValidator());
            services.AddSingleton(new ConfigurationHotReloadManager());
            return services;
        }

        /// <summary>
        /// Registers CorrelationDashboardHelper in the dependency injection container.
        /// </summary>
        public static IServiceCollection AddCorrelationDashboardHelper(this IServiceCollection services)
        {
            services.AddSingleton(new CorrelationDashboardHelper());
            return services;
        }

        /// <summary>
        /// Registers all logging features at once.
        /// </summary>
        public static IServiceCollection AddAllEonaCatLoggingFeatures(this IServiceCollection services, 
            LogFeaturesConfiguration config = null)
        {
            config ??= new LogFeaturesConfiguration();

            services.AddLogSearchEngine(config.LogSearchMaxSize);
            services.AddAlertingEngine();
            services.AddLogReplayEngine();
            services.AddConfigurationValidation();
            services.AddCorrelationDashboardHelper();

            return services;
        }

        /// <summary>
        /// Gets LogSearchEngine from service provider and performs a search.
        /// </summary>
        public static IServiceProvider WithLogSearch(this IServiceProvider provider,
            Action<LogSearchEngine> configureSearch)
        {
            var engine = provider.GetService<LogSearchEngine>();
            if (engine != null)
            {
                configureSearch(engine);
            }
            return provider;
        }

        /// <summary>
        /// Gets AlertingEngine from service provider and configures alerting.
        /// </summary>
        public static IServiceProvider WithAlerting(this IServiceProvider provider,
            Action<AlertingEngine> configureAlerting)
        {
            var engine = provider.GetService<AlertingEngine>();
            if (engine != null)
            {
                configureAlerting(engine);
            }
            return provider;
        }

        /// <summary>
        /// Gets LogReplayEngine from service provider and performs log operations.
        /// </summary>
        public static IServiceProvider WithLogReplay(this IServiceProvider provider,
            Action<LogReplayEngine> configureReplay)
        {
            var engine = provider.GetService<LogReplayEngine>();
            if (engine != null)
            {
                configureReplay(engine);
            }
            return provider;
        }

        /// <summary>
        /// Validates logger configuration on startup.
        /// </summary>
        public static IServiceProvider ValidateLoggerConfiguration(this IServiceProvider provider, ILogger logger)
        {
            var validator = provider.GetService<ConfigurationValidator>();
            if (validator != null)
            {
                var report = validator.Validate(logger);
                if (!report.IsValid)
                {
                    var errors = report.GetErrors();
                    if (errors.Any())
                    {
                        throw new InvalidOperationException(
                            $"Logger configuration validation failed:\n{report.ToString()}");
                    }
                }
            }
            return provider;
        }

        /// <summary>
        /// Enables hot-reload support with a handler callback.
        /// </summary>
        public static IServiceProvider EnableConfigurationHotReload(this IServiceProvider provider,
            Action<ConfigurationChangeNotification> onConfigChanged)
        {
            var reloadManager = provider.GetService<ConfigurationHotReloadManager>();
            if (reloadManager != null)
            {
                reloadManager.EnableHotReload(onConfigChanged);
            }
            return provider;
        }

        /// <summary>
        /// Gets CorrelationDashboardHelper from service provider and records activity.
        /// </summary>
        public static IServiceProvider RecordCorrelatedActivity(this IServiceProvider provider,
            string correlationId, string activityName, string serviceName, ActivityStatus status,
            double durationMs, Exception exception = null)
        {
            var helper = provider.GetService<CorrelationDashboardHelper>();
            if (helper != null)
            {
                helper.RecordActivity(correlationId, activityName, serviceName, status, durationMs, exception);
            }
            return provider;
        }

        /// <summary>
        /// Gets tracing dashboard statistics from service provider.
        /// </summary>
        public static DashboardStatistics GetTracingStatistics(this IServiceProvider provider)
        {
            var helper = provider.GetService<CorrelationDashboardHelper>();
            return helper?.GetStatistics() ?? new DashboardStatistics();
        }

        /// <summary>
        /// Gets search statistics from service provider.
        /// </summary>
        public static LogSearchStatistics GetSearchStatistics(this IServiceProvider provider)
        {
            var engine = provider.GetService<LogSearchEngine>();
            return engine?.GetStatistics() ?? new LogSearchStatistics();
        }

        /// <summary>
        /// Gets alerting statistics from service provider.
        /// </summary>
        public static AlertingStatistics GetAlertingStatistics(this IServiceProvider provider)
        {
            var engine = provider.GetService<AlertingEngine>();
            return engine?.GetStatistics() ?? new AlertingStatistics();
        }

        /// <summary>
        /// Performs a complex log search using fluent API.
        /// </summary>
        public static IEnumerable<LogSearchEntry> SearchLogs(this IServiceProvider provider,
            LogLevel? level = null, string keyword = null, string loggerName = null,
            string correlationId = null, DateTime? fromUtc = null, DateTime? toUtc = null,
            int limit = 0)
        {
            var engine = provider.GetService<LogSearchEngine>();
            if (engine == null)
                return Enumerable.Empty<LogSearchEntry>();

            var query = new LogSearchQuery
            {
                Keyword = keyword,
                Level = level,
                LoggerName = loggerName,
                CorrelationId = correlationId,
                FromUtc = fromUtc,
                ToUtc = toUtc,
                Limit = limit
            };

            return engine.Search(query);
        }

        /// <summary>
        /// Adds an alert rule using fluent configuration.
        /// </summary>
        public static IServiceProvider AddAlertRule(this IServiceProvider provider,
            string ruleName, Action<AlertRuleBuilder> configureRule)
        {
            var engine = provider.GetService<AlertingEngine>();
            if (engine != null)
            {
                engine.AddRule(ruleName, configureRule);
            }
            return provider;
        }

        /// <summary>
        /// Exports captured logs to JSON.
        /// </summary>
        public static IServiceProvider ExportLogsToJson(this IServiceProvider provider, string filePath)
        {
            var engine = provider.GetService<LogReplayEngine>();
            if (engine != null)
            {
                engine.ExportToJson(filePath);
            }
            return provider;
        }

        /// <summary>
        /// Imports captured logs from JSON.
        /// </summary>
        public static IServiceProvider ImportLogsFromJson(this IServiceProvider provider, string filePath)
        {
            var engine = provider.GetService<LogReplayEngine>();
            if (engine != null)
            {
                engine.ImportFromJson(filePath);
            }
            return provider;
        }

        /// <summary>
        /// Gets a correlation trace for visualization.
        /// </summary>
        public static GanttChartData GetTraceAsGanttChart(this IServiceProvider provider, string correlationId)
        {
            var helper = provider.GetService<CorrelationDashboardHelper>();
            return helper?.GetAsGanttChart(correlationId) ?? null;
        }

        /// <summary>
        /// Gets the service dependency map for the system.
        /// </summary>
        public static ServiceDependencyMap GetServiceDependencies(this IServiceProvider provider)
        {
            var helper = provider.GetService<CorrelationDashboardHelper>();
            return helper?.GetDependencyMap() ?? new ServiceDependencyMap();
        }

        /// <summary>
        /// Gets critical paths (slow traces) from the system.
        /// </summary>
        public static IEnumerable<CriticalPath> GetCriticalPaths(this IServiceProvider provider, int topCount = 10)
        {
            var helper = provider.GetService<CorrelationDashboardHelper>();
            return helper?.FindCriticalPaths(topCount) ?? Enumerable.Empty<CriticalPath>();
        }
    }

    /// <summary>
    /// Configuration for logging features.
    /// </summary>
    public class LogFeaturesConfiguration
    {
        /// <summary>
        /// Maximum number of logs to keep in the search index.
        /// </summary>
        public int LogSearchMaxSize { get; set; } = 10000;

        /// <summary>
        /// Whether to enable search indexing by default.
        /// </summary>
        public bool EnableSearchByDefault { get; set; } = true;

        /// <summary>
        /// Whether to enable alerting by default.
        /// </summary>
        public bool EnableAlertingByDefault { get; set; } = true;

        /// <summary>
        /// Whether to enable log capture for replay by default.
        /// </summary>
        public bool EnableReplayByDefault { get; set; } = false;

        /// <summary>
        /// Whether to enable tracing dashboard by default.
        /// </summary>
        public bool EnableTracingByDefault { get; set; } = true;

        /// <summary>
        /// Maximum age of trace data to keep (in hours).
        /// </summary>
        public int TraceDataMaxAgeHours { get; set; } = 24;
    }
}
