import os
import logging
from urllib.parse import quote_plus

class DatabaseConfig:
    """
    Database configuration settings
    Supports SQLite and MySQL with Namecheap hosting optimization
    """
    
    @staticmethod
    def get_database_uri():
        """Return database URI based on specified type with Namecheap optimization"""
        db_type = os.environ.get('DB_TYPE', 'sqlite')
        
        if db_type.lower() == 'mysql':
            try:
                # MySQL settings for Namecheap hosting
                mysql_user = os.environ.get('MYSQL_USER')
                mysql_password = os.environ.get('MYSQL_PASSWORD')
                mysql_host = os.environ.get('MYSQL_HOST', 'localhost')
                mysql_port = os.environ.get('MYSQL_PORT', '3306')
                mysql_database = os.environ.get('MYSQL_DATABASE')
                
                # Validate required MySQL parameters
                if not all([mysql_user, mysql_password, mysql_database]):
                    logging.warning("Missing MySQL credentials, falling back to SQLite")
                    return DatabaseConfig._get_sqlite_uri()
                
                # URL encode password to handle special characters
                encoded_password = quote_plus(mysql_password)
                
                # Optimized connection string for Namecheap hosting
                connection_params = [
                    'charset=utf8mb4',
                    'connect_timeout=60',
                    'read_timeout=30',
                    'write_timeout=30',
                    'autocommit=true',
                    'sql_mode=STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO'
                ]
                
                params_string = '&'.join(connection_params)
                
                return f'mysql+pymysql://{mysql_user}:{encoded_password}@{mysql_host}:{mysql_port}/{mysql_database}?{params_string}'
                
            except Exception as e:
                logging.error(f"MySQL connection error: {e}")
                logging.info("Falling back to SQLite database")
                return DatabaseConfig._get_sqlite_uri()
        
        else:
            return DatabaseConfig._get_sqlite_uri()
    
    @staticmethod
    def _get_sqlite_uri():
        """Get SQLite database URI"""
        base_dir = os.path.abspath(os.path.dirname(__file__))
        db_path = os.environ.get('SQLITE_PATH', os.path.join(base_dir, 'instance', 'database.db'))
        
        # Ensure instance directory exists
        instance_dir = os.path.dirname(db_path)
        if not os.path.exists(instance_dir):
            os.makedirs(instance_dir, exist_ok=True)
            
        return f'sqlite:///{db_path}'
    
    @staticmethod
    def get_engine_options():
        """Database engine settings optimized for hosting environments"""
        db_type = os.environ.get('DB_TYPE', 'sqlite')
        
        if db_type.lower() == 'mysql':
            return {
                'pool_pre_ping': True,
                'pool_recycle': 3600,  # Increased for stability
                'pool_size': 5,
                'max_overflow': 10,
                'pool_timeout': 30,
                'echo': False,
                'connect_args': {
                    'connect_timeout': 60,
                    'read_timeout': 30,
                    'write_timeout': 30,
                    'charset': 'utf8mb4',
                    'autocommit': True
                }
            }
        else:
            return {
                'echo': False,
                'pool_pre_ping': True,
                'connect_args': {
                    'check_same_thread': False,
                    'timeout': 30
                }
            }
    
    @staticmethod
    def test_connection():
        """Test database connection"""
        try:
            from sqlalchemy import create_engine, text
            
            uri = DatabaseConfig.get_database_uri()
            options = DatabaseConfig.get_engine_options()
            
            engine = create_engine(uri, **options)
            
            with engine.connect() as connection:
                if 'mysql' in uri:
                    result = connection.execute(text('SELECT 1'))
                else:
                    result = connection.execute(text('SELECT 1'))
                
                if result.fetchone():
                    logging.info("Database connection successful")
                    return True
                    
        except Exception as e:
            logging.error(f"Database connection failed: {e}")
            return False
        
        return False