using System;
using System.Data.SqlClient;

namespace HorseRacingPredictor.Manager
{
    internal abstract class Database
    {
        // La stringa di connessione viene rimossa da qui e definita nelle classi derivate
        protected abstract string _connectionString { get; }

        protected SqlConnection GetConnection()
        {
            var connection = new SqlConnection(_connectionString);
            connection.Open();
            return connection;
        }

        public void LogError(string operation, Exception ex)
        {
            var message = ex != null ? ex.Message : "Nessuna eccezione fornita";
            Console.WriteLine($"Errore durante {operation}: {message}");
        }

        /// <summary>
        /// Esegue una query SQL e gestisce le eccezioni in modo centralizzato
        /// </summary>
        public void ExecuteQuery(string operation, Action<SqlConnection> action)
        {
            try
            {
                using (var connection = GetConnection())
                {
                    action(connection);
                }
            }
            catch (Exception ex)
            {
                LogError(operation, ex);
            }
        }

        /// <summary>
        /// Esegue una query SQL all'interno di una transazione e gestisce le eccezioni
        /// </summary>
        public void ExecuteTransactionalQuery(string operation, Action<SqlConnection, SqlTransaction> action)
        {
            try
            {
                using (var connection = GetConnection())
                using (var transaction = connection.BeginTransaction())
                {
                    try
                    {
                        action(connection, transaction);
                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        LogError($"{operation} (transazione rollback)", ex);
                        throw; // Rilancia l'eccezione per gestione di livello superiore
                    }
                }
            }
            catch (Exception ex)
            {
                LogError(operation, ex);
            }
        }

        /// <summary>
        /// Metodo per verificare se la connessione al database è valida
        /// </summary>
        public bool TestConnection()
        {
            try
            {
                using (var connection = GetConnection())
                {
                    return connection.State == System.Data.ConnectionState.Open;
                }
            }
            catch (Exception ex)
            {
                LogError("test della connessione", ex);
                return false;
            }
        }
    }
}
