using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services;
using AsbCloudInfrastructure.Services.Analysis;
using AsbCloudInfrastructure.Services.Cache;
using AsbCloudInfrastructure.Services.WellOperationService;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace AsbCloudInfrastructure
{
    public static class DependencyInjection
    {
        public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddDbContext<AsbCloudDbContext>(options =>
                options.UseNpgsql(configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Scoped);

            services.AddScoped<IAsbCloudDbContext>(provider => provider.GetService<AsbCloudDbContext>());
            services.AddScoped<IFileShareService, GoogleDriveService>();

            services.AddHostedService<ReportsBackgroundService>();
            services.AddHostedService<TelemetryAnalyticsBackgroundService>();

            services.AddSingleton(new CacheDb());
            services.AddSingleton<ITelemetryTracker, TelemetryTracker>();
            services.AddSingleton<IReportsBackgroundQueue, ReportsBackgroundQueue>();
            services.AddSingleton<IRequerstTrackerService, RequerstTrackerService>();

            services.AddTransient<IAuthService, AuthService>();
            services.AddTransient<IWellService, WellService>();
            services.AddTransient<IClusterService, ClusterService>();
            services.AddTransient<ITelemetryService, TelemetryService>();
            services.AddTransient<IMessageService, MessageService>();
            services.AddTransient<IEventService, EventService>();
            services.AddTransient<ITelemetryUserService, TelemetryUserService>();
            services.AddTransient<IReportService, ReportService>();
            services.AddTransient<ITelemetryAnalyticsService, TelemetryAnalyticsService>();
            services.AddTransient<IFileService, FileService>();
            services.AddTransient<IWellOperationService, WellOperationService>();
            services.AddTransient<IWellOperationsStatService, WellOperationsStatService>();
            services.AddTransient<IWellOperationImportService, WellOperationImportService>();
            services.AddTransient<IWellCompositeService, WellCompositeService>();
            services.AddTransient<IMeasureService, MeasureService>();
            services.AddTransient<IDrillingProgramService, DrillingProgramService>();
            services.AddTransient<IDrillParamsService, DrillParamsService>();
            services.AddTransient<IDrillFlowChartService, DrillFlowChartService>();
            services.AddTransient<ITimeZoneService, TimeZoneService>();

            // admin crud services:
            services.AddTransient<ICrudService<DepositDto>, CrudServiceBase<DepositDto, Deposit>>();
            services.AddTransient<ICrudService<ClusterDto>, CrudServiceBase<ClusterDto, Cluster>>();
            services.AddTransient<ICrudService<WellDto>, CrudServiceBase<WellDto, Well>>();
            services.AddTransient<ICrudService<CompanyDto>, CrudServiceBase<CompanyDto, Company>>();
            services.AddTransient<ICrudService<UserDto>, CrudServiceBase<UserDto, User>>();
            services.AddTransient<ICrudService<UserRoleDto>, CrudServiceBase<UserRoleDto, UserRole>>();
            services.AddTransient<ICrudService<TelemetryDto>, CrudServiceBase<TelemetryDto, Telemetry>>();
            services.AddTransient<ICrudService<DrillParamsDto>, DrillParamsService>();

            // TelemetryData services
            services.AddTransient<ITelemetryDataService<TelemetryDataSaubDto>, TelemetryDataSaubService>();
            services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>();

            return services;
        }
    }
}