package com.saas.shared.config;

import com.saas.shared.core.SchemaMultiTenantConnectionProvider;
import com.saas.shared.core.TenantIdentifierResolverImpl;
import org.hibernate.cfg.AvailableSettings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import jakarta.persistence.EntityManagerFactory;
import java.util.HashMap;
import java.util.Map;

/**
 * Tenant JPA Configuration
 * 
 * Configures a separate multi-tenant EntityManagerFactory for tenant entities only.
 * This ensures tenant tables (CallCostRecord, AiApiCostRecord, VapiAssistant, etc.) 
 * are created only in tenant databases (tenant_X), not in saas_db.
 * 
 * Package scope: com.saas.tenant.entity
 * Multi-tenancy: SCHEMA strategy with dynamic routing
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    basePackages = "com.saas.tenant.repository",
    entityManagerFactoryRef = "tenantEntityManagerFactory",
    transactionManagerRef = "tenantTransactionManager"
)
public class TenantJpaConfig {
    
    @Autowired
    private SchemaMultiTenantConnectionProvider connectionProvider;
    
    @Autowired
    private TenantIdentifierResolverImpl tenantIdentifierResolver;
    
    /**
     * Tenant EntityManagerFactory - scans ONLY tenant entities
     * Uses multi-tenant connection provider for dynamic routing
     */
    @Bean(name = "tenantEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean tenantEntityManagerFactory() {
        
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(connectionProvider.getAnyDataSource());
        em.setPackagesToScan("com.saas.tenant.entity");
        em.setPersistenceUnitName("tenantPU");
        
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(false);
        vendorAdapter.setGenerateDdl(false); // Managed by TenantSchemaMigrationService
        em.setJpaVendorAdapter(vendorAdapter);
        
        Map<String, Object> properties = new HashMap<>();
        properties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, connectionProvider);
        properties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, tenantIdentifierResolver);
        properties.put("hibernate.multiTenancy", "SCHEMA");
        // CRITICAL: Disable auto-DDL for tenant entities to prevent creating tables in saas_db
        // TenantSchemaMigrationService handles schema creation/updates per tenant database
        properties.put("hibernate.hbm2ddl.auto", "none");
        properties.put("hibernate.dialect", "org.hibernate.dialect.MariaDBDialect");
        properties.put("hibernate.format_sql", true);
        properties.put("hibernate.physical_naming_strategy", 
                      "org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy");
        em.setJpaPropertyMap(properties);
        
        return em;
    }
    
    @Bean(name = "tenantTransactionManager")
    public PlatformTransactionManager tenantTransactionManager(
            @Qualifier("tenantEntityManagerFactory") EntityManagerFactory tenantEntityManagerFactory) {
        return new JpaTransactionManager(tenantEntityManagerFactory);
    }
}
