// System
using System;
using System.Data;
using System.Data.OleDb;
using System.Text.Json;

// Microsoft
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;

// Project
using Compliance.DTOs;
using Compliance.Infrastructure.Repositories;
using Compliance.Services;
using Compliance.Services.ValidationRules;

namespace Compliance
{
    internal class Program
    {
        private static string GetConnectionString(IConfiguration configuration)
        {
            return configuration.GetConnectionString("DefaultConnection") 
                ?? throw new InvalidOperationException("Connection string not found");
        }
        private static readonly JsonSerializerOptions s_writeOptions = new()
        {
            WriteIndented = true
        };

        public static async Task Main(string[] args)
        {
            if (args.Length == 0) { return; }

            var services = ConfigureServices();
            var billComplianceService = services.GetRequiredService<IBillComplianceService>();

            // Read JSON input
            var jsonInput = await File.ReadAllTextAsync(args[0]);
            var request = JsonSerializer.Deserialize<BillComplianceRequest>(jsonInput) ?? throw new InvalidOperationException("Failed to deserialize request");
            var result = await billComplianceService.ValidateBillAsync(request);
            
            // Output results
            var jsonOutput = JsonSerializer.Serialize(result, s_writeOptions);
            await File.WriteAllTextAsync("compliance_results.json", jsonOutput);
        }

        private static ServiceProvider ConfigureServices()
        {
            var services = new ServiceCollection();

            // Add configuration
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();
            services.AddSingleton<IConfiguration>(configuration);

            var connectionString = GetConnectionString(configuration);
            
            services.AddSingleton<IDistributorRepository>(new DistributorRepository(connectionString));
            services.AddSingleton<IClientRepository>(new ClientRepository(connectionString));

            // Register validation rule factory
            services.AddSingleton<IValidationRuleFactory, ValidationRuleFactory>();
            
            services.AddSingleton<IBillComplianceService, BillComplianceService>();

            return services.BuildServiceProvider();
        }
    }
}