package dmo.fs.db.dodex.mssql;

import dmo.fs.db.dodex.entities.Users;
import dmo.fs.db.dodex.hib.MutinySessionFactory;
import jakarta.enterprise.inject.spi.CDI;
import org.hibernate.Session;
import org.hibernate.reactive.mutiny.Mutiny;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serial;
import java.io.Serializable;
import java.time.Duration;
import java.util.List;

public class DodexDatabaseMssql extends DbMssql implements Serializable {
  @Serial
  private static final long serialVersionUID = 1L;
  private final static Logger logger = LoggerFactory.getLogger(DodexDatabaseMssql.class.getName());
  private Mutiny.SessionFactory sessionFactory;
  protected static Session entityManager;
  static protected String dbName;

  public DodexDatabaseMssql() {
    super();
  }

    public void sessionFactorySetup() throws Exception {
      MutinySessionFactory mutinySessionFactory =
        CDI.current().select(MutinySessionFactory.class).isUnsatisfied() ? null :
          CDI.current().select(MutinySessionFactory.class).get();
      logger.info("CDI mutinySessionFactory databaseSetup*****************: {}", mutinySessionFactory);
      if(mutinySessionFactory == null) {
          throw new NullPointerException("MutinySessionFactory from CDI");
      }

      List<Mutiny.SessionFactory> msfList = mutinySessionFactory.getSqlserverSessionFactory().listActive();
      if(!msfList.isEmpty()) {
          sessionFactory = msfList.get(0);
          logger.info("Sqlserver Mutiny Factory************: {}", sessionFactory);
      } else {
          throw new Exception("MutinySessionFactory from CDI not found");
      }

//    SessionFactory sessionFactory;
//      DodexRouter dodexRouter = CDI.current().select(DodexRouter.class).isUnsatisfied() ? null :
//        CDI.current().select(DodexRouter.class).get();
//      if(dodexRouter == null) {
//          throw new NullPointerException("DodexRouter from CDI");
//      }
//    try {
//      new DodexEntityManager();
//      sessionFactory = DodexEntityManager.getEmf();
//      emf = sessionFactory;
//    } catch (IOException ioe) {
//      throw new RuntimeException(ioe.getMessage());
//    }
//    entityManager = Objects.requireNonNull(sessionFactory).createEntityManager();

//    Map<String, Object> properties = sessionFactory.getProperties();
//    Object sessionDbname = properties.get("database");
//    dbName = sessionDbname != null ? sessionDbname.toString() : "dodex";
//    Object mode = properties.get("mode");
  }


  public void configDatabase() {
    String[] types = {"TABLE"};

    Mutiny.Session mutinySession = sessionFactory.openSession().await().atMost(Duration.ofSeconds(2));
    /*
    SELECT  *

    FROM    INFORMATION_SCHEMA.TABLES

    WHERE   TABLE_SCHEMA = 'PutSchemaHere'
            AND
            TABLE_NAME   = 'PutTableNameHere'
     */
    String query = "FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dodex' AND TABLE_NAME = 'users'";
    mutinySession.createQuery("from dmo.fs.db.dodex.entities.sqlserver.Users", Users.class)
        .getResultCount().onItem().invoke((userCount) -> {
            logger.info("Number of Users: {} ", userCount);
        }).subscribe().asCompletionStage();
//          mutinySession.find(Users.class, 1);

//    Session session = entityManager.unwrap(Session.class);
//    session.doWork(connection -> {
//      try {
//        connection.setAutoCommit(false);
//        DatabaseMetaData databaseMetaData = connection.getMetaData();
//        boolean didCreateATable = false;
//
//        ResultSet rsDbname = databaseMetaData.getTables(dbName, null, "USERS", types);
//
//        if (!rsDbname.next()) {
//          connection.createStatement().execute(getCreateTable("USERS"));
//          connection.createStatement().execute(getCreateTable("NAMEIDX"));
//          connection.createStatement().execute(getCreateTable("PASSWORDIDX"));
//          didCreateATable = true;
//          logger.info("Users Table Created.");
//        }
//        rsDbname = databaseMetaData.getTables(dbName, null, "MESSAGES", types);
//        if (!rsDbname.next()) {
//          connection.createStatement().execute(getCreateTable("MESSAGES"));
//          didCreateATable = true;
//          logger.info("Messages Table Created.");
//        }
//        rsDbname = databaseMetaData.getTables(dbName, null, "UNDELIVERED", types);
//        if (!rsDbname.next()) {
//          connection.createStatement().execute(getCreateTable("UNDELIVERED"));
//          didCreateATable = true;
//          logger.info("Undelivered Table Created.");
//        }
//        rsDbname = databaseMetaData.getTables(dbName, null, "GROUPS", types);
//        if (!rsDbname.next()) {
//          connection.createStatement().execute(getCreateTable("GROUPS"));
//          didCreateATable = true;
//          logger.info("Groups Table Created.");
//        }
//        rsDbname = databaseMetaData.getTables(dbName, null, "MEMBER", types);
//        if (!rsDbname.next()) {
//          connection.createStatement().execute(getCreateTable("MEMBER"));
//          didCreateATable = true;
//          logger.info("Member Table Created.");
//        }
//        rsDbname = databaseMetaData.getTables(dbName, null, "GOLFER", types);
//        if (!rsDbname.next()) {
//          connection.createStatement().execute(getCreateTable("GOLFER"));
//          didCreateATable = true;
//          logger.info("Golfer Table Created.");
//        }
//        rsDbname = databaseMetaData.getTables(dbName, null, "COURSE", types);
//        if (!rsDbname.next()) {
//          connection.createStatement().execute(getCreateTable("COURSE"));
//          didCreateATable = true;
//          logger.info("Course Table Created.");
//        }
//        rsDbname = databaseMetaData.getTables(dbName, null, "RATINGS", types);
//        if (!rsDbname.next()) {
//          connection.createStatement().execute(getCreateTable("RATINGS"));
//          connection.createStatement().execute(getCreateTable("RATINGSIDX"));
//          didCreateATable = true;
//          logger.info("Ratings Table Created.");
//        }
//        rsDbname = databaseMetaData.getTables(dbName, null, "SCORES", types);
//        if (!rsDbname.next()) {
//          connection.createStatement().execute(getCreateTable("SCORES"));
//          didCreateATable = true;
//          logger.info("Scores Table Created.");
//        }
//        if (didCreateATable) {
//          ResultSet rsSchemas = databaseMetaData.getCatalogs();
//          while (rsSchemas.next()) {
//            if (dbName.equals(rsSchemas.getString(1))) {
//              logger.warn("Used database: '{}' to Create Tables.", dbName);
//            }
//          }
//        }
//        rsDbname.close();
//        connection.commit();
//        connection.close();
//      } catch (SQLException se) {
//        se.printStackTrace();
//      }
//    });
  }

    public Mutiny.SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
