using System.Data;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using PlanTempus.Core.Database.ConnectionFactory;

namespace PlanTempus.Core.Database;

public class SqlOperations : IDatabaseOperations
{
    private readonly IDbConnectionFactory _connectionFactory;
    private readonly TelemetryClient _telemetryClient;

    public SqlOperations(IDbConnectionFactory connectionFactory, TelemetryClient telemetryClient)
    {
        _connectionFactory = connectionFactory;
        _telemetryClient = telemetryClient;
    }

    public DatabaseScope CreateScope(string operationName)
    {
        var connection = _connectionFactory.Create();
        connection.Open();
        var operation = _telemetryClient.StartOperation<DependencyTelemetry>(operationName);
        operation.Telemetry.Type = "SQL";
        operation.Telemetry.Target = "PostgreSQL";

        return new DatabaseScope(connection, operation);
    }

    public async Task<T> ExecuteAsync<T>(Func<IDbConnection, Task<T>> operation, string operationName)
    {
        using var scope = CreateScope(operationName);
        try
        {
            var result = await operation(scope.Connection);
            return result;
        }
        catch (Exception ex)
        {
            scope.Error(ex);
            throw;
        }
    }

    public async Task ExecuteAsync(Func<IDbConnection, Task> operation, string operationName)
    {
        using var scope = CreateScope(operationName);
        try
        {
            await operation(scope.Connection);
        }
        catch (Exception ex)
        {
            scope.Error(ex);
            throw;
        }
    }
}