from __future__ import annotations

from pathlib import Path
from typing import Generator

from dotenv import load_dotenv
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# Load environment variables from .env file if it exists
# Path: backend/db/session.py -> backend/db -> backend -> punimtag/ -> .env
env_path = Path(__file__).parent.parent.parent / ".env"
load_dotenv(dotenv_path=env_path)


def get_database_url() -> str:
    """Fetch database URL from environment or defaults."""
    import os
    # Check for environment variable first
    db_url = os.getenv("DATABASE_URL")
    if db_url:
        return db_url
    # Default to PostgreSQL for development (without password - must be set via env var)
    # This ensures no hardcoded passwords in the codebase
    raise ValueError(
        "DATABASE_URL environment variable not set. "
        "Please set DATABASE_URL in your .env file or environment."
    )


def get_auth_database_url() -> str:
    """Fetch auth database URL from environment."""
    import os
    db_url = os.getenv("DATABASE_URL_AUTH")
    if not db_url:
        raise ValueError("DATABASE_URL_AUTH environment variable not set")
    return db_url


database_url = get_database_url()
# PostgreSQL connection pool settings
pool_kwargs = {
    "pool_pre_ping": True,
    "pool_size": 10,
    "max_overflow": 20,
    "pool_recycle": 3600,
}

engine = create_engine(
    database_url,
    future=True,
    **pool_kwargs
)
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, future=True)


def get_db() -> Generator:
    """Yield a DB session for request lifecycle."""
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


# Auth database setup
try:
    auth_database_url = get_auth_database_url()
    auth_pool_kwargs = {
        "pool_pre_ping": True,
        "pool_size": 10,
        "max_overflow": 20,
        "pool_recycle": 3600,
    }
    
    auth_engine = create_engine(
        auth_database_url,
        future=True,
        **auth_pool_kwargs
    )
    AuthSessionLocal = sessionmaker(bind=auth_engine, autoflush=False, autocommit=False, future=True)
except ValueError as e:
    # DATABASE_URL_AUTH not set - auth database not available
    print(f"[DB Session] ⚠️  Auth database not configured: {e}")
    auth_engine = None
    AuthSessionLocal = None
except Exception as e:
    # Other errors (connection failures, etc.) - log but don't crash
    import os
    print(f"[DB Session] ⚠️  Failed to initialize auth database: {e}")
    print(f"[DB Session]    URL was: {os.getenv('DATABASE_URL_AUTH', 'not set')}")
    auth_engine = None
    AuthSessionLocal = None


def get_auth_db() -> Generator:
    """Yield a DB session for auth database request lifecycle."""
    if AuthSessionLocal is None:
        from fastapi import HTTPException, status
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail="Auth database not configured. Please set DATABASE_URL_AUTH environment variable in the backend configuration."
        )
    db = AuthSessionLocal()
    try:
        yield db
    finally:
        db.close()


