from abc import ABC, abstractmethod
from datetime import datetime, timezone
from sqlalchemy.orm import Session, sessionmaker
from sqlalchemy.engine import Engine
from sqlalchemy import create_engine, text
from sqlalchemy.exc import SQLAlchemyError

class ConexionBase(ABC):
    def __init__(self, uri: str):
        self.estado = "pendiente"
        self.timestamp = datetime.now(timezone.utc)
        self._engine: Engine = create_engine(uri)
        self._Session = sessionmaker(bind=self._engine)
        self._session_instance: Session | None = None

    @abstractmethod
    def get_session(self) -> Session:
        if self._session_instance is None:
            self._session_instance = self._Session()
        return self._session_instance

    @abstractmethod
    def get_engine(self) -> Engine:
        return self._engine

    def probar_conexion(self) -> bool:
        try:
            with self._engine.connect() as connection:
                connection.execute(text("SELECT 1"))
            self.estado = "exito"
            return True
        except SQLAlchemyError:
            self.estado = "fallo"
            return False

    def close(self):
        if self._session_instance is not None:
            self._session_instance.close()
            self._session_instance = None