package com.saas.shared.core;

import lombok.extern.slf4j.Slf4j;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@Slf4j
@Component
public class SchemaMultiTenantConnectionProvider implements MultiTenantConnectionProvider<String> {

    private final DataSource dataSource;

    public SchemaMultiTenantConnectionProvider(DataSource dataSource) {
        this.dataSource = dataSource;
        log.info("🔧 SchemaMultiTenantConnectionProvider INITIALIZED");
    }

    @Override
    public Connection getAnyConnection() throws SQLException {
        return dataSource.getConnection();
    }

    @Override
    public void releaseAnyConnection(Connection connection) throws SQLException {
        connection.close();
    }

    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
        log.info("🔥 getConnection() CALLED with tenantIdentifier: {}", tenantIdentifier);
        final Connection connection = getAnyConnection();
        try {
            // MySQL database-based multi-tenancy
            log.info("⚡ Executing: USE {}", tenantIdentifier);
            connection.createStatement().execute("USE " + tenantIdentifier);
            log.info("✅ Successfully switched to database: {}", tenantIdentifier);
        } catch (SQLException e) {
            log.error("❌ FAILED to switch to database {}: {}", tenantIdentifier, e.getMessage());
            throw new SQLException("Could not switch to database " + tenantIdentifier, e);
        }
        return connection;
    }

    @Override
    public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
        try {
            // Reset to default database
            connection.createStatement().execute("USE saas_db");
        } catch (SQLException e) {
            // Log error but continue to close connection
        } finally {
            connection.close();
        }
    }

    @Override
    public boolean supportsAggressiveRelease() {
        return false;
    }

    @Override
    public boolean isUnwrappableAs(Class<?> unwrapType) {
        return false;
    }

    @Override
    public <T> T unwrap(Class<T> unwrapType) {
        return null;
    }
}
