using Microsoft.Extensions.DependencyInjection;
using Journal.Core.Repositories;
using Journal.Core.Services.Ai;
using Journal.Core.Services.Config;
using Journal.Core.Services.Database;
using Journal.Core.Services.Entries;
using Journal.Core.Services.Fragments;
using Journal.Core.Services.Lists;
using Journal.Core.Services.Logging;
using Journal.Core.Services.Sidecar;
using Journal.Core.Services.Speech;
using Journal.Core.Services.Conversations;
using Journal.Core.Services.Todos;
using Journal.Core.Services.Vault;

namespace Journal.Core;

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddFragmentServices(this IServiceCollection services)
    {
        services.AddSingleton<IDatabaseSessionService, DatabaseSessionService>();
        services.AddSingleton<IFragmentRepository, SqliteFragmentRepository>();
        services.AddSingleton<IJournalConfigService, JournalConfigService>();
        services.AddSingleton<IFragmentService, FragmentService>();
        services.AddTransient<IEntrySearchService, EntrySearchService>();
        services.AddSingleton<IVaultCryptoService, VaultCryptoService>();
        services.AddSingleton<IVaultStorageService, VaultStorageService>();
        services.AddSingleton<IJournalDatabaseService, JournalDatabaseService>();
        services.AddSingleton<IAiService>(provider =>
        {
            var config = provider.GetRequiredService<IJournalConfigService>().Current;
            if (!string.Equals(config.AiProvider, "python-sidecar", StringComparison.OrdinalIgnoreCase))
                return new DisabledAiService(config.AiProvider);

            try
            {
                return new PythonSidecarAiService(config);
            }
            catch (Exception ex)
            {
                return new DisabledAiService(
                    provider: "python-sidecar",
                    message: $"Python AI sidecar unavailable: {ex.Message}",
                    healthy: false);
            }
        });
        services.AddSingleton<ISpeechBridgeService>(provider =>
        {
            var config = provider.GetRequiredService<IJournalConfigService>().Current;
            try
            {
                return new PythonSidecarSpeechService(config);
            }
            catch (Exception ex)
            {
                return new DisabledSpeechBridgeService(
                    provider: "python-sidecar",
                    message: $"Python speech sidecar unavailable: {ex.Message}");
            }
        });
        services.AddSingleton<IS2TService, DisabledS2TService>();
        services.AddSingleton<IEntryFileRepository, SqliteEntryFileRepository>();
        services.AddSingleton<IEntryFileService, EntryFileService>();
        services.AddSingleton<IListRepository, SqliteListRepository>();
        services.AddSingleton<IListService, ListService>();
        services.AddSingleton<ITodoRepository, SqliteTodoRepository>();
        services.AddSingleton<ITodoService, TodoService>();
        services.AddSingleton<ICoachService>(new DisabledCoachService());
        services.AddSingleton<IConversationRepository, SqliteConversationRepository>();
        services.AddSingleton<IConversationService, ConversationService>();
        services.AddSingleton<CommandLogger>();
        services.AddSingleton<SidecarCli>();
        return services;
    }
}
